FAUST compiler  0.9.9.6b8
occurences.cpp
Go to the documentation of this file.
00001 #include <assert.h>
00002 #include <stdlib.h>
00003 #include "recursivness.hh"
00004 #include "occurences.hh"
00005 #include "sigtype.hh"
00006 #include "sigtyperules.hh"
00007 #include <iostream>
00008 
00009 using namespace std;
00010 
00014 static int xVariability (int v, int r)
00015 {
00016     //cerr << "xVariability (" << v << ", " <<  r << ")" << endl;
00017     //assert (v < 3);               // kKonst=0, kBlock=1, kSamp=2
00018     //assert(r==0 | v==2);
00019     if (r>1) r=1;
00020     return min(3, v + r);
00021 }
00022 
00023 //-------------------------------------------------
00024 //  Occurences methods
00025 //-------------------------------------------------
00026 
00027 Occurences::Occurences(int v, int r) : fXVariability(xVariability(v,r)) {
00028     for (int i=0; i<4; i++) fOccurences[i]=0;
00029     fMultiOcc = false;
00030     fMaxDelay = 0;
00031     fOutDelayOcc = false;
00032 }
00033 
00034 Occurences* Occurences::incOccurences(int v, int r, int d) {
00035     int ctxt = xVariability(v,r);
00036     //assert (ctxt >= fXVariability);
00037     fOccurences[ctxt] += 1;
00038     fMultiOcc = fMultiOcc | (ctxt > fXVariability) | (fOccurences[ctxt] > 1);
00039     if (d == 0) {
00040         //cerr << "Occurence outside a delay " << endl;
00041         fOutDelayOcc = true;
00042     }
00043     if (d > fMaxDelay) {
00044         //cerr << "Max delay : " << fMaxDelay << " <- " << d << endl;
00045         fMaxDelay = d;
00046     }
00047     return this;
00048 }
00049 
00050 bool Occurences::hasMultiOccurences()   const   { return fMultiOcc; }
00051 
00052 bool Occurences::hasOutDelayOccurences() const  { return fOutDelayOcc; }
00053 
00054 int Occurences::getMaxDelay() const
00055 {
00056     return fMaxDelay;
00057 }
00058 
00059 //--------------------------------------------------
00060 //  Mark and retrieve occurences of subtrees of root
00061 //--------------------------------------------------
00062 
00063 void OccMarkup::mark(Tree root)
00064 {
00065     fRootTree = root;
00066     fPropKey = tree(unique("OCCURENCES"));
00067 
00068     if (isList(root)) {
00069         while (isList(root)) {
00070             //incOcc(kSamp, 1, hd(root));
00071             incOcc(nil, kSamp, 0, 0, hd(root));
00072             root = tl(root);
00073         }
00074         //cerr << "END OF LIST IS " << *root << endl;
00075     } else {
00076         //incOcc(kSamp, 1, root);
00077         incOcc(nil, kSamp, 0, 0, root);
00078     }
00079 }
00080 
00081 Occurences* OccMarkup::retrieve(Tree t)
00082 {
00083     Occurences* p = getOcc(t);
00084     if (p == 0) {
00085         //cerr << "No Occurences info attached to : " << *t << endl;
00086         //exit(1);
00087     }
00088     return p;
00089 }
00090 
00091 //------------------------------------------------------------------------------
00092 // Increment the occurences of t within context v,r,d and proceed recursively
00093 //------------------------------------------------------------------------------
00094 
00095 void OccMarkup::incOcc(Tree env, int v, int r, int d, Tree t)
00096 {
00097     // Check if we have already visited this tree
00098     Occurences* occ = getOcc(t);
00099 
00100     if (occ==0) {
00101         // 1) We build initial occurence information
00102         Type    ty = getCertifiedSigType(t);
00103         int v0 = ty->variability();
00104         int r0 = getRecursivness(t);
00105 
00106         occ = new Occurences(v0,r0);
00107         setOcc(t, occ);
00108 
00109         // We mark the subtrees of t
00110         Tree c, x, y, z;
00111         if (isSigFixDelay(t,x,y)) {
00112             Type g2 = getCertifiedSigType(y);
00113             int d2 = checkDelayInterval(g2);
00114             assert(d2>=0);
00115             incOcc(env, v0, r0, d2, x);
00116             incOcc(env, v0, r0, 0, y);
00117         } else if (isSigPrefix(t,y,x)) {
00118             incOcc(env, v0, r0, 1, x);
00119             incOcc(env, v0, r0, 0, y);
00120         } else if (isSigSelect3(t,c,y,x,z)) {
00121             // make a special case for select3 implemented with real if
00122             // because the c expression will be used twice in the C++
00123             // translation
00124             incOcc(env, v0, r0, 0, c);
00125             incOcc(env, v0, r0, 0, c);
00126             incOcc(env, v0, r0, 0, x);
00127             incOcc(env, v0, r0, 0, y);
00128             incOcc(env, v0, r0, 0, z);
00129         } else {
00130             vector<Tree> br;
00131             int n = getSubSignals(t, br);
00132             if (n>0 && ! isSigGen(t)) {
00133                 for (int i=0; i<n; i++) incOcc(env, v0, r0, 0, br[i]);
00134             }
00135         }
00136     }
00137 
00138     occ->incOccurences(v,r,d);
00139 
00140 }
00141 
00142 
00143 
00144 Occurences* OccMarkup::getOcc(Tree t)
00145 {
00146     Tree p = t->getProperty(fPropKey);
00147     if (p) {
00148         return (Occurences*) tree2ptr(p);
00149     } else {
00150         return 0;
00151     }
00152 }
00153 
00154 
00155 void OccMarkup::setOcc(Tree t, Occurences* occ)
00156 {
00157     t->setProperty(fPropKey, tree(occ));
00158 }
00159 
00160 
00161 
00168 static int position (Tree env, Tree t, int p)
00169 {
00170     if (isNil(env)) return 0;   // was not in the environment
00171     if (hd(env) == t) return p;
00172     else return position (tl(env), t, p+1);
00173 }