Skip to content

Commit

Permalink
Merge pull request #1350 from GaijinEntertainment/keepalive-take-2
Browse files Browse the repository at this point in the history
policies.keep_alive
  • Loading branch information
borisbat authored Nov 4, 2024
2 parents ce8df34 + ae1aeaf commit c22a95a
Show file tree
Hide file tree
Showing 11 changed files with 1,218 additions and 69 deletions.
483 changes: 483 additions & 0 deletions examples/test/misc/hello_new_syntax.das

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions include/daScript/ast/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -1394,6 +1394,7 @@ namespace das
bool completion = false; // this code is being compiled for 'completion' mode
bool export_all = false; // when user compiles, export all (public?) functions
bool serialize_main_module = true; // if false, then we recompile main module each time
bool keep_alive = false; // produce keep-alive noodes
// error reporting
int32_t always_report_candidates_threshold = 6; // always report candidates if there are less than this number
// infer passes
Expand Down
1 change: 1 addition & 0 deletions include/daScript/ast/ast_expressions.h
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ namespace das
virtual ExpressionPtr clone( const ExpressionPtr & expr = nullptr ) const override;
void autoDereference();
virtual SimNode * simulate (Context &) const override { return nullptr; }
SimNode * keepAlive ( Context &, SimNode * result ) const;
virtual ExpressionPtr visit(Visitor & vis) override;
virtual string describe() const;
virtual bool rtti_isCallLikeExpr() const override { return true; }
Expand Down
296 changes: 296 additions & 0 deletions include/daScript/simulate/runtime_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,166 @@ namespace das
}
};

//////////////////////////////
// FOR GOOD ARRAY (KEEP ALIVE)
//////////////////////////////

#if DAS_ENABLE_KEEPALIVE

template <int totalCount>
struct SimNodeKeepAlive_ForGoodArray : public SimNode_ForGoodArray<totalCount> {
SimNodeKeepAlive_ForGoodArray ( const LineInfo & at ) : SimNode_ForGoodArray<totalCount>(at) {}
DAS_EVAL_ABI virtual vec4f eval ( Context & context ) override {
DAS_PROFILE_NODE
Array * __restrict pha[totalCount];
char * __restrict ph[totalCount];
for ( int t=0; t!=totalCount; ++t ) {
pha[t] = cast<Array *>::to(sources[t]->eval(context));
array_lock(context, *pha[t], &this->debugInfo);
ph[t] = pha[t]->data;
}
char ** __restrict pi[totalCount];
int szz = INT_MAX;
for ( int t=0; t!=totalCount; ++t ) {
pi[t] = (char **)(context.stack.sp() + stackTop[t]);
szz = das::min(szz, int(pha[t]->size));
}
SimNode ** __restrict tail = list + total;
for (int i = 0; i!=szz; ++i) {
for (int t = 0; t != totalCount; ++t) {
*pi[t] = ph[t];
ph[t] += strides[t];
}
SimNode ** __restrict body = list;
loopbegin:;
DAS_KEEPALIVE_LOOP(&context);
for (; body!=tail; ++body) {
(*body)->eval(context);
DAS_PROCESS_LOOP_FLAGS(break);
}
}
loopend:;
for ( int t=0; t!=totalCount; ++t ) {
array_unlock(context, *pha[t], &this->debugInfo);
}
evalFinal(context);
context.stopFlags &= ~EvalFlags::stopForBreak;
return v_zero();
}
};

template <>
struct SimNodeKeepAlive_ForGoodArray<0> : public SimNode_ForGoodArray<0> {
SimNodeKeepAlive_ForGoodArray ( const LineInfo & at ) : SimNode_ForGoodArray<0>(at) {}
};

template <>
struct SimNodeKeepAlive_ForGoodArray<1> : public SimNode_ForGoodArray<1> {
SimNodeKeepAlive_ForGoodArray ( const LineInfo & at ) : SimNode_ForGoodArray<1>(at) {}
DAS_EVAL_ABI virtual vec4f eval ( Context & context ) override {
DAS_PROFILE_NODE
Array * __restrict pha;
char * __restrict ph;
pha = cast<Array *>::to(sources[0]->eval(context));
array_lock(context, *pha, &this->debugInfo);
ph = pha->data;
char ** __restrict pi;
int szz = int(pha->size);
pi = (char **)(context.stack.sp() + stackTop[0]);
auto stride = strides[0];
SimNode ** __restrict tail = list + total;
for (int i = 0; i!=szz; ++i) {
*pi = ph;
ph += stride;
SimNode ** __restrict body = list;
loopbegin:;
DAS_KEEPALIVE_LOOP(&context);
for (; body!=tail; ++body) {
(*body)->eval(context);
DAS_PROCESS_LOOP_FLAGS(break);
}
}
loopend:;
evalFinal(context);
array_unlock(context, *pha, &this->debugInfo);
context.stopFlags &= ~EvalFlags::stopForBreak;
return v_zero();
}
};

