VectorCompiler Class Reference

Compile a list of FAUST signals into a vector C++ class. More...

#include <compile_vect.hh>

Inherits ScalarCompiler.

Collaboration diagram for VectorCompiler:
Collaboration graph
[legend]

List of all members.

Protected Member Functions

virtual string CS (Tree sig)
 Compile a signal.
virtual string generateCode (Tree sig)
 Compile a signal.
virtual string generateCacheCode (Tree sig, const string &exp)
 Generate cache code for a signal if needed.
virtual void generateDelayLine (const string &ctype, const string &vname, int mxd, const string &exp)
 Generate code for the delay mecchanism without using temporary variables.
virtual string generateFixDelay (Tree sig, Tree exp, Tree delay)
 Generate code for accessing a delayed signal.
virtual string generateDelayVec (Tree sig, const string &exp, const string &ctype, const string &vname, int mxd)
 Generate code for the delay mecchanism.
bool needSeparateLoop (Tree sig)
 Test if a signal need to be compiled in a separate loop.

Detailed Description

Compile a list of FAUST signals into a vector C++ class.

Definition at line 39 of file compile_vect.hh.


Member Function Documentation

string VectorCompiler::CS ( Tree  sig  )  [protected, virtual]

Compile a signal.

Parameters:
sig the signal expression to compile.
Returns:
the C code translation of sig as a string

Reimplemented from ScalarCompiler.

Definition at line 81 of file compile_vect.cpp.

References generateCode(), ScalarCompiler::getCompiledExpression(), and ScalarCompiler::setCompiledExpression().

Referenced by generateFixDelay().

00082 {
00083     int         i;
00084     Tree        x;
00085     string      code;
00086 
00087     if (!getCompiledExpression(sig, code)) {
00088         code = generateCode(sig);
00089         //cerr << "CS : " << code << " for " << ppsig(sig) << endl;
00090         setCompiledExpression(sig, code);
00091     } else {
00092         // check for recursive dependencies
00093         Loop*   ls;
00094         Loop*   tl = fClass->topLoop();
00095         if (isProj(sig, &i, x) && tl->findRecDefinition(x)) {
00096             tl->addRecDependency(x);
00097         } else if (fClass->getLoopProperty(sig,ls)) {
00098             //cerr << "in CS : fBackwardLoopDependencies.insert : " << tl << " --dependson--> " << ls << endl;
00099             tl->fBackwardLoopDependencies.insert(ls);
00100         } else {
00101            //cerr << "in CS :  no loop property for : " << ppsig(sig) << endl;
00102 
00103         }
00104     }
00105     return code;
00106 }

Here is the call graph for this function:

Here is the caller graph for this function:

string VectorCompiler::generateCacheCode ( Tree  sig,
const string &  exp 
) [protected, virtual]

Generate cache code for a signal if needed.

Parameters:
sig the signal expression.
exp the corresponding C code.
Returns:
the cached C code

Reimplemented from ScalarCompiler.

Definition at line 155 of file compile_vect.cpp.

References generateDelayLine(), OccMarkup::retrieve(), and ScalarCompiler::setVectorNameProperty().

00156 {
00157     string      vname, ctype;
00158     int         sharing = getSharingCount(sig);
00159     Type        t = getSigType(sig);
00160     Occurences* o = fOccMarkup.retrieve(sig);
00161     int         d = o->getMaxDelay();
00162 
00163     if (t->variability() < kSamp) {
00164         if (d==0) {
00165             // non-sample, not delayed : same as scalar cache
00166             return ScalarCompiler::generateCacheCode(sig,exp);
00167 
00168         } else {
00169             // it is a non-sample but used delayed
00170             // we need a delay line
00171             getTypedNames(getSigType(sig), "Xec", ctype, vname);
00172             generateDelayLine(ctype, vname, d, exp);
00173             setVectorNameProperty(sig, vname);
00174             if (verySimple(sig)) {
00175                 return exp;
00176             } else {
00177                 return subst("$0[i]", vname);
00178             }
00179         }
00180     } else {
00181         // sample-rate signal
00182         if (d > 0) {
00183             // used delayed : we need a delay line
00184             getTypedNames(getSigType(sig), "Yec", ctype, vname);
00185             generateDelayLine(ctype, vname, d, exp);
00186             setVectorNameProperty(sig, vname);
00187 
00188             if (verySimple(sig)) {
00189                 return exp;
00190             } else {
00191                 return subst("$0[i]", vname);
00192             }
00193         } else {
00194             // not delayed
00195             if ( sharing > 1 && ! verySimple(sig) ) {
00196                 // shared and not simple : we need a vector
00197                // cerr << "ZEC : " << ppsig(sig) << endl;
00198                 getTypedNames(getSigType(sig), "Zec", ctype, vname);
00199                 generateDelayLine(ctype, vname, d, exp);
00200                 setVectorNameProperty(sig, vname);
00201                 return subst("$0[i]", vname);
00202            } else {
00203                 // not shared or simple : no cache needed
00204                 return exp;
00205             }
00206         }
00207     }
00208 }

Here is the call graph for this function:

string VectorCompiler::generateCode ( Tree  sig  )  [protected, virtual]

Compile a signal.

Parameters:
sig the signal expression to compile.
Returns:
the C code translation of sig as a string

Reimplemented from ScalarCompiler.

Definition at line 113 of file compile_vect.cpp.

References needSeparateLoop().

Referenced by CS().

