diff --git a/compiler/generator/compile_scal.cpp b/compiler/generator/compile_scal.cpp index 2cdafaf4a4..ba39eddca6 100644 --- a/compiler/generator/compile_scal.cpp +++ b/compiler/generator/compile_scal.cpp @@ -42,7 +42,6 @@ #include "ppsig.hh" #include "prim2.hh" #include "recursivness.hh" -#include "sharing.hh" #include "sigDependenciesGraph.hh" #include "sigNewConstantPropagation.hh" #include "sigPromotion.hh" @@ -128,10 +127,6 @@ Tree ScalarCompiler::prepare(Tree LS) typeAnnotation(L2, true); // Annotate L2 with type information and check causality endTiming("L2 typeAnnotation"); - startTiming("sharingAnalysis"); - sharingAnalysis(L2, fSharingKey); // Annotate L2 with sharing count - endTiming("sharingAnalysis"); - startTiming("occurrences analysis"); delete fOccMarkup; fOccMarkup = new OccMarkup(fConditionProperty); @@ -164,7 +159,6 @@ Tree ScalarCompiler::prepare2(Tree L0) recursivnessAnnotation(L0); // Annotate L0 with recursivness information typeAnnotation(L0, true); // Annotate L0 with type information - sharingAnalysis(L0, fSharingKey); // annotate L0 with sharing count delete fOccMarkup; fOccMarkup = new OccMarkup(); @@ -866,28 +860,27 @@ string ScalarCompiler::generateCacheCode(Tree sig, const string& exp) } string vname, ctype; - int sharing = getSharingCount(sig, fSharingKey); Occurrences* o = fOccMarkup->retrieve(sig); faustassert(o); // check for expression occuring in delays if (o->getMaxDelay() > 0) { getTypedNames(getCertifiedSigType(sig), "Vec", ctype, vname); - if (sharing > 1) { + if (o->hasMultiOccurrences()) { return generateDelayVec(sig, generateVariableStore(sig, exp), ctype, vname, o->getMaxDelay(), o->getDelayCount()); } else { return generateDelayVec(sig, exp, ctype, vname, o->getMaxDelay(), o->getDelayCount()); } - } else if ((sharing > 1) || (o->hasMultiOccurrences())) { + } else if (o->hasMultiOccurrences()) { return generateVariableStore(sig, exp); - } else if (sharing == 1) { + } else if (o->getOccurrencesSum() == 1) { return exp; } else { - cerr << "ASSERT : sharing count (" << sharing << ") for " << *sig << endl; + cerr << "ASSERT : getOccurrencesSum (" << o->getOccurrencesSum() << ") for " << *sig << endl; faustassert(false); return {}; } diff --git a/compiler/generator/compile_vect.cpp b/compiler/generator/compile_vect.cpp index 3ffba52a8c..1c6c557914 100644 --- a/compiler/generator/compile_vect.cpp +++ b/compiler/generator/compile_vect.cpp @@ -26,7 +26,6 @@ #include "compile_vect.hh" #include "floats.hh" #include "ppsig.hh" -#include "sharing.hh" using namespace std; @@ -220,7 +219,6 @@ string VectorCompiler::generateLoopCode(Tree sig) string VectorCompiler::generateCacheCode(Tree sig, const string& exp) { string vname, ctype; - int sharing = getSharingCount(sig, fSharingKey); Type t = getCertifiedSigType(sig); Occurrences* o = fOccMarkup->retrieve(sig); int d = o->getMaxDelay(); @@ -234,7 +232,7 @@ string VectorCompiler::generateCacheCode(Tree sig, const string& exp) // it is a non-sample expressions but used delayed // we need a delay line getTypedNames(getCertifiedSigType(sig), "Vec", ctype, vname); - if ((sharing > 1) && !verySimple(sig)) { + if (o->hasMultiOccurrences() && !verySimple(sig)) { // first cache this expression because it // it is shared and complex string cachedexp = generateVariableStore(sig, exp); @@ -279,10 +277,10 @@ string VectorCompiler::generateCacheCode(Tree sig, const string& exp) } else { // not delayed Tree x, y; - if (sharing > 1 && isSigDelay(sig, x, y) && verySimple(y)) { + if (o->hasMultiOccurrences() && isSigDelay(sig, x, y) && verySimple(y)) { // cerr << "SPECIAL CASE NO CACHE NEEDED : " << ppsig(sig) << endl; return exp; - } else if (sharing > 1 && !verySimple(sig)) { + } else if (o->hasMultiOccurrences() && !verySimple(sig)) { // shared and not simple : we need a vector // cerr << "ZEC : " << ppsig(sig) << endl; getTypedNames(getCertifiedSigType(sig), "Zec", ctype, vname); @@ -306,7 +304,6 @@ bool VectorCompiler::needSeparateLoop(Tree sig) { Occurrences* o = fOccMarkup->retrieve(sig); Type t = getCertifiedSigType(sig); - int c = getSharingCount(sig, fSharingKey); bool b; int i; @@ -322,7 +319,7 @@ bool VectorCompiler::needSeparateLoop(Tree sig) } else if (isProj(sig, &i, x)) { // cerr << "REC "; // recursive expressions require a separate loop b = true; - } else if (c > 1) { + } else if (o->hasMultiOccurrences()) { // cerr << "SHA(" << c << ") "; // expressions used several times required a separate loop b = true; } else { diff --git a/compiler/generator/dag_instructions_compiler.cpp b/compiler/generator/dag_instructions_compiler.cpp index 1df9cf7e39..f14e7b3e5d 100644 --- a/compiler/generator/dag_instructions_compiler.cpp +++ b/compiler/generator/dag_instructions_compiler.cpp @@ -24,7 +24,6 @@ #include "dag_instructions_compiler.hh" #include "fir_to_fir.hh" #include "ppsig.hh" -#include "sharing.hh" #include "sigtyperules.hh" #include "timing.hh" @@ -283,7 +282,6 @@ ValueInst* DAGInstructionsCompiler::generateCacheCode(Tree sig, ValueInst* exp) { string vname; BasicTyped* ctype; - int sharing = getSharingCount(sig, fSharingKey); ::Type t = getCertifiedSigType(sig); Occurrences* o = fOccMarkup->retrieve(sig); int d = o->getMaxDelay(); @@ -299,7 +297,7 @@ ValueInst* DAGInstructionsCompiler::generateCacheCode(Tree sig, ValueInst* exp) getTypedNames(getCertifiedSigType(sig), "Vec", ctype, vname); Address::AccessType access; - if ((sharing > 1) && !verySimple(sig)) { + if (o->hasMultiOccurrences() && !verySimple(sig)) { // first cache this expression because it // it is shared and complex ValueInst* cachedexp = generateVariableStore(sig, exp); @@ -342,10 +340,10 @@ ValueInst* DAGInstructionsCompiler::generateCacheCode(Tree sig, ValueInst* exp) } else { // not delayed Tree x, y; - if (sharing > 1 && isSigDelay(sig, x, y) && verySimple(y)) { + if (o->hasMultiOccurrences() && isSigDelay(sig, x, y) && verySimple(y)) { // cerr << "SPECIAL CASE NO CACHE NEEDED : " << ppsig(sig) << endl; return exp; - } else if (sharing > 1 && !verySimple(sig)) { + } else if (o->hasMultiOccurrences() && !verySimple(sig)) { // shared and not simple : we need a vector // cerr << "Zec : " << ppsig(sig) << endl; getTypedNames(getCertifiedSigType(sig), "Zec", ctype, vname); @@ -373,7 +371,6 @@ bool DAGInstructionsCompiler::needSeparateLoop(Tree sig) { Occurrences* o = fOccMarkup->retrieve(sig); ::Type t = getCertifiedSigType(sig); - int c = getSharingCount(sig, fSharingKey); bool b; int i; @@ -387,7 +384,7 @@ bool DAGInstructionsCompiler::needSeparateLoop(Tree sig) b = false; } else if (isProj(sig, &i, x)) { b = true; - } else if (c > 1) { + } else if (o->hasMultiOccurrences()) { b = true; } else { // sample expressions that are not recursive, not delayed diff --git a/compiler/generator/instructions_compiler.cpp b/compiler/generator/instructions_compiler.cpp index f84ca46a74..4b41088a75 100644 --- a/compiler/generator/instructions_compiler.cpp +++ b/compiler/generator/instructions_compiler.cpp @@ -32,7 +32,6 @@ #include "normalform.hh" #include "prim2.hh" #include "recursivness.hh" -#include "sharing.hh" #include "sigPromotion.hh" #include "sigRetiming.hh" #include "sigToGraph.hh" @@ -120,9 +119,6 @@ Tree InstructionsCompiler::prepare(Tree LS) typeAnnotation(L2, true); // Annotate L2 with type information and check causality endTiming("L2 typeAnnotation"); - startTiming("sharingAnalysis"); - sharingAnalysis(L2, fSharingKey); // Annotate L2 with sharing count - endTiming("sharingAnalysis"); startTiming("occurrences analysis"); delete fOccMarkup; @@ -156,7 +152,6 @@ Tree InstructionsCompiler::prepare2(Tree L0) recursivnessAnnotation(L0); // Annotate L0 with recursivness information typeAnnotation(L0, true); // Annotate L0 with type information - sharingAnalysis(L0, fSharingKey); // Annotate L0 with sharing count delete fOccMarkup; fOccMarkup = new OccMarkup(); @@ -1049,28 +1044,27 @@ ValueInst* InstructionsCompiler::generateCacheCode(Tree sig, ValueInst* exp) string vname; BasicTyped* ctype; - int sharing = getSharingCount(sig, fSharingKey); Occurrences* o = fOccMarkup->retrieve(sig); faustassert(o); // Check for expression occuring in delays if (o->getMaxDelay() > 0) { getTypedNames(getCertifiedSigType(sig), "Vec", ctype, vname); - if (sharing > 1) { + if (o->hasMultiOccurrences()) { return generateDelayVec(sig, generateVariableStore(sig, exp), ctype, vname, o->getMaxDelay()); } else { return generateDelayVec(sig, exp, ctype, vname, o->getMaxDelay()); } - } else if (sharing > 1 || (o->hasMultiOccurrences())) { + } else if (o->hasMultiOccurrences()) { return generateVariableStore(sig, exp); - } else if (sharing == 1) { + } else if (o->getOccurrencesSum() == 1) { return exp; } else { - cerr << "ASSERT : in sharing count (" << sharing << ") for " << *sig << endl; + cerr << "ASSERT : getOccurrencesSum (" << o->getOccurrencesSum() << ") for " << *sig << endl; faustassert(false); return IB::genNullValueInst(); } @@ -1302,9 +1296,14 @@ ValueInst* InstructionsCompiler::generateBargraphAux(Tree sig, Tree path, ValueI ::Type t = getCertifiedSigType(sig); // Cast to external float - ValueInst* val = (gGlobal->gFAUSTFLOAT2Internal) ? exp : IB::genCastFloatMacroInst(exp); + ValueInst* bg_in = generateCacheCode(sig,exp); + ValueInst* val = (gGlobal->gFAUSTFLOAT2Internal) ? bg_in : IB::genCastFloatMacroInst(bg_in); StoreVarInst* res = IB::genStoreStructVar(varname, val); + string tempname; + BasicTyped* ctype; + getTypedNames(t, "Temp", ctype, tempname); + switch (t->variability()) { case kKonst: pushResetUIInstructions(res); @@ -1312,19 +1311,23 @@ ValueInst* InstructionsCompiler::generateBargraphAux(Tree sig, Tree path, ValueI case kBlock: { if (gGlobal->gExtControl) { - pushControlDeclare(res); + pushControlDeclare(IB::genDecStackVar(tempname, ctype, val)); + pushControlDeclare(IB::genStoreStructVar(varname, IB::genLoadStackVar(tempname))); } else { - pushComputeBlockMethod(res); + pushComputeBlockMethod(IB::genDecStackVar(tempname, ctype, val)); + pushComputeBlockMethod(IB::genStoreStructVar(varname, IB::genLoadStackVar(tempname))); } break; } case kSamp: - pushComputeDSPMethod(IB::genControlInst(getConditionCode(sig), res)); - break; + // pushComputeBlockMethod(IB::genDecStackVar(tempname, ctype));//c + pushComputeBlockMethod(IB::genDecStackVar(tempname, ctype, IB::genLoadStructVar(varname)));//initialize for rust + pushComputeDSPMethod(IB::genControlInst(getConditionCode(sig), IB::genStoreStackVar(tempname, val))); + pushPostComputeBlockMethod(IB::genStoreStructVar(varname, IB::genLoadStackVar(tempname))); + return IB::genLoadStackVar(tempname); } - - return generateCacheCode(sig, IB::genLoadStructVar(varname)); + return bg_in; } ValueInst* InstructionsCompiler::generateVBargraph(Tree sig, Tree path, ValueInst* exp) diff --git a/compiler/generator/occurrences.cpp b/compiler/generator/occurrences.cpp index 122629521c..4b1024cef1 100644 --- a/compiler/generator/occurrences.cpp +++ b/compiler/generator/occurrences.cpp @@ -53,6 +53,15 @@ int Occurrences::getOccurrence(int variability) const return fOccurrences[variability]; } +int Occurrences::getOccurrencesSum() const +{ + int sum = 0; + for (int i = 0; i < 4; i++) { + sum += fOccurrences[i]; + } + return sum; +} + Occurrences::Occurrences(int v, int r, Tree xc) : fXVariability(xVariability(v, r)) { for (int i = 0; i < 4; i++) { @@ -66,12 +75,16 @@ Occurrences::Occurrences(int v, int r, Tree xc) : fXVariability(xVariability(v, fExecCondition = xc; } -Occurrences* Occurrences::incOccurrences(int v, int r, int d, Tree xc) +Occurrences* Occurrences::incOccurrences(int v, int r, int d, Tree xc, bool is_not_attached) { int ctxt = xVariability(v, r); // assert (ctxt >= fXVariability); fOccurrences[ctxt] += 1; - fMultiOcc = fMultiOcc | (ctxt > fXVariability) | (fOccurrences[ctxt] > 1); + if (is_not_attached){ + fMultiOcc = fMultiOcc | (fOccurrences[ctxt] > 1); + } else { + fMultiOcc = fMultiOcc | (ctxt > fXVariability) | (fOccurrences[ctxt] > 1); + } if (d == 0) { // cerr << "Occurence outside a delay " << endl; fOutDelayOcc = true; @@ -147,7 +160,7 @@ Occurrences* OccMarkup::retrieve(Tree t) // xc : exec condition expression //------------------------------------------------------------------------------ -void OccMarkup::incOcc(Tree env, int v, int r, int d, Tree xc, Tree t) +void OccMarkup::incOcc(Tree env, int v, int r, int d, Tree xc, Tree t, bool is_not_attached) { // Check if we have already visited this tree Occurrences* occ = getOcc(t); @@ -178,13 +191,17 @@ void OccMarkup::incOcc(Tree env, int v, int r, int d, Tree xc, Tree t) int n = getSubSignals(t, br); if (n > 0 && !isSigGen(t)) { for (int i = 0; i < n; i++) { - incOcc(env, v0, r0, 0, c0, br[i]); + if (t->node() == gGlobal->SIGATTACH && i==1){//count second not attached arm differently + incOcc(env, v0, r0, 0, c0, br[i], true); + } else { + incOcc(env, v0, r0, 0, c0, br[i], is_not_attached); + } } } } } - occ->incOccurrences(v, r, d, xc); + occ->incOccurrences(v, r, d, xc, is_not_attached); if (!firstVisit) { // Special case for -1*y. Because the sharing of -1*y will be ignored diff --git a/compiler/generator/occurrences.hh b/compiler/generator/occurrences.hh index 833d73c13b..a9ca9b8ec0 100644 --- a/compiler/generator/occurrences.hh +++ b/compiler/generator/occurrences.hh @@ -40,7 +40,7 @@ class Occurrences : public virtual Garbageable { public: Occurrences(int v, int r, Tree xc); Occurrences* incOccurrences(int v, int r, int d, - Tree xc); ///< inc occurrences in context v,r,d,xc + Tree xc, bool is_not_attached = false); ///< inc occurrences in context v,r,d,xc bool hasMultiOccurrences() const; ///< true if multiple occurrences or occ. in higher ctxt bool hasOutDelayOccurrences() const; ///< true if has occurrences outside a a delay @@ -49,6 +49,7 @@ class Occurrences : public virtual Garbageable { int getDelayCount() const; Tree getExecCondition() const; ///< return the exec condition int getOccurrence(int variability) const; ///< return the number of occurrence by variability + int getOccurrencesSum() const; ///< return the number of occurrence by variability }; /** @@ -61,7 +62,7 @@ class OccMarkup : public virtual Garbageable { std::map fConditions; ///< condition associated to each tree void incOcc(Tree env, int v, int r, int d, Tree xc, - Tree t); ///< inc the occurrence of t in context v,r + Tree t, bool is_not_attached = false); ///< inc the occurrence of t in context v,r Occurrences* getOcc(Tree t); ///< get Occurrences property of t or null void setOcc(Tree t, Occurrences* occ); ///< set Occurrences property of t diff --git a/compiler/signals/sharing.cpp b/compiler/signals/sharing.cpp deleted file mode 100644 index 5787af5591..0000000000 --- a/compiler/signals/sharing.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/************************************************************************ - ************************************************************************ - FAUST compiler - Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale - --------------------------------------------------------------------- - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - ************************************************************************ - ************************************************************************/ - -/***************************************************************************** -****************************************************************************** - FAUST SIGNAL COMPILER - Y. Orlarey, (c) Grame 2002 ------------------------------------------------------------------------------- - History : - --------- - 2002-02-08 : First version - -****************************************************************************** -*****************************************************************************/ - -#include - -#include "sharing.hh" -#include "sigtyperules.hh" - -using namespace std; - -/***************************************************************************** -****************************************************************************** - - SHARING ANALYSIS - -****************************************************************************** -*****************************************************************************/ - -static void setSharingCount(Tree sig, Tree key, int count) -{ - setProperty(sig, key, tree(count)); -} - -//------------------------------------------------------------------------------ -// Create a specific property key for the sharing count of subtrees of t -//------------------------------------------------------------------------------ - -static void sharingAnnotation(int vctxt, Tree sig, Tree key) -{ - int count = getSharingCount(sig, key); - if (count > 0) { - // it is not our first visit - setSharingCount(sig, key, count + 1); - - } else { - // it is our first visit, - int v = getCertifiedSigType(sig)->variability(); - - // check "time sharing" cases - if (v < vctxt) { - setSharingCount(sig, key, - 2); // time sharing occurence : slower expression in faster context - } else { - setSharingCount(sig, key, 1); // regular occurence - } - - // Annotate the sub signals - tvec subsig; - int n = getSubSignals(sig, subsig); - if (n > 0 && !isSigGen(sig)) { - for (int i = 0; i < n; i++) { - sharingAnnotation(v, subsig[i], key); - } - } - } -} - -//------------------------------------------------------------------------------ -// Get the sharing count of sig -//------------------------------------------------------------------------------ - -int getSharingCount(Tree sig, Tree key) -{ - Tree c; - if (getProperty(sig, key, c)) { - return c->node().getInt(); - } else { - return 0; - } -} - -//------------------------------------------------------------------------------ -// Create a specific property key for the sharing count of subtrees of sig -//------------------------------------------------------------------------------ - -void sharingAnalysis(Tree sig, Tree& key) -{ - key = shprkey(sig); - if (isList(sig)) { - while (isList(sig)) { - sharingAnnotation(kSamp, hd(sig), key); - sig = tl(sig); - } - } else { - sharingAnnotation(kSamp, sig, key); - } -} diff --git a/compiler/signals/sharing.hh b/compiler/signals/sharing.hh deleted file mode 100644 index 1253e3bdaf..0000000000 --- a/compiler/signals/sharing.hh +++ /dev/null @@ -1,34 +0,0 @@ -/************************************************************************ - ************************************************************************ - FAUST compiler - Copyright (C) 2023 GRAME, Centre National de Creation Musicale - --------------------------------------------------------------------- - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - ************************************************************************ - ************************************************************************/ - -#include "tlib.hh" - -//------------------------------------------------------------------------------ -// Get the sharing count of sig -//------------------------------------------------------------------------------ - -int getSharingCount(Tree sig, Tree key); - -//------------------------------------------------------------------------------ -// Create a specific property key for the sharing count of subtrees of sig -//------------------------------------------------------------------------------ - -void sharingAnalysis(Tree t, Tree& key);