00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "compile_vect.hh"
00025 #include "floats.hh"
00026 #include "ppsig.hh"
00027 #include "delayline.hh"
00028
00029 extern int gVecSize;
00030 extern bool gSchedulerSwitch;
00031
00032 void VectorCompiler::compileMultiSignal (Tree L)
00033 {
00034
00035 L = prepare(L);
00036
00037 for (int i = 0; i < fClass->inputs(); i++) {
00038 if (gSchedulerSwitch) {
00039 fClass->addZone3(subst("$1* input$0 = &input[$0][fIndex];", T(i), xfloat()));
00040 } else {
00041 fClass->addZone3(subst("$1* input$0 = &input[$0][index];", T(i), xfloat()));
00042 }
00043 }
00044 for (int i = 0; i < fClass->outputs(); i++) {
00045 if (gSchedulerSwitch) {
00046 fClass->addZone3(subst("$1* output$0 = &output[$0][fIndex];", T(i), xfloat()));
00047 } else {
00048 fClass->addZone3(subst("$1* output$0 = &output[$0][index];", T(i), xfloat()));
00049 }
00050 }
00051
00052 fClass->addSharedDecl("fullcount");
00053 fClass->addSharedDecl("input");
00054 fClass->addSharedDecl("output");
00055
00056 for (int i = 0; isList(L); L = tl(L), i++) {
00057 Tree sig = hd(L);
00058 fClass->openLoop("count");
00059 fClass->addExecCode(subst("output$0[i] = $2$1;", T(i), CS(sig), xcast()));
00060 fClass->closeLoop();
00061 }
00062
00063 if (gSchedulerSwitch) {
00064
00065 fClass->buildTasksList();
00066 }
00067
00068 generateUserInterfaceTree(prepareUserInterfaceTree(fUIRoot));
00069 generateMacroInterfaceTree("", prepareUserInterfaceTree(fUIRoot));
00070 if (fDescription) {
00071 fDescription->ui(prepareUserInterfaceTree(fUIRoot));
00072 }
00073 }
00074
00075
00081 string VectorCompiler::CS (Tree sig)
00082 {
00083 int i;
00084 Tree x;
00085 string code;
00086
00087 if (!getCompiledExpression(sig, code)) {
00088 code = generateCode(sig);
00089
00090 setCompiledExpression(sig, code);
00091 } else {
00092
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
00099 tl->fBackwardLoopDependencies.insert(ls);
00100 } else {
00101
00102
00103 }
00104 }
00105 return code;
00106 }
00107
00113 string VectorCompiler::generateCode (Tree sig)
00114 {
00115 int i;
00116 Tree x;
00117 Loop* l;
00118
00119 l = fClass->topLoop();
00120 assert(l);
00121
00122 if (needSeparateLoop(sig)) {
00123
00124 if (isProj(sig, &i, x)) {
00125
00126 if (l->findRecDefinition(x)) {
00127
00128 l->addRecDependency(x);
00129 return ScalarCompiler::generateCode(sig);
00130 } else {
00131
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 }
00147
00148
00155 string VectorCompiler::generateCacheCode(Tree sig, const string& exp)
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
00166 return ScalarCompiler::generateCacheCode(sig,exp);
00167
00168 } else {
00169
00170
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
00182 if (d > 0) {
00183
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
00195 if ( sharing > 1 && ! verySimple(sig) ) {
00196
00197
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
00204 return exp;
00205 }
00206 }
00207 }
00208 }
00209
00210
00211
00212
00218 bool VectorCompiler::needSeparateLoop(Tree sig)
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
00231 b = true;
00232 } else if (verySimple(sig) || t->variability()<kSamp) {
00233 b = false;
00234 } else if (isSigFixDelay(sig, x, y)) {
00235 b = false;
00236 } else if (isProj(sig, &i ,x)) {
00237
00238 b = true;
00239 } else if (c > 1) {
00240
00241 b = true;
00242 } else {
00243
00244
00245 b = false;
00246 }
00247
00248
00249
00250
00251
00252 return b;
00253 }
00254
00255
00256
00257
00258 void VectorCompiler::generateDelayLine(const string& ctype, const string& vname, int mxd, const string& exp)
00259 {
00260 if (mxd == 0) {
00261 vectorLoop(fClass, ctype, vname, exp);
00262 } else {
00263 dlineLoop(fClass, ctype, vname, mxd, exp);
00264 }
00265 }
00266
00267
00268 string VectorCompiler::generateVariableStore(Tree sig, const string& exp)
00269 {
00270 Type t = getSigType(sig);
00271
00272 if (getSigType(sig)->variability() == kSamp) {
00273 string vname, ctype;
00274 getTypedNames(t, "Vector", ctype, vname);
00275 vectorLoop(fClass, ctype, vname, exp);
00276 return subst("$0[i]", vname);
00277 } else {
00278 return ScalarCompiler::generateVariableStore(sig, exp);
00279 }
00280 }
00281
00282
00288 string VectorCompiler::generateFixDelay (Tree sig, Tree exp, Tree delay)
00289 {
00290 int mxd, d;
00291 string vecname;
00292
00293
00294
00295 CS(exp);
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
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
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 }
00335
00336
00342 string VectorCompiler::generateDelayVec(Tree sig, const string& exp, const string& ctype, const string& vname, int mxd)
00343 {
00344
00345
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 }
00354
00355