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
00028 extern int gVecSize;
00029
00030 void VectorCompiler::compileMultiSignal (Tree L)
00031 {
00032
00033 L = prepare(L);
00034
00035 for (int i = 0; i < fClass->inputs(); i++) {
00036 fClass->addZone3(subst("$1* input$0 = &input[$0][index];", T(i), xfloat()));
00037 }
00038 for (int i = 0; i < fClass->outputs(); i++) {
00039 fClass->addZone3(subst("$1* output$0 = &output[$0][index];", T(i), xfloat()));
00040 }
00041
00042 fClass->addSharedDecl("fullcount");
00043 fClass->addSharedDecl("input");
00044 fClass->addSharedDecl("output");
00045
00046 for (int i = 0; isList(L); L = tl(L), i++) {
00047 Tree sig = hd(L);
00048 fClass->openLoop("count");
00049 fClass->addExecCode(subst("output$0[i] = $2$1;", T(i), CS(sig), xcast()));
00050 fClass->closeLoop();
00051 }
00052
00053 generateUserInterfaceTree(prepareUserInterfaceTree(fUIRoot));
00054 generateMacroInterfaceTree("", prepareUserInterfaceTree(fUIRoot));
00055 if (fDescription) {
00056 fDescription->ui(prepareUserInterfaceTree(fUIRoot));
00057 }
00058 }
00059
00060
00066 string VectorCompiler::CS (Tree sig)
00067 {
00068 int i;
00069 Tree x;
00070 string code;
00071
00072 if (!getCompiledExpression(sig, code)) {
00073 code = generateCode(sig);
00074
00075 setCompiledExpression(sig, code);
00076 } else {
00077
00078 Loop* ls;
00079 Loop* tl = fClass->topLoop();
00080 if (isProj(sig, &i, x) && tl->findRecDefinition(x)) {
00081 tl->addRecDependency(x);
00082
00083 } else if (fClass->getLoopProperty(sig,ls)) {
00084
00085 tl->fBackwardLoopDependencies.insert(ls);
00086 } else {
00087 Tree x,d;
00088 if (isSigFixDelay(sig, x, d)) {
00089 if (fClass->getLoopProperty(x,ls)) {
00090
00091 tl->fBackwardLoopDependencies.insert(ls);
00092 } else {
00093
00094
00095 }
00096 } else {
00097
00098 }
00099 }
00100 }
00101
00102 return code;
00103 }
00104
00110 string VectorCompiler::generateCode (Tree sig)
00111 {
00112 int i;
00113 Tree x;
00114 Loop* l;
00115
00116 l = fClass->topLoop();
00117 assert(l);
00118
00119 if (needSeparateLoop(sig)) {
00120
00121 if (isProj(sig, &i, x)) {
00122
00123 if (l->findRecDefinition(x)) {
00124
00125 l->addRecDependency(x);
00126 return ScalarCompiler::generateCode(sig);
00127 } else {
00128
00129 fClass->openLoop(x, "count");
00130 string c = ScalarCompiler::generateCode(sig);
00131 fClass->closeLoop(sig);
00132 return c;
00133 }
00134 } else {
00135 fClass->openLoop("count");
00136 string c = ScalarCompiler::generateCode(sig);
00137 fClass->closeLoop(sig);
00138 return c;
00139 }
00140 } else {
00141 return ScalarCompiler::generateCode(sig);
00142 }
00143 }
00144
00145
00152 string VectorCompiler::generateCacheCode(Tree sig, const string& exp)
00153 {
00154 string vname, ctype;
00155 int sharing = getSharingCount(sig);
00156 Type t = getSigType(sig);
00157 Occurences* o = fOccMarkup.retrieve(sig);
00158 int d = o->getMaxDelay();
00159
00160 if (t->variability() < kSamp) {
00161 if (d==0) {
00162
00163 return ScalarCompiler::generateCacheCode(sig,exp);
00164
00165 } else {
00166
00167
00168 getTypedNames(getSigType(sig), "Vec", ctype, vname);
00169 if ((sharing > 1) && !verySimple(sig)) {
00170
00171
00172 string cachedexp = generateVariableStore(sig, exp);
00173 generateDelayLine(ctype, vname, d, cachedexp);
00174 setVectorNameProperty(sig, vname);
00175 return cachedexp;
00176 } else {
00177
00178
00179 generateDelayLine(ctype, vname, d, exp);
00180 setVectorNameProperty(sig, vname);
00181 return exp;
00182 }
00183 }
00184 } else {
00185
00186 if (d > 0) {
00187
00188 getTypedNames(getSigType(sig), "Yec", ctype, vname);
00189 generateDelayLine(ctype, vname, d, exp);
00190 setVectorNameProperty(sig, vname);
00191
00192 if (verySimple(sig)) {
00193 return exp;
00194 } else {
00195 return subst("$0[i]", vname);
00196 }
00197 } else {
00198
00199 if ( sharing > 1 && ! verySimple(sig) ) {
00200
00201
00202 getTypedNames(getSigType(sig), "Zec", ctype, vname);
00203 generateDelayLine(ctype, vname, d, exp);
00204 setVectorNameProperty(sig, vname);
00205 return subst("$0[i]", vname);
00206 } else {
00207
00208 return exp;
00209 }
00210 }
00211 }
00212 }
00213
00219 bool VectorCompiler::needSeparateLoop(Tree sig)
00220 {
00221 Occurences* o = fOccMarkup.retrieve(sig);
00222 Type t = getSigType(sig);
00223 int c = getSharingCount(sig);
00224 bool b;
00225
00226 int i;
00227 Tree x,y;
00228
00229
00230 if (o->getMaxDelay()>0) {
00231
00232 b = true;
00233 } else if (verySimple(sig) || t->variability()<kSamp) {
00234 b = false;
00235 } else if (isSigFixDelay(sig, x, y)) {
00236 b = false;
00237 } else if (isProj(sig, &i ,x)) {
00238
00239 b = true;
00240 } else if (c > 1) {
00241
00242 b = true;
00243 } else {
00244
00245
00246 b = false;
00247 }
00248
00249
00250
00251
00252
00253 return b;
00254 }
00255
00256 void VectorCompiler::generateDelayLine(const string& ctype, const string& vname, int mxd, const string& exp)
00257 {
00258 if (mxd == 0) {
00259 vectorLoop(ctype, vname, exp);
00260 } else {
00261 dlineLoop(ctype, vname, mxd, exp);
00262 }
00263 }
00264
00265 string VectorCompiler::generateVariableStore(Tree sig, const string& exp)
00266 {
00267 Type t = getSigType(sig);
00268
00269 if (getSigType(sig)->variability() == kSamp) {
00270 string vname, ctype;
00271 getTypedNames(t, "Vector", ctype, vname);
00272 vectorLoop(ctype, vname, exp);
00273 return subst("$0[i]", vname);
00274 } else {
00275 return ScalarCompiler::generateVariableStore(sig, exp);
00276 }
00277 }
00278
00279
00285 string VectorCompiler::generateFixDelay (Tree sig, Tree exp, Tree delay)
00286 {
00287 int mxd, d;
00288 string vecname;
00289
00290
00291
00292 CS(exp);
00293
00294 mxd = fOccMarkup.retrieve(exp)->getMaxDelay();
00295
00296 if (! getVectorNameProperty(exp, vecname)) {
00297 cerr << "no vector name for " << ppsig(exp) << endl;
00298 exit(1);
00299 }
00300
00301 if (mxd == 0) {
00302
00303 return subst("$0[i]", vecname);
00304
00305 } else if (mxd < gMaxCopyDelay){
00306 if (isSigInt(delay, &d)) {
00307 if (d == 0) {
00308 return subst("$0[i]", vecname);
00309 } else {
00310 return subst("$0[i-$1]", vecname, T(d));
00311 }
00312 } else {
00313 return subst("$0[i-$1]", vecname, CS(delay));
00314 }
00315
00316 } else {
00317
00318
00319 int N = pow2limit( mxd+gVecSize );
00320
00321 if (isSigInt(delay, &d)) {
00322 if (d == 0) {
00323 return subst("$0[($0_idx+i)&$1]", vecname, T(N-1));
00324 } else {
00325 return subst("$0[($0_idx+i-$2)&$1]", vecname, T(N-1), T(d));
00326 }
00327 } else {
00328 return subst("$0[($0_idx+i-$2)&$1]", vecname, T(N-1), CS(delay));
00329 }
00330 }
00331 }
00332
00333
00339 string VectorCompiler::generateDelayVec(Tree sig, const string& exp, const string& ctype, const string& vname, int mxd)
00340 {
00341
00342
00343 generateDelayLine(ctype, vname, mxd, exp);
00344 setVectorNameProperty(sig, vname);
00345 if (verySimple(sig)) {
00346 return exp;
00347 } else {
00348 return subst("$0[i]", vname);
00349 }
00350 }
00351
00352 #if 0
00353 static int pow2limit(int x)
00354 {
00355 int n = 2;
00356 while (n < x) { n = 2*n; }
00357 return n;
00358 }
00359 #endif
00360
00370 void VectorCompiler::vectorLoop (const string& tname, const string& vecname, const string& cexp)
00371 {
00372
00373 fClass->addSharedDecl(vecname);
00374
00375
00376 fClass->addZone1(subst("$0 \t$1[$2];", tname, vecname, T(gVecSize)));
00377
00378
00379 fClass->addExecCode(subst("$0[i] = $1;", vecname, cexp));
00380 }
00381
00382
00392 void VectorCompiler::dlineLoop (const string& tname, const string& dlname, int delay, const string& cexp)
00393 {
00394 if (delay < gMaxCopyDelay) {
00395
00396
00397
00398
00399 string buf = subst("$0_tmp", dlname);
00400 string pmem= subst("$0_perm", dlname);
00401
00402
00403 delay = (delay+3)&-4;
00404
00405
00406 string dsize = T(delay);
00407 fClass->addDeclCode(subst("$0 \t$1[$2];", tname, pmem, dsize));
00408
00409
00410 fClass->addInitCode(subst("for (int i=0; i<$1; i++) $0[i]=0;", pmem, dsize));
00411
00412
00413
00414
00415 fClass->addSharedDecl(buf);
00416
00417
00418 fClass->addZone1(subst("$0 \t$1[$2+$3];", tname, buf, T(gVecSize), dsize));
00419
00420 fClass->addFirstPrivateDecl(dlname);
00421 fClass->addZone2(subst("$0* \t$1 = &$2[$3];", tname, dlname, buf, dsize));
00422
00423
00424 fClass->addPreCode(subst("for (int i=0; i<$2; i++) $0[i]=$1[i];", buf, pmem, dsize));
00425
00426
00427 fClass->addExecCode(subst("$0[i] = $1;", dlname, cexp));
00428
00429
00430 fClass->addPostCode(subst("for (int i=0; i<$2; i++) $0[i]=$1[count+i];", pmem, buf, dsize));
00431
00432 } else {
00433
00434
00435
00436
00437 delay = pow2limit(delay + gVecSize);
00438 string dsize = T(delay);
00439 string mask = T(delay-1);
00440
00441
00442 string idx = subst("$0_idx", dlname);
00443 string idx_save = subst("$0_idx_save", dlname);
00444
00445
00446 fClass->addDeclCode(subst("$0 \t$1[$2];", tname, dlname, dsize));
00447 fClass->addDeclCode(subst("int \t$0;", idx));
00448 fClass->addDeclCode(subst("int \t$0;", idx_save));
00449
00450
00451 fClass->addInitCode(subst("for (int i=0; i<$1; i++) $0[i]=0;", dlname, dsize));
00452 fClass->addInitCode(subst("$0 = 0;", idx));
00453 fClass->addInitCode(subst("$0 = 0;", idx_save));
00454
00455
00456 fClass->addPreCode(subst("$0 = ($0+$1)&$2;", idx, idx_save, mask));
00457
00458
00459 fClass->addExecCode(subst("$0[($2+i)&$3] = $1;", dlname, cexp, idx, mask));
00460
00461
00462 fClass->addPostCode(subst("$0 = count;", idx_save));
00463 }
00464 }
00465