00114 {
00115     int     i;
00116     Tree    x;
00117     Loop*   l;
00118 
00119     l = fClass->topLoop();
00120     assert(l);
00121 
00122     if (needSeparateLoop(sig)) {
00123         // we need a separate loop unless it's an old recursion
00124         if (isProj(sig, &i, x)) {
00125             // projection of a recursive group x
00126             if (l->findRecDefinition(x)) {
00127                 // x is already in the loop stack
00128                 l->addRecDependency(x);
00129                 return ScalarCompiler::generateCode(sig);
00130             } else {
00131                 // x must be defined
00132                 fClass->openLoop(x, "count");
00133                 string c = ScalarCompiler::generateCode(sig);
00134                 fClass->closeLoop(sig);
00135                 return c;
00136             }
00137         } else {
00138             fClass->openLoop("count");
00139             string c = ScalarCompiler::generateCode(sig);
00140             fClass->closeLoop(sig);
00141             return c;
00142         }
00143     } else {
00144         return ScalarCompiler::generateCode(sig);
00145     }
00146 }

Here is the call graph for this function:

Here is the caller graph for this function:

string VectorCompiler::generateDelayVec ( Tree  sig,
const string &  exp,
const string &  ctype,
const string &  vname,
int  mxd 
) [protected, virtual]

Generate code for the delay mecchanism.

The generated code depend of the maximum delay attached to exp and the "less temporaries" switch

Reimplemented from ScalarCompiler.

Definition at line 342 of file compile_vect.cpp.

References generateDelayLine(), and ScalarCompiler::setVectorNameProperty().

00343 {
00344     // it is a non-sample but used delayed
00345     // we need a delay line
00346     generateDelayLine(ctype, vname, mxd, exp);
00347     setVectorNameProperty(sig, vname);
00348     if (verySimple(sig)) {
00349         return exp;
00350     } else {
00351         return subst("$0[i]", vname);
00352     }
00353 }

Here is the call graph for this function:

string VectorCompiler::generateFixDelay ( Tree  sig,
Tree  exp,
Tree  delay 
) [protected, virtual]

Generate code for accessing a delayed signal.

The generated code depend of the maximum delay attached to exp and the gLessTempSwitch.

Reimplemented from ScalarCompiler.

Definition at line 288 of file compile_vect.cpp.

References CS(), ScalarCompiler::getVectorNameProperty(), ScalarCompiler::pow2limit(), and OccMarkup::retrieve().

00289 {
00290     int     mxd, d; 
00291     string  vecname;
00292  
00293     //cerr << "VectorCompiler::generateFixDelay " << ppsig(sig) << endl;
00294 
00295     CS(exp); // ensure exp is compiled to have a vector name
00296 
00297     mxd = fOccMarkup.retrieve(exp)->getMaxDelay();
00298 
00299     if (! getVectorNameProperty(exp, vecname)) {
00300         cerr << "no vector name for " << ppsig(exp) << endl;
00301         exit(1);
00302     }
00303 
00304     if (mxd == 0) {
00305         // not a real vector name but a scalar name
00306         return subst("$0[i]", vecname);
00307 
00308     } else if (mxd < gMaxCopyDelay){
00309         if (isSigInt(delay, &d)) {
00310             if (d == 0) {
00311                 return subst("$0[i]", vecname);
00312             } else {
00313                 return subst("$0[i-$1]", vecname, T(d));
00314             }
00315         } else {
00316             return subst("$0[i-$1]", vecname, CS(delay));
00317         }
00318 
00319     } else {
00320 
00321         // long delay : we use a ring buffer of size 2^x
00322         int     N   = pow2limit( mxd+gVecSize );
00323 
00324         if (isSigInt(delay, &d)) {
00325             if (d == 0) {
00326                 return subst("$0[($0_idx+i)&$1]", vecname, T(N-1));
00327             } else {
00328                 return subst("$0[($0_idx+i-$2)&$1]", vecname, T(N-1), T(d));
00329             }
00330         } else {
00331             return subst("$0[($0_idx+i-$2)&$1]", vecname, T(N-1), CS(delay));
00332         }
00333     }
00334 }

Here is the call graph for this function:

bool VectorCompiler::needSeparateLoop ( Tree  sig  )  [protected]

Test if a signal need to be compiled in a separate loop.

Parameters:
sig the signal expression to test.
Returns:
true if a separate loop is needed

Definition at line 218 of file compile_vect.cpp.

References OccMarkup::retrieve().

Referenced by generateCode().

00219 {
00220     Occurences* o = fOccMarkup.retrieve(sig);
00221     Type        t = getSigType(sig);
00222     int         c = getSharingCount(sig);
00223     bool        b;
00224 
00225     int         i;
00226     Tree        x,y;
00227 
00228 
00229     if (o->getMaxDelay()>0) {
00230         //cerr << "DLY "; // delayed expressions require a separate loop
00231         b = true;
00232     } else if (verySimple(sig) || t->variability()<kSamp) {
00233         b = false;      // non sample computation never require a loop
00234     } else if (isSigFixDelay(sig, x, y)) {
00235         b = false;      // 
00236     } else if (isProj(sig, &i ,x)) {
00237         //cerr << "REC "; // recursive expressions require a separate loop
00238         b = true;
00239     } else if (c > 1) {
00240         //cerr << "SHA(" << c << ") "; // expressions used several times required a separate loop
00241         b = true;
00242     } else {
00243         // sample expressions that are not recursive, not delayed
00244         // and not shared, doesn't require a separate loop.
00245         b = false;
00246     }
00247 /*    if (b) {
00248         cerr << "Separate Loop for " << ppsig(sig) << endl;
00249     } else {
00250         cerr << "Same Loop for " << ppsig(sig) << endl;
00251     }*/
00252     return b;
00253 }

Here is the call graph for this function:

Here is the caller graph for this function:


The documentation for this class was generated from the following files:
Generated by  doxygen 1.6.2-20100208