template <int totalCount>
struct SimNodeKeepAlive_ForGoodArray1 : public SimNode_ForGoodArray1<totalCount> {
SimNodeKeepAlive_ForGoodArray1 ( const LineInfo & at ) : SimNode_ForGoodArray1<totalCount>(at) {}
DAS_EVAL_ABI virtual vec4f eval ( Context & context ) override {
DAS_PROFILE_NODE
Array * __restrict pha[totalCount];
char * __restrict ph[totalCount];
for ( int t=0; t!=totalCount; ++t ) {
pha[t] = cast<Array *>::to(sources[t]->eval(context));
array_lock(context, *pha[t], &this->debugInfo);
ph[t] = pha[t]->data;
}
char ** __restrict pi[totalCount];
int szz = INT_MAX;
for ( int t=0; t!=totalCount; ++t ) {
pi[t] = (char **)(context.stack.sp() + stackTop[t]);
szz = das::min(szz, int(pha[t]->size));
}
SimNode * __restrict body = list[0];
for (int i = 0; i!=szz && !context.stopFlags; ++i) {
for (int t = 0; t != totalCount; ++t) {
*pi[t] = ph[t];
ph[t] += strides[t];
}
body->eval(context);
DAS_PROCESS_KEEPALIVE_LOOP1_FLAGS(continue);
}
loopend:;
evalFinal(context);
for ( int t=0; t!=totalCount; ++t ) {
array_unlock(context, *pha[t], &this->debugInfo);
}
context.stopFlags &= ~EvalFlags::stopForBreak;
return v_zero();
}
};

template <>
struct SimNodeKeepAlive_ForGoodArray1<0> : public SimNode_ForBase {
SimNodeKeepAlive_ForGoodArray1 ( const LineInfo & at ) : SimNode_ForBase(at) {}
};

template <>
struct SimNodeKeepAlive_ForGoodArray1<1> : public SimNode_ForBase {
SimNodeKeepAlive_ForGoodArray1 ( const LineInfo & at ) : SimNode_ForBase(at) {}
DAS_EVAL_ABI virtual vec4f eval ( Context & context ) override {
DAS_PROFILE_NODE
Array * __restrict pha;
char * __restrict ph;
pha = cast<Array *>::to(sources[0]->eval(context));
array_lock(context, *pha, &this->debugInfo);
ph = pha->data;
char ** __restrict pi;
int szz = int(pha->size);
pi = (char **)(context.stack.sp() + stackTop[0]);
auto stride = strides[0];
SimNode * __restrict body = list[0];
for (int i = 0; i!=szz && !context.stopFlags; ++i) {
*pi = ph;
ph += stride;
body->eval(context);
DAS_PROCESS_KEEPALIVE_LOOP1_FLAGS(continue);
}
loopend:;
evalFinal(context);
array_unlock(context, *pha, &this->debugInfo);
context.stopFlags &= ~EvalFlags::stopForBreak;
return v_zero();
}
};

#endif

///////////////////////
// FOR GOOD ARRAY DEBUG
///////////////////////
Expand Down Expand Up @@ -626,6 +786,142 @@ namespace das
}
};

#if DAS_ENABLE_KEEPALIVE

////////////////////////////
// FOR FIXED ARRAY KEEPALIVE
////////////////////////////

// FOR
template <int totalCount>
struct SimNodeKeepAlive_ForFixedArray : SimNode_ForFixedArray<totalCount> {
SimNodeKeepAlive_ForFixedArray ( const LineInfo & at ) : SimNode_ForFixedArray<totalCount>(at) {}
DAS_EVAL_ABI virtual vec4f eval ( Context & context ) override {
DAS_PROFILE_NODE
char * __restrict ph[totalCount];
for ( int t=0; t!=totalCount; ++t ) {
ph[t] = cast<char *>::to(sources[t]->eval(context));
}
char ** __restrict pi[totalCount];
for ( int t=0; t!=totalCount; ++t ) {
pi[t] = (char **)(context.stack.sp() + stackTop[t]);
}
SimNode ** __restrict tail = list + total;
for (uint32_t i=0, is=size; i!=is; ++i) {
for (int t = 0; t != totalCount; ++t) {
*pi[t] = ph[t];
ph[t] += strides[t];
}
SimNode ** __restrict body = list;
loopbegin:;
DAS_KEEPALIVE_LOOP(&context);
for (; body!=tail; ++body) {
(*body)->eval(context);
DAS_PROCESS_LOOP_FLAGS(break);
}
}
loopend:;
evalFinal(context);
context.stopFlags &= ~EvalFlags::stopForBreak;
return v_zero();
}
};

