/*** frequencyCountAndSize ***/ int frequencyCountAndSize(const TransactionTable &tt, const Occurences &tids, Frequencies *itemsFrequency, Array<item_t> *presentItems, Array<int> *workspace){ int dbSize = 0; Array<Transaction> *transactions = tt.trans; Array<weight_t> *weights = tt.weights; workspace->expandInit(tt.maxItem+1, 0); // freq_t *pItemsFrequency = itemsFrequency->pData(); itemsFrequency->expandInit(tt.maxItem+1, 0); const tid_t *tidsEnd = tids.pEnd(); for(const tid_t *tid = tids.pData(); tid < tidsEnd ;++tid){ weight_t weight = (*weights)[*tid]; const item_t *transEnd = (*transactions)[*tid].pEnd(); for(item_t *x = (*transactions)[*tid].pData(); x < transEnd; ++x){ ++dbSize; if( (*itemsFrequency)[*x] == 0) presentItems->pushBack(*x); (*itemsFrequency)[*x] += weight; //TODO Double the number of caches misses maybe keep this info in itemfrequency (*workspace)[*x] += 1; //pItemsFrequency[*x]+=weight; } } return dbSize; }
/*** frequencyCount ***/ int frequencyCount(const TransactionTable &tt, const Occurences &tids, Frequencies *itemsFrequency, Array<item_t> *presentItems){ int dbSize = 0; Array<Transaction> *transactions = tt.trans; Array<weight_t> *weights = tt.weights; // freq_t *pItemsFrequency = itemsFrequency->pData(); #ifndef NDEBUG for (int i = 0; i < tt.maxItem; i++){ assert((*itemsFrequency)[i] == 0); } #endif const tid_t *tidsEnd = tids.pEnd(); for(const tid_t *tid = tids.pData(); tid < tidsEnd ;++tid){ weight_t weight = (*weights)[*tid]; const item_t *transEnd = (*transactions)[*tid].pEnd(); for(item_t *x = (*transactions)[*tid].pData(); x < transEnd; ++x){ ++dbSize; if( (*itemsFrequency)[*x] == 0) presentItems->pushBack(*x); (*itemsFrequency)[*x] += weight; //pItemsFrequency[*x]+=weight; } } return dbSize; }
string DocCompiler::generateCacheCode(Tree sig, const string& exp) { // cerr << "!! entering generateCacheCode with sig=\"" << ppsig(sig) << "\"" << endl; string vname, ctype, code, vectorname; int sharing = getSharingCount(sig); Occurences* o = fOccMarkup.retrieve(sig); // check reentrance if(getCompiledExpression(sig, code)) { // cerr << "!! generateCacheCode called a true getCompiledExpression" << endl; return code; } // check for expression occuring in delays if(o->getMaxDelay() > 0) { if(getVectorNameProperty(sig, vectorname)) { return exp; } getTypedNames(getCertifiedSigType(sig), "r", ctype, vname); gDocNoticeFlagMap["recursigs"] = true; // cerr << "- r : generateCacheCode : vame=\"" << vname << "\", for sig=\"" << ppsig(sig) << "\"" << endl; if(sharing > 1) { // cerr << " generateCacheCode calls generateDelayVec(generateVariableStore) on vame=\"" << vname << "\"" << endl; return generateDelayVec(sig, generateVariableStore(sig, exp), ctype, vname, o->getMaxDelay()); } else { // cerr << " generateCacheCode calls generateDelayVec(exp) on vame=\"" << vname << "\"" << endl; return generateDelayVec(sig, exp, ctype, vname, o->getMaxDelay()); } } else if(sharing == 1 || getVectorNameProperty(sig, vectorname) || isVerySimpleFormula(sig)) { // cerr << "! generateCacheCode : sharing == 1 : return \"" << exp << "\"" << endl; return exp; } else if(sharing > 1) { // cerr << "! generateCacheCode : sharing > 1 : return \"" << exp << "\"" << endl; return generateVariableStore(sig, exp); } else { cerr << "Error in sharing count (" << sharing << ") for " << *sig << endl; exit(1); } return "Error in generateCacheCode"; }
string DocCompiler::generateFVar (Tree sig, const string& file, const string& exp) { string ctype, vname; Occurences* o = fOccMarkup.retrieve(sig); if (o->getMaxDelay()>0) { getTypedNames(getCertifiedSigType(sig), "r", ctype, vname); gGlobal->gDocNoticeFlagMap["recursigs"] = true; //cerr << "- r : generateFVar : \"" << vname << "\"" << endl; setVectorNameProperty(sig, vname); generateDelayVec(sig, exp, ctype, vname, o->getMaxDelay()); } return generateCacheCode(sig, exp); }
string DocCompiler::generateNumber (Tree sig, const string& exp) { string ctype, vname; Occurences* o = fOccMarkup.retrieve(sig); // check for number occuring in delays if (o->getMaxDelay()>0) { getTypedNames(getCertifiedSigType(sig), "r", ctype, vname); gGlobal->gDocNoticeFlagMap["recursigs"] = true; //cerr << "- r : generateNumber : \"" << vname << "\"" << endl; generateDelayVec(sig, exp, ctype, vname, o->getMaxDelay()); } return exp; }
string ScalarCompiler::generateNumber(Tree sig, const string& exp) { string ctype, vname; Occurences* o = fOccMarkup.retrieve(sig); // check for number occuring in delays if(o->getMaxDelay() > 0) { getTypedNames(getCertifiedSigType(sig), "Vec", ctype, vname); generateDelayVec(sig, exp, ctype, vname, o->getMaxDelay()); } return exp; }
string ScalarCompiler::generateFConst(Tree sig, const string& file, const string& exp) { string ctype, vname; Occurences* o = fOccMarkup.retrieve(sig); addIncludeFile(file); if(o->getMaxDelay() > 0) { getTypedNames(getCertifiedSigType(sig), "Vec", ctype, vname); generateDelayVec(sig, exp, ctype, vname, o->getMaxDelay()); } return exp; }
/*** BEG computeOccurencesSizes ***/ void computeOccurencesSizes(const TransactionTable &tt, const Occurences &tids, Array<int> *workspace){ Array<Transaction> *transactions = tt.trans; Array<weight_t> *weights = tt.weights; workspace->expandInit(tt.maxItem+1, 0); // freq_t *pItemsFrequency = itemsFrequency->pData(); const tid_t *tidsEnd = tids.pEnd(); for(const tid_t *tid = tids.pData(); tid < tidsEnd ;++tid){ weight_t weight = (*weights)[*tid]; const item_t *transEnd = (*transactions)[*tid].pEnd(); for(item_t *x = (*transactions)[*tid].pData(); x < transEnd; ++x){ (*workspace)[*x] += 1; } } }
string DocCompiler::generateFConst (Tree sig, const string& file, const string& exp) { string ctype, vname; Occurences* o = fOccMarkup.retrieve(sig); if (o->getMaxDelay()>0) { getTypedNames(getCertifiedSigType(sig), "r", ctype, vname); gGlobal->gDocNoticeFlagMap["recursigs"] = true; //cerr << "- r : generateFConst : \"" << vname << "\"" << endl; generateDelayVec(sig, exp, ctype, vname, o->getMaxDelay()); } if (exp == "fSamplingFreq") { //gGlobal->gDocNoticeFlagMap["fsamp"] = true; return "f_S"; } return "\\mathrm{"+exp+"}"; }
string ScalarCompiler::generateCacheCode(Tree sig, const string& exp) { string vname, ctype, code; int sharing = getSharingCount(sig); Occurences* o = fOccMarkup.retrieve(sig); // check reentrance if(getCompiledExpression(sig, code)) { return code; } // check for expression occuring in delays if(o->getMaxDelay() > 0) { getTypedNames(getCertifiedSigType(sig), "Vec", ctype, vname); if(sharing > 1) { return generateDelayVec(sig, generateVariableStore(sig, exp), ctype, vname, o->getMaxDelay()); } else { return generateDelayVec(sig, exp, ctype, vname, o->getMaxDelay()); } } else if(sharing == 1) { return exp; } else if(sharing > 1) { return generateVariableStore(sig, exp); } else { cerr << "Error in sharing count (" << sharing << ") for " << *sig << endl; exit(1); } return "Error in generateCacheCode"; }
// like generateCacheCode but we force caching like if sharing was always > 1 string ScalarCompiler::forceCacheCode(Tree sig, const string& exp) { string vname, ctype, code; Occurences* o = fOccMarkup.retrieve(sig); // check reentrance if(getCompiledExpression(sig, code)) { return code; } // check for expression occuring in delays if(o->getMaxDelay() > 0) { getTypedNames(getCertifiedSigType(sig), "Vec", ctype, vname); return generateDelayVec(sig, generateVariableStore(sig, exp), ctype, vname, o->getMaxDelay()); } else { return generateVariableStore(sig, exp); } }
/** * Test if a signal need to be compiled in a separate loop. * @param sig the signal expression to test. * @return true if a separate loop is needed */ bool VectorCompiler::needSeparateLoop(Tree sig) { Occurences* o = fOccMarkup.retrieve(sig); Type t = getCertifiedSigType(sig); int c = getSharingCount(sig); bool b; int i; Tree x,y; if (o->getMaxDelay()>0) { //cerr << "DLY "; // delayed expressions require a separate loop b = true; } else if (verySimple(sig) || t->variability()<kSamp) { b = false; // non sample computation never require a loop } else if (isSigFixDelay(sig, x, y)) { b = false; // } else if (isProj(sig, &i ,x)) { //cerr << "REC "; // recursive expressions require a separate loop b = true; } else if (c > 1) { //cerr << "SHA(" << c << ") "; // expressions used several times required a separate loop b = true; } else { // sample expressions that are not recursive, not delayed // and not shared, doesn't require a separate loop. b = false; } /* if (b) { cerr << "Separate Loop for " << ppsig(sig) << endl; } else { cerr << "Same Loop for " << ppsig(sig) << endl; }*/ return b; }
/** * 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; } } } }