void dfs(ProcSet& visited, ProcSet& onPath, ProcSet& loopHeads, proc * p) { if(onPath.find(p) != onPath.end()){ loopHeads.insert(p); return; } if(visited.find(p) != visited.end()) return; onPath.insert(p); visited.insert(p); if(callees.find(p) == callees.end()) return; for(ProcSet::iterator pit = callees[p].begin(); pit != callees[p].end(); ++pit) dfs(visited, onPath, loopHeads, *pit); onPath.erase(p); return; }
void collectReachable(proc * p, ProcSet& reachable) { if(reachable.find(p) != reachable.end()) return; reachable.insert(p); for(ProcSet::iterator pit = callees[p].begin(); pit != callees[p].end(); ++pit) collectReachable(*pit, reachable); }
bool ProcDecompiler::decompileProcInRecursionGroup(UserProc *proc, ProcSet &visited) { bool changed = false; Project *project = proc->getProg()->getProject(); visited.insert(proc); m_callStack.push_back(proc); for (Function *c : proc->getCallees()) { if (c->isLib()) { continue; } UserProc *callee = static_cast<UserProc *>(c); if (visited.find(callee) != visited.end()) { continue; } else if (proc->getRecursionGroup()->find(callee) == proc->getRecursionGroup()->end()) { // not in recursion group any more continue; } // visit unvisited callees first changed |= decompileProcInRecursionGroup(callee, visited); } proc->setStatus(PROC_INCYCLE); // So the calls are treated as childless project->alertDecompiling(proc); earlyDecompile(proc); // The standard preservation analysis should automatically perform conditional preservation. middleDecompile(proc); proc->setStatus(PROC_PRESERVEDS); // Mark all the relevant calls as non childless (will harmlessly get done again later) // FIXME: why exactly do we do this? proc->markAsNonChildless(proc->getRecursionGroup()); // Need to propagate into the initial arguments, since arguments are uses, // and we are about to remove unused statements. changed |= PassManager::get()->executePass(PassID::LocalAndParamMap, proc); changed |= PassManager::get()->executePass(PassID::CallArgumentUpdate, proc); changed |= PassManager::get()->executePass(PassID::Dominators, proc); changed |= PassManager::get()->executePass(PassID::StatementPropagation, proc); // Need to propagate into arguments assert(m_callStack.back() == proc); m_callStack.pop_back(); return changed; }
/******************************************************************* * Function Name: receive * Description: sends an X message to the port's influences ********************************************************************/ ParallelCoordinator &ParallelMCoordinator::sortExternalMessage( const BasicExternalMessage &msg ) { //cout << "In function ParallelMCoordinator::receive(ExternalMessage)"<<endl << flush; ProcSet procs; //Remote procs that have already received the message const InfluenceList &influList( msg.port().influences() ) ; InfluenceList::const_iterator cursor( influList.begin() ) ; BasicExternalMessage xMsg( msg ) ; xMsg.procId( id() ) ; for( ; cursor != influList.end(); cursor++ ) { //If the destination model has a local master send message //to the local master, to the appropiate port //Otherwise, find the slave processor that has to received the message //and forward the message. Only one message per slave should be sent. if ((*cursor)->model().isLocalMaster()) { synchronizeList.insert( (*cursor)->model().localProc() ); xMsg.port( *(*cursor) ) ; send( xMsg,(*cursor)->model().localProc() ) ; } else { //When forwarding a message, do not translate the port const ProcId& slaveId = (*cursor)->model().parentId(); if (procs.find( slaveId ) == procs.end() ) { synchronizeList.insert( slaveId ); procs.insert(slaveId); xMsg.port( msg.port()); send( xMsg, slaveId ); } // if }//for }//else return *this ; }
/******************************************************************* * Function Name: receive * Description: translates the output event to a X messages for the * influenced children and to a Y message for his father ********************************************************************/ ParallelCoordinator &ParallelMCoordinator::sortOutputMessage( const BasicOutputMessage &msg ) { //cout << "In function ParallelMCoordinator::receive(OutputMessage)"<<endl << flush; Coupled &coupled( static_cast< Coupled & >( model() ) ); ProcSet procs; //Remote procs that have already received an external msg. const InfluenceList &influList( msg.port().influences() ); InfluenceList::const_iterator cursor( influList.begin() ); BasicOutputMessage outMsg( msg ); outMsg.procId( id() ); BasicExternalMessage extMsg; extMsg.time( msg.time() ); extMsg.procId( id() ); extMsg.value( msg.value()->clone() ); extMsg.senderModelId( msg.port().modelId() ); for( ; cursor != influList.end(); cursor++ ) { // Search for the port in the ouput ports list. // If found, send message to parent model. // If not found in the output ports list, then it must be an external message // If so, check if the recipient has a local master processor. // If the recipient does not have a local master processor, find the // corresponding slave processor and send the message. if( coupled.outputPorts().find( (*cursor)->id() ) == coupled.outputPorts().end() ) { if ( (*cursor)->model().isLocalMaster()) { synchronizeList.insert((*cursor)->model().localProc()); extMsg.port( * (*cursor) ); send( extMsg, (*cursor)->model().localProc()); } else { //When forwarding a message, do not translate the port //const ProcId& slaveId = parentSlaveForModel( (*cursor)->model() ); const ProcId& slaveId = (*cursor)->model().parentId(); //Two conditions must be satisfied for a message to be forwarded //to a slave processor: //1. The slave should not be the sender of the output message //2. The slave should not have already been sent the message if (slaveId != msg.procId() && procs.find( slaveId ) == procs.end() ) { synchronizeList.insert( slaveId ); procs.insert(slaveId); extMsg.port( msg.port()); send( extMsg, slaveId ); } // if } } else { outMsg.port( * (*cursor) ); send( outMsg, parentId ); } }//for return *this; }