template <>
struct SimNodeKeepAlive_ForFixedArray<0> : SimNode_ForFixedArray<0> {
SimNodeKeepAlive_ForFixedArray ( const LineInfo & at ) : SimNode_ForFixedArray<0>(at) {}
};

template <>
struct SimNodeKeepAlive_ForFixedArray<1> : SimNode_ForFixedArray<1> {
SimNodeKeepAlive_ForFixedArray ( const LineInfo & at ) : SimNode_ForFixedArray<1>(at) {}
DAS_EVAL_ABI virtual vec4f eval ( Context & context ) override {
DAS_PROFILE_NODE
char * __restrict ph = cast<char *>::to(sources[0]->eval(context));
char ** __restrict pi = (char **)(context.stack.sp() + stackTop[0]);
auto stride = strides[0];
SimNode ** __restrict tail = list + total;
for (uint32_t i=0, is=size; i!=is; ++i) {
*pi = ph;
ph += stride;
SimNode ** __restrict body = list;
loopbegin:;
DAS_KEEPALIVE_LOOP(&context);
for (; body!=tail; ++body) {
(*body)->eval(context);
DAS_PROCESS_LOOP_FLAGS(break);
}
}
loopend:;
evalFinal(context);
context.stopFlags &= ~EvalFlags::stopForBreak;
return v_zero();
}
};

// FOR
template <int totalCount>
struct SimNodeKeepAlive_ForFixedArray1 : SimNode_ForFixedArray1<totalCount> {
SimNodeKeepAlive_ForFixedArray1 ( const LineInfo & at ) : SimNode_ForFixedArray1<totalCount>(at) {}
virtual SimNode * visit ( SimVisitor & vis ) override {
return visitFor(vis, totalCount, "ForFixedArray1");
}
DAS_EVAL_ABI virtual vec4f eval ( Context & context ) override {
DAS_PROFILE_NODE
char * __restrict ph[totalCount];
for ( int t=0; t!=totalCount; ++t ) {
ph[t] = cast<char *>::to(sources[t]->eval(context));
}
char ** __restrict pi[totalCount];
for ( int t=0; t!=totalCount; ++t ) {
pi[t] = (char **)(context.stack.sp() + stackTop[t]);
}
SimNode * __restrict body = list[0];
for (uint32_t i=0, is=size; i!=is && !context.stopFlags; ++i) {
for (int t = 0; t != totalCount; ++t) {
*pi[t] = ph[t];
ph[t] += strides[t];
}
body->eval(context);
DAS_PROCESS_KEEPALIVE_LOOP1_FLAGS(continue);
}
loopend:;
evalFinal(context);
context.stopFlags &= ~EvalFlags::stopForBreak;
return v_zero();
}
};

template <>
struct SimNodeKeepAlive_ForFixedArray1<0> : SimNode_ForFixedArray1<0> {
SimNodeKeepAlive_ForFixedArray1 ( const LineInfo & at ) : SimNode_ForFixedArray1<0>(at) {}
};

template <>
struct SimNodeKeepAlive_ForFixedArray1<1> : SimNode_ForFixedArray1<1> {
SimNodeKeepAlive_ForFixedArray1 ( const LineInfo & at ) : SimNode_ForFixedArray1<1>(at) {}
DAS_EVAL_ABI virtual vec4f eval ( Context & context ) override {
DAS_PROFILE_NODE
char * __restrict ph = cast<char *>::to(sources[0]->eval(context));
char ** __restrict pi = (char **)(context.stack.sp() + stackTop[0]);
auto stride = strides[0];
SimNode * __restrict body = list[0];
for (uint32_t i=0, is=size; i!=is && !context.stopFlags; ++i) {
*pi = ph;
ph += stride;
body->eval(context);
DAS_PROCESS_KEEPALIVE_LOOP1_FLAGS(continue);
}
loopend:;
evalFinal(context);
context.stopFlags &= ~EvalFlags::stopForBreak;
return v_zero();
}
};


#endif

////////////////////////
// FOR FIXED ARRAY DEBUG
////////////////////////
Expand Down
Loading

0 comments on commit c22a95a

Please sign in to comment.