Esempio n. 1
0
ControlFlowGraph::BlockPointerVector ControlFlowGraph::pre_order_sequence() {
	typedef std::unordered_set<iterator> BlockSet;
	typedef std::stack<iterator> Stack;
	
	BlockSet visited;
	BlockPointerVector sequence;
	Stack stack;
	
	if (!empty()) {
		stack.push(get_entry_block());
		visited.insert(get_entry_block());
	}
	
	while (!stack.empty()) {
		iterator current = stack.top();
		stack.pop();
		
		sequence.push_back(current);
		
		// favor the fallthrough
		iterator fallthrough = end();
		
		if (current->has_fallthrough_edge()) {
			edge_iterator fallthroughEdge 	
				= sequence.back()->get_fallthrough_edge();
			
			if (visited.insert(fallthroughEdge->tail).second) {
				fallthrough = fallthroughEdge->tail;
			}
		}
		
		for (pointer_iterator block = current->successors.begin(); 
			block != current->successors.end(); ++block) {
			if (visited.insert(*block).second) {
				stack.push(*block);
			}
		}
		
		if (fallthrough != end()) {
			stack.push(fallthrough);
		}
	}
	
	return sequence;
}
Esempio n. 2
0
ControlFlowGraph::BlockPointerVector ControlFlowGraph::executable_sequence() {
	typedef std::unordered_set<iterator> BlockSet;
	BlockPointerVector sequence;
	BlockSet unscheduled;

	for(iterator i = begin(); i != end(); ++i)
	{
		unscheduled.insert(i);
	}

	report("Getting executable sequence.");

	sequence.push_back(get_entry_block());
	unscheduled.erase(get_entry_block());
	report(" added " << get_entry_block()->label());

	while (!unscheduled.empty()) {
		if (sequence.back()->has_fallthrough_edge()) {
			edge_iterator fallthroughEdge 	
				= sequence.back()->get_fallthrough_edge();
			if (unscheduled.count(fallthroughEdge->tail) != 0) {
				sequence.push_back(fallthroughEdge->tail);
				unscheduled.erase(fallthroughEdge->tail);
			}
		}
		else {
			// find a new block, favor branch targets over random blocks
			iterator next = *unscheduled.begin();
			
			for(edge_pointer_iterator edge = sequence.back()->out_edges.begin();
				edge != sequence.back()->out_edges.end(); ++edge)
			{
				if(unscheduled.count((*edge)->tail) != 0)
				{
					next = (*edge)->tail;
				}
			}
			
			// rewind through fallthrough edges to find the beginning of the 
			// next chain of fall throughs
			report("  restarting at " << next->label());
			bool rewinding = true;
			while (rewinding) {
				rewinding = false;
				for (edge_pointer_iterator edge = next->in_edges.begin(); 
					edge != next->in_edges.end(); ++edge) {
					if ((*edge)->type == Edge::FallThrough) {
						assertM(unscheduled.count((*edge)->head) != 0, 
							(*edge)->head->label() 
							<< " has multiple fallthrough branches.");
						next = (*edge)->head;
						report("   rewinding to " << next->label() );
						rewinding = true;
						break;
					}
				}
			}
			sequence.push_back(next);
			unscheduled.erase(next);
		}
		
		report(" added " << sequence.back()->label());
	}

	return sequence;
}