bool Trace::traverse_recursive(Event* loophead, int depth, event_handler handler, int *len){ if( loophead == NULL){ cerr << "traverse_recursive() called with NULL loophead, depth = " << depth << endl; return false; } if(handler == NULL){ cerr << "traverse_recursive() called without event handler" << endl; return false; } Event *looptail, *event_iter; Loop* loopstack = loophead->getLoopStack(); loop_t *loop; vector<ValueSet *> *mems = NULL, *iters = NULL; int iter = 0, mem = 0, length; if(loopstack->getDepth() == 0){ looptail = tail; iter = 1; } else if( 0 <= depth && depth < loopstack->getDepth() ){ loop = loopstack->getLoopAt(depth); mems = loop->mem->getParamValues(); iters = loop->iter->getParamValues(); /* trace reader ensures that only the loop rlparam related to the current node is read */ assert(mems->size() == 1); assert(iters->size() == 1); if(typeid(*(mems->at(0))) == typeid(Histogram) || typeid(*(iters->at(0))) == typeid(Histogram)){ cerr << "traverse_recursive() doesn't support histogram trace: \n" << loophead->toString(); return false; } mem = dynamic_cast<ParamValue *>(mems->at(0) )->getCurrentValue(true); iter = dynamic_cast<ParamValue *>(iters->at(0) )->getCurrentValue(true); looptail = loophead; for(int i=1; i<mem; i++) looptail = looptail->next; if(len) *len = mem; } else { cerr << "invalid depth: loophead: \n" << loophead->toString() << " depth = " << depth << endl; return false; } bool done ; for(int i=0; i<iter; i++){ event_iter = loophead; done = false; while(!done){ if(event_iter == NULL){ cerr << "NULL event" << endl; exit(1); } if(event_iter == loophead && event_iter->getLoopStack()->getDepth() > depth+1){ if( !traverse_recursive(event_iter, depth+1, handler, &length) ){ return false; } for(int j=1; j<length; j++) event_iter = event_iter->next; if(event_iter == looptail) done = true; event_iter = event_iter->next; } if(done) break; if(event_iter != NULL && event_iter != loophead && event_iter->getLoopStack()->getDepth() > 0){ if( !traverse_recursive(event_iter, 0, handler, &length) ){ return false; } for(int j=1; j<length; j++) event_iter = event_iter->next; if(event_iter == looptail) done = true; event_iter = event_iter->next; } else if (event_iter != NULL){ if(event_iter == looptail) done = true; handler(event_iter, depth, i); event_iter = event_iter->next; } } } return true; }