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);
}
Beispiel #2
0
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;
}
Beispiel #3
0
/*******************************************************************
* 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 ;
}
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;
}
Beispiel #5
0
/*******************************************************************
* 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;

}