From bd4f1d380845e1eaa50817ec3d978ed1c8f3ce7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Letz?= Date: Fri, 21 Feb 2025 14:06:06 +0100 Subject: [PATCH] Handle ma.SR adaptation in propagate. --- compiler/draw/drawschema.cpp | 4 +- compiler/draw/schema/downsamplingSchema.cpp | 7 ++-- compiler/draw/schema/upsamplingSchema.cpp | 2 +- compiler/draw/sigToGraph.cpp | 6 +-- compiler/generator/code_container.hh | 7 +++- compiler/generator/instructions.hh | 38 ++++++++++++++++++- compiler/generator/instructions_compiler.cpp | 32 ++++++++-------- compiler/normalize/normalform.cpp | 4 +- compiler/parallelize/code_loop.cpp | 18 +++++++-- compiler/parallelize/code_loop.hh | 24 ++++++++++-- compiler/propagate/propagate.cpp | 24 +++++++++--- compiler/signals/ppsig.cpp | 6 +-- compiler/signals/sigtyperules.cpp | 3 +- compiler/transform/sigIdentity.cpp | 2 +- .../transform/sigNewConstantPropagation.cpp | 5 ++- compiler/transform/treeTransform.cpp | 2 +- 16 files changed, 133 insertions(+), 51 deletions(-) diff --git a/compiler/draw/drawschema.cpp b/compiler/draw/drawschema.cpp index 318f0a3c72..b3b52eb4eb 100644 --- a/compiler/draw/drawschema.cpp +++ b/compiler/draw/drawschema.cpp @@ -48,6 +48,7 @@ #include "compatibility.hh" #include "description.hh" #include "devLib.h" +#include "downsamplingSchema.h" #include "drawschema.hh" #include "exception.hh" #include "files.hh" @@ -56,13 +57,12 @@ #include "occur.hh" #include "occurrences.hh" #include "ondemandSchema.h" -#include "upsamplingSchema.h" -#include "downsamplingSchema.h" #include "ppbox.hh" #include "prim2.hh" #include "property.hh" #include "routeSchema.h" #include "schema.h" +#include "upsamplingSchema.h" #include "xtended.hh" #if 0 diff --git a/compiler/draw/schema/downsamplingSchema.cpp b/compiler/draw/schema/downsamplingSchema.cpp index 55bd8ae54c..00158479bd 100644 --- a/compiler/draw/schema/downsamplingSchema.cpp +++ b/compiler/draw/schema/downsamplingSchema.cpp @@ -21,8 +21,8 @@ #include -#include "exception.hh" #include "downsamplingSchema.h" +#include "exception.hh" using namespace std; @@ -31,8 +31,9 @@ const double downsamplingSchema::fTopMargin( const double downsamplingSchema::fHorMargin(10); // left and right gap const double downsamplingSchema::fBotMargin( 10); // gap between the bottom and the bottom of the inside schema -const double downsamplingSchema::fMinWidth(50); // Minimal width of an downsampling block -const string downsamplingSchema::fText("downsampling"); // Test to display, tipically "downsampling" +const double downsamplingSchema::fMinWidth(50); // Minimal width of an downsampling block +const string downsamplingSchema::fText( + "downsampling"); // Test to display, tipically "downsampling" /** * Returns an enlarged schema, but only if really needed diff --git a/compiler/draw/schema/upsamplingSchema.cpp b/compiler/draw/schema/upsamplingSchema.cpp index 354e3959b3..531457eb7f 100644 --- a/compiler/draw/schema/upsamplingSchema.cpp +++ b/compiler/draw/schema/upsamplingSchema.cpp @@ -31,7 +31,7 @@ const double upsamplingSchema::fTopMargin( const double upsamplingSchema::fHorMargin(10); // left and right gap const double upsamplingSchema::fBotMargin( 10); // gap between the bottom and the bottom of the inside schema -const double upsamplingSchema::fMinWidth(50); // Minimal width of an upsampling block +const double upsamplingSchema::fMinWidth(50); // Minimal width of an upsampling block const string upsamplingSchema::fText("upsampling"); // Test to display, tipically "upsampling" /** diff --git a/compiler/draw/sigToGraph.cpp b/compiler/draw/sigToGraph.cpp index 63f5384791..2d6e4d1937 100644 --- a/compiler/draw/sigToGraph.cpp +++ b/compiler/draw/sigToGraph.cpp @@ -324,11 +324,9 @@ static string sigLabel(Tree sig) else if (isSigAssertBounds(sig, x, y, z)) { fout << "assertbounds"; - } - else if (isSigLowest(sig, x)) { + } else if (isSigLowest(sig, x)) { fout << "lowest"; - } - else if (isSigHighest(sig, x)) { + } else if (isSigHighest(sig, x)) { fout << "highest"; } diff --git a/compiler/generator/code_container.hh b/compiler/generator/code_container.hh index 9a3ba7f122..7170639e1d 100644 --- a/compiler/generator/code_container.hh +++ b/compiler/generator/code_container.hh @@ -494,9 +494,14 @@ class CodeContainer : public virtual Garbageable { void openUSblock(ValueInst* us_factor) { fCurLoop->openUSblock(us_factor); } void closeUSblock() { fCurLoop->closeUSblock(); } - void openDSblock(ValueInst* ds_factor, const std::string& ds_counter) { fCurLoop->openDSblock(ds_factor, ds_counter); } + void openDSblock(ValueInst* ds_factor, const std::string& ds_counter) + { + fCurLoop->openDSblock(ds_factor, ds_counter); + } void closeDSblock() { fCurLoop->closeDSblock(); } + ValueInst* getSRFactor() { return fCurLoop->getSRFactor(); } + void generateExtGlobalDeclarations(InstVisitor* visitor) { if (fExtGlobalDeclarationInstructions->fCode.size() > 0) { diff --git a/compiler/generator/instructions.hh b/compiler/generator/instructions.hh index 066f6fb623..c88485e1a0 100644 --- a/compiler/generator/instructions.hh +++ b/compiler/generator/instructions.hh @@ -3100,12 +3100,46 @@ struct IB { static ValueInst* genMul(ValueInst* a1, ValueInst* a2) { - return isOne(a1) ? a2 : (isOne(a2) ? a1 : genBinopInst(kMul, a1, a2)); + if (isOne(a1)) { + return a2; + } else if (isOne(a2)) { + return a1; + } else if (castInt32(a1) && castInt32(a2)) { + return genInt32NumInst(castInt32(a1)->fNum * castInt32(a2)->fNum); + } else if (castInt64(a1) && castInt64(a2)) { + return genInt64NumInst(castInt64(a1)->fNum * castInt64(a2)->fNum); + } else if (castFloat(a1) && castFloat(a2)) { + return genFloatNumInst(castFloat(a1)->fNum * castFloat(a2)->fNum); + } else if (castDouble(a1) && castDouble(a2)) { + return genDoubleNumInst(castDouble(a1)->fNum * castDouble(a2)->fNum); + } else if (castQuad(a1) && castQuad(a2)) { + return genQuadNumInst(castQuad(a1)->fNum * castQuad(a2)->fNum); + } else if (castFixed(a1) && castFixed(a2)) { + return genFixedPointNumInst(castFixed(a1)->fNum * castFixed(a2)->fNum); + } else { + return genBinopInst(kMul, a1, a2); + } } static ValueInst* genDiv(ValueInst* a1, ValueInst* a2) { - return isOne(a2) ? a1 : genBinopInst(kDiv, a1, a2); + if (isOne(a2)) { + return a1; + } else if (castInt32(a1) && castInt32(a2)) { + return genInt32NumInst(castInt32(a1)->fNum / castInt32(a2)->fNum); + } else if (castInt64(a1) && castInt64(a2)) { + return genInt64NumInst(castInt64(a1)->fNum / castInt64(a2)->fNum); + } else if (castFloat(a1) && castFloat(a2)) { + return genFloatNumInst(castFloat(a1)->fNum / castFloat(a2)->fNum); + } else if (castDouble(a1) && castDouble(a2)) { + return genDoubleNumInst(castDouble(a1)->fNum / castDouble(a2)->fNum); + } else if (castQuad(a1) && castQuad(a2)) { + return genQuadNumInst(castQuad(a1)->fNum / castQuad(a2)->fNum); + } else if (castFixed(a1) && castFixed(a2)) { + return genFixedPointNumInst(castFixed(a1)->fNum / castFixed(a2)->fNum); + } else { + return genBinopInst(kDiv, a1, a2); + } } static BinopInst* genRem(ValueInst* a1, ValueInst* a2) { return genBinopInst(kRem, a1, a2); } diff --git a/compiler/generator/instructions_compiler.cpp b/compiler/generator/instructions_compiler.cpp index 1428ed8d15..60d4872ae7 100644 --- a/compiler/generator/instructions_compiler.cpp +++ b/compiler/generator/instructions_compiler.cpp @@ -389,14 +389,14 @@ bool InstructionsCompiler::getCompiledExpression(Tree sig, ValueType& cexp) } /** - * Set the ValueType of a compiled expression is already compiled + * Set the ValueType of a compiled expression if already compiled * @param sig the signal expression to compile. * @param cexp the ValueType representing the compiled expression. * @return the cexp (for commodity) */ -ValueType InstructionsCompiler::setCompiledExpression(Tree sig, const ValueType& cexp) +ValueInst* InstructionsCompiler::setCompiledExpression(Tree sig, const ValueType& cexp) { - ValueType old; + ValueInst* old; if (fCompileProperty.get(sig, old) && (old != cexp)) { // stringstream error; // error << "ERROR already a compiled expression attached : " << old << " replaced by " << @@ -845,7 +845,7 @@ void InstructionsCompiler::compileSingleSignal(Tree sig) ValueInst* InstructionsCompiler::generateCode(Tree sig) { -#if 0 +#if 1 fprintf(stderr, "CALL generateCode("); printSignal(sig, stderr); fprintf(stderr, ")\n"); @@ -1333,7 +1333,7 @@ ValueInst* InstructionsCompiler::generateVariableStore(Tree sig, ValueInst* exp) getTypedNames(t, "Const", ctype, vname); // TODO: deactivated for now since getOccurrence fails in some cases - + // The variable is used in compute (kBlock or kSamp), // so define is as a field in the DSP struct if (o->getOccurrence(kBlock) || o->getOccurrence(kSamp)) { @@ -1345,7 +1345,7 @@ ValueInst* InstructionsCompiler::generateVariableStore(Tree sig, ValueInst* exp) pushInitMethod(IB::genDecStackVar(vname, ctype, exp)); return IB::genLoadStackVar(vname); } - + /* // Always put variables in DSP struct for now pushDeclare(IB::genDecStructVar(vname, ctype)); @@ -3617,18 +3617,18 @@ ValueInst* InstructionsCompiler::generateUS(Tree sig, const tvec& w) outputs.push_back(w[i]); } } + + std::cout << "opening upsampling statement" << std::endl; + + // 2/ We compile the clock signal and open an us statement + fContainer->getCurLoop()->openUSblock(CS(clock)); - // 2/ We compile the input signals unconditionnally + // 3/ We then compile the input signals unconditionnally for (Tree x : inputs) { ValueInst* temp = CS(x); - dump2FIR(temp); + //dump2FIR(temp); } - - std::cout << "opening upsampling statement" << std::endl; - - // 3/ We then compile the clock signal and open an us statement - fContainer->getCurLoop()->openUSblock(CS(clock)); - + // 4/ Compute the scheduling of the output signals of the us circuit std::vector V = ondemandCompilationOrder(outputs); @@ -3653,11 +3653,11 @@ ValueInst* InstructionsCompiler::generateDS(Tree sig, const tvec& w) fDSCounter = "fDSCounter"; pushDeclare(IB::genDecStructVar(fDSCounter, IB::genInt32Typed())); pushClearMethod(IB::genStoreStructVar(fDSCounter, IB::genInt32NumInst(0))); - + FIRIndex value = FIRIndex(IB::genLoadStructVar(fDSCounter)) + 1; pushPostComputeDSPMethod(IB::genStoreStructVar(fDSCounter, value)); } - + // 1/ We extract the clock, the inputs and the outputs signals // form w = [clock, input1, input2, ..., nil, output1, output2, ...] faustassert(w.size() > 2); diff --git a/compiler/normalize/normalform.cpp b/compiler/normalize/normalform.cpp index 7e8586c543..cb6d5c797e 100644 --- a/compiler/normalize/normalform.cpp +++ b/compiler/normalize/normalform.cpp @@ -43,7 +43,7 @@ static Tree simplifyToNormalFormAux(Tree LS) // Update the SR value using US/DS information. startTiming("L4 signalSampleRate"); - L1 = signalSampleRate(L1); + // L1 = signalSampleRate(L1); endTiming("L4 signalSampleRate"); // Annotate L1 with type information @@ -145,7 +145,7 @@ static Tree simplifyToNormalFormAux(Tree LS) startTiming("L4 signalChecker"); SignalChecker checker(L4); endTiming("L4 signalChecker"); - //std::cout << ppsig(L4) << std::endl; + // std::cout << ppsig(L4) << std::endl; return L4; } diff --git a/compiler/parallelize/code_loop.cpp b/compiler/parallelize/code_loop.cpp index 38e854d7ec..b2cb75c8bc 100644 --- a/compiler/parallelize/code_loop.cpp +++ b/compiler/parallelize/code_loop.cpp @@ -357,6 +357,10 @@ void CodeLoop::closeUSblock() ForLoopInst* loop = IB::genForLoopInst(loop_decl, loop_end, loop_inc); loop->pushFrontInst(us_block); pushComputeDSPMethod(loop); + // Adjust fSRFactor + // fSRFactor = IB::genDiv(fSRFactor, b->fUSfactor); + // pushComputeDSPMethod(IB::genStoreStructVar("fIntSampleRate", + // IB::genDiv(IB::genLoadStructVar("fIntSampleRate"), b->fUSfactor))); } void CodeLoop::closeDSblock() @@ -364,15 +368,21 @@ void CodeLoop::closeDSblock() CodeDSblock* b = dynamic_cast(fCodeStack.top()); faustassert(b); fCodeStack.pop(); - + BlockInst* ds_block1 = new BlockInst(); ds_block1->pushBackInst(b->fPreInst); ds_block1->pushBackInst(b->fComputeInst); ds_block1->pushBackInst(b->fPostInst); - + BlockInst* ds_block2 = new BlockInst(); - ds_block2->pushBackInst(IB::genIfInst( - IB::genEqual(IB::genRem(IB::genLoadStructVar(b->fDSCounter), b->fDSfactor), IB::genInt32NumInst(0)), ds_block1)); + ds_block2->pushBackInst( + IB::genIfInst(IB::genEqual(IB::genRem(IB::genLoadStructVar(b->fDSCounter), b->fDSfactor), + IB::genInt32NumInst(0)), + ds_block1)); pushComputeDSPMethod(ds_block2); + // Adjust fSRFactor + // fSRFactor = IB::genMul(fSRFactor, b->fDSfactor); + // pushComputeDSPMethod(IB::genStoreStructVar("fIntSampleRate", + // IB::genMul(IB::genLoadStructVar("fIntSampleRate"), b->fDSfactor))); } diff --git a/compiler/parallelize/code_loop.hh b/compiler/parallelize/code_loop.hh index 26e9e35c76..bc6cc6a909 100644 --- a/compiler/parallelize/code_loop.hh +++ b/compiler/parallelize/code_loop.hh @@ -88,10 +88,13 @@ struct CodeUSblock : public Codeblock { }; struct CodeDSblock : public Codeblock { - ValueInst* fDSfactor; ///< downsampling factor of the US block + ValueInst* fDSfactor; ///< downsampling factor of the US block std::string fDSCounter; - CodeDSblock(ValueInst* ds_factor, const std::string& ds_counter) : Codeblock(), fDSfactor(ds_factor), fDSCounter(ds_counter) {} + CodeDSblock(ValueInst* ds_factor, const std::string& ds_counter) + : Codeblock(), fDSfactor(ds_factor), fDSCounter(ds_counter) + { + } }; class CodeLoop : public virtual Garbageable { @@ -113,6 +116,8 @@ class CodeLoop : public virtual Garbageable { std::stack fCodeStack; //< stack of IF/US/DS code blocks + ValueInst* fSRFactor; + int fUseCount; ///< how many loops depend on this one std::list fExtraLoops; ///< extra loops that where in sequences @@ -150,6 +155,7 @@ class CodeLoop : public virtual Garbageable { fComputeInst(new BlockInst()), fPostInst(new BlockInst()), fLoopIndex(index_name), + fSRFactor(IB::genInt32NumInst(1)), fUseCount(0) { } @@ -166,6 +172,7 @@ class CodeLoop : public virtual Garbageable { fComputeInst(new BlockInst()), fPostInst(new BlockInst()), fLoopIndex(index_name), + fSRFactor(IB::genInt32NumInst(1)), fUseCount(0) { } @@ -208,14 +215,15 @@ class CodeLoop : public virtual Garbageable { ValueInst* getLoopIndex() { if (fCodeStack.size() > 0) { - CodeUSblock* us_block = dynamic_cast(fCodeStack.top()); - if (us_block) { + if (CodeUSblock* us_block = dynamic_cast(fCodeStack.top())) { return IB::genLoadLoopVar(us_block->fLoopIndex); } } return IB::genLoadLoopVar(fLoopIndex); } + ValueInst* getSRFactor() { return fSRFactor; } + ForLoopInst* generateScalarLoop(const std::string& counter, bool loop_var_in_bytes = false); // For SYFALA : loop with a fixed size (known at compile time) @@ -276,6 +284,10 @@ class CodeLoop : public virtual Garbageable { { CodeUSblock* b = new CodeUSblock(us_factor); fCodeStack.push(b); + // Adjust fSRFactor + // fSRFactor = IB::genMul(fSRFactor, us_factor); + // pushComputeDSPMethod(IB::genStoreStructVar("fIntSampleRate", + // IB::genMul(IB::genLoadStructVar("fIntSampleRate"), us_factor))); } /** @@ -291,6 +303,10 @@ class CodeLoop : public virtual Garbageable { { CodeDSblock* b = new CodeDSblock(ds_factor, ds_counter); fCodeStack.push(b); + // Adjust fSRFactor + // fSRFactor = IB::genDiv(fSRFactor, ds_factor); + // pushComputeDSPMethod(IB::genStoreStructVar("fIntSampleRate", + // IB::genDiv(IB::genLoadStructVar("fIntSampleRate"), ds_factor))); } /** diff --git a/compiler/propagate/propagate.cpp b/compiler/propagate/propagate.cpp index c0682a85b8..2d85c067f2 100644 --- a/compiler/propagate/propagate.cpp +++ b/compiler/propagate/propagate.cpp @@ -277,7 +277,19 @@ static siglist realPropagate(Tree clockenv, Tree slotenv, Tree path, Tree box, c else if (isBoxFConst(box, type, name, file)) { faustassert(lsig.size() == 0); - return makeList(sigFConst(type, name, file)); + // Specific case for sampling rate (ma.SR) + string vname = string(tree2str(name)); + if ((vname == "fSamplingFreq") || (vname == "fSamplingRate")) { + Tree clock = hd(clockenv); + Tree us_ds = hd(tl(clockenv)); + if (us_ds == tree("Upsampling")) { + return makeList(sigMul(sigFConst(type, name, file), clock)); + } else if (us_ds == tree("Downsampling")) { + return makeList(sigDiv(sigFConst(type, name, file), clock)); + } + } else { + return makeList(sigFConst(type, name, file)); + } } else if (isBoxFVar(box, type, name, file)) { @@ -699,8 +711,9 @@ static siglist realPropagate(Tree clockenv, Tree slotenv, Tree path, Tree box, c // 3/ We compute the clock environment inside the upsampling by combining the clock, the // address of the circuit, and the current clock environment - Tree addr = boxPrim0((prim0)box); - Tree clockenv2 = cons(H, cons(addr, clockenv)); + Tree addr = boxPrim0((prim0)box); + // Tree clockenv2 = cons(H, cons(addr, clockenv)); + Tree clockenv2 = cons(H, cons(tree("Upsampling"), clockenv)); // 4/ We compute X1 the inputs of the ondemand using temporary variables siglist X1; @@ -764,8 +777,9 @@ static siglist realPropagate(Tree clockenv, Tree slotenv, Tree path, Tree box, c // 3/ We compute the clock environment inside the downsampling by combining the clock, the // address of the circuit, and the current clock environment - Tree addr = boxPrim0((prim0)box); - Tree clockenv2 = cons(H, cons(addr, clockenv)); + Tree addr = boxPrim0((prim0)box); + // Tree clockenv2 = cons(H, cons(addr, clockenv)); + Tree clockenv2 = cons(H, cons(tree("Downsampling"), clockenv)); // 4/ We compute X1 the inputs of the downsampling using temporary variables siglist X1; diff --git a/compiler/signals/ppsig.cpp b/compiler/signals/ppsig.cpp index 8599ecdb24..892528b231 100644 --- a/compiler/signals/ppsig.cpp +++ b/compiler/signals/ppsig.cpp @@ -492,7 +492,7 @@ ostream& ppsigShared::printfun(ostream& fout, const string& funame, const tvec& fout << sep << ppsigShared(arg, fEnv); sep = ','; } - return fout << ")"; + return fout << ')'; } ostream& ppsigShared::printui(ostream& fout, const string& funame, Tree label) const @@ -523,11 +523,11 @@ ostream& ppsigShared::printui(ostream& fout, const string& funame, Tree label, T ostream& ppsigShared::printout(ostream& fout, int i, Tree x) const { if (fPriority > 0) { - fout << "("; + fout << '('; } fout << "OUT" << i << " = " << ppsigShared(x, fEnv, 0); if (fPriority > 0) { - fout << ")"; + fout << ')'; } return fout; } diff --git a/compiler/signals/sigtyperules.cpp b/compiler/signals/sigtyperules.cpp index 61f43f3753..2822baa6b4 100644 --- a/compiler/signals/sigtyperules.cpp +++ b/compiler/signals/sigtyperules.cpp @@ -769,7 +769,8 @@ static Type inferSigType(Tree sig, Tree env) return castInterval(sampCast(t1), itv::reunion(t1->getInterval(), interval(0, 0))); } else if (Tree x, y; isSigZeroPad(sig, x, y)) { - return T(x, env); + Type t1 = T(x, env); + return castInterval(sampCast(t1), itv::reunion(t1->getInterval(), interval(0, 0))); } else if (Tree x, y; isSigDecimate(sig, x, y)) { return T(x, env); diff --git a/compiler/transform/sigIdentity.cpp b/compiler/transform/sigIdentity.cpp index dbc54a1e5d..540ebf7c6c 100644 --- a/compiler/transform/sigIdentity.cpp +++ b/compiler/transform/sigIdentity.cpp @@ -338,6 +338,6 @@ Tree SignalIdentityImp::transformation(Tree sig) return nullptr; } - // Explicit instanciation for CACHE = true and false +// Explicit instanciation for CACHE = true and false template class SignalIdentityImp; template class SignalIdentityImp; diff --git a/compiler/transform/sigNewConstantPropagation.cpp b/compiler/transform/sigNewConstantPropagation.cpp index 253e75d833..220f61d0e8 100644 --- a/compiler/transform/sigNewConstantPropagation.cpp +++ b/compiler/transform/sigNewConstantPropagation.cpp @@ -63,8 +63,11 @@ static void explainInterval(Tree sig) Tree SigNewConstantPropagation::transformation(Tree sig) { if (Tree h, x; isSigClocked(sig, h, x)) { - return sigClocked(h, self(x)); + return SignalIdentity::transformation(sig); + } else if (Tree x, y; isSigZeroPad(sig, x, y)) { + return SignalIdentity::transformation(sig); } + Type tt = getCertifiedSigType(sig); interval I = tt->getInterval(); diff --git a/compiler/transform/treeTransform.cpp b/compiler/transform/treeTransform.cpp index 6bfd00aa84..0110f5066d 100644 --- a/compiler/transform/treeTransform.cpp +++ b/compiler/transform/treeTransform.cpp @@ -23,8 +23,8 @@ #include #include "Text.hh" -#include "treeTransform.hh" #include "list.hh" +#include "treeTransform.hh" using namespace std;