FAUST compiler  0.9.9.6b8
loopDetector.cpp
Go to the documentation of this file.
00001 #include "loopDetector.hh"
00002 #include "ppbox.hh"
00003  
00004 void loopDetector::listPossibleCycles (vector<int>& v)
00005 {
00006     //cerr << "list possible cycles" << endl;
00007     Tree t = get(0);
00008     for (int i=1; i<=(fBuffersize/2); i++) {
00009         if (t == get(i)) { 
00010             //cout << "possible cycle at " << i << endl;
00011             v.push_back(i); 
00012         }
00013     }
00014 }
00015  
00016 bool loopDetector::detect (Tree t)
00017 {
00018     //cerr << "detect " << t << endl;
00019     fPhase++;
00020     fBuffer[fPhase%fBuffersize] = t;
00021     if ((fPhase%fCheckperiod) == 0) {
00022         // list possible cycles
00023         vector<int> vc;
00024         listPossibleCycles(vc);
00025     
00026         // check each possible cycle
00027         //for (int i = vc.size(); i > 0;) {
00028         for (unsigned int i = 0; i < vc.size(); i++) {
00029             //i--;
00030             if (isCycle(vc[i])) {
00031                 cerr    << "ERROR : the Faust compiler has detected an endless cycle of "
00032                         << vc[i]  
00033                         << " evaluations. Last evaluated expression : "
00034                         << fPhase << endl;
00035                 exit(1);
00036                 return true;
00037             }
00038         }       
00039     }
00040     return false;
00041 }
00042 
00043 
00044 bool loopDetector::isCycle(int period)
00045 {
00046     //cerr << "check cycle " << period << endl;
00047     int n = fBuffersize/period; // number of periods
00048     for (int i=0; i<period; i++) {
00049         Tree x = get(i);
00050         for (int p=1; p<n; p++) {
00051             if (x != get(i+p*period)) return false;
00052         }
00053     }
00054     return true;
00055 }