string VectorCompiler::generateDelayVec(Tree sig, const string& exp, const string& ctype, const string& vname, int mxd) { // it is a non-sample but used delayed // we need a delay line generateDelayLine(ctype, vname, mxd, exp); setVectorNameProperty(sig, vname); if (verySimple(sig)) { return exp; } else { return subst("$0[i]", vname); } }
/** * Generate code for a group of mutually recursive definitions */ void DocCompiler::generateRec(Tree sig, Tree var, Tree le, int priority) { int N = len(le); vector<bool> used(N); vector<int> delay(N); vector<string> vname(N); vector<string> ctype(N); // prepare each element of a recursive definition for(int i = 0; i < N; i++) { Tree e = sigProj(i, sig); // recreate each recursive definition if(fOccMarkup.retrieve(e)) { // this projection is used used[i] = true; // cerr << "generateRec : used[" << i << "] = true" << endl; getTypedNames(getCertifiedSigType(e), "r", ctype[i], vname[i]); gDocNoticeFlagMap["recursigs"] = true; // cerr << "- r : generateRec setVectorNameProperty : \"" << vname[i] << "\"" << endl; setVectorNameProperty(e, vname[i]); delay[i] = fOccMarkup.retrieve(e)->getMaxDelay(); } else { // this projection is not used therefore // we should not generate code for it used[i] = false; // cerr << "generateRec : used[" << i << "] = false" << endl; } } // generate delayline for each element of a recursive definition for(int i = 0; i < N; i++) { if(used[i]) { generateDelayLine(ctype[i], vname[i], delay[i], CS(nth(le, i), priority)); } } }
/** * Generate cache code for a signal if needed * @param sig the signal expression. * @param exp the corresponding C code. * @return the cached C code */ string VectorCompiler::generateCacheCode(Tree sig, const string& exp) { string vname, ctype; int sharing = getSharingCount(sig); Type t = getCertifiedSigType(sig); Occurences* o = fOccMarkup.retrieve(sig); int d = o->getMaxDelay(); if (t->variability() < kSamp) { if (d==0) { // non-sample, not delayed : same as scalar cache return ScalarCompiler::generateCacheCode(sig,exp); } else { // 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)) { // first cache this expression because it // it is shared and complex string cachedexp = generateVariableStore(sig, exp); generateDelayLine(ctype, vname, d, cachedexp); setVectorNameProperty(sig, vname); return cachedexp; } else { // no need to cache this expression because // it is either not shared or very simple generateDelayLine(ctype, vname, d, exp); setVectorNameProperty(sig, vname); return exp; } } } else { // sample-rate signal if (d > 0) { // used delayed : we need a delay line getTypedNames(getCertifiedSigType(sig), "Yec", ctype, vname); generateDelayLine(ctype, vname, d, exp); setVectorNameProperty(sig, vname); if (verySimple(sig)) { return exp; } else { if (d < gMaxCopyDelay) { return subst("$0[i]", vname); } else { // we use a ring buffer string mask = T(pow2limit(d + gVecSize)-1); return subst("$0[($0_idx+i) & $1]", vname, mask); } } } else { // not delayed if ( sharing > 1 && ! verySimple(sig) ) { // shared and not simple : we need a vector // cerr << "ZEC : " << ppsig(sig) << endl; getTypedNames(getCertifiedSigType(sig), "Zec", ctype, vname); generateDelayLine(ctype, vname, d, exp); setVectorNameProperty(sig, vname); return subst("$0[i]", vname); } else { // not shared or simple : no cache needed return exp; } } } }