예제 #1
0
void G_addEdge(G_node from, G_node to) {
  assert(from);  assert(to);
  assert(from->mygraph == to->mygraph);
  if (G_goesTo(from, to)) return;
  to->preds=G_NodeList(from, to->preds);
  from->succs=G_NodeList(to, from->succs);
}
예제 #2
0
/* generic creation of G_node */
G_node G_Node(G_graph g, void *info)
{G_node n = (G_node)checked_malloc(sizeof *n);
 G_nodeList p = G_NodeList(n, NULL);
 assert(g);
 n->mygraph=g;
 n->mykey=g->nodecount++;

 if (g->mylast==NULL)
   g->mynodes=g->mylast=p;
 else g->mylast = g->mylast->tail = p;

 n->succs=NULL;
 n->preds=NULL;
 n->info=info;
 return n;
}
예제 #3
0
G_graph FG_AssemFlowGraph(AS_instrList il) {
	UD_init();

	//(I) Iterate over the entire instruction list
	AS_instr instr = NULL;
	G_node prev = NULL;
	G_node curr = NULL;
	G_graph graph = G_Graph();
	G_nodeList jumpList = NULL;
	G_nodeList jumpListHead = NULL;
	for(; il!=NULL; il=il->tail){
		instr = il->head;
		if(instr!=NULL){
			//1) create a node (and put it into the graph), using the 
			//   instruction as the associated info.
			curr = G_Node(graph, instr);

			//2) special handling
			int type = IT_COMMON;
			Temp_tempList defs = NULL;
			Temp_tempList uses = NULL;
			switch(instr->kind) {
			case I_OPER:
				// Check if it's a JUMP instruction
				// We do this check here by looking if As_target is null, 
				// instead of inspecting the assembly op (j, beq, ...)
				if(instr->u.OPER.jumps!=NULL &&
					instr->u.OPER.jumps->labels!=NULL){
					type = IT_JUMP;
					// put this instruction into a separate list
					if(jumpList==NULL){
						jumpList = G_NodeList(curr, NULL);
						jumpListHead = jumpList;
					} else {
						jumpList->tail = G_NodeList(curr, NULL);
						jumpList = jumpList->tail;
					}
				}
				defs = instr->u.OPER.dst;
				uses = instr->u.OPER.src;
				break;
			case I_LABEL:
				//2.2) label should be also saved in the label-node list for (II)
				LT_enter(instr->u.LABEL.label, curr);
				break;
			case I_MOVE:
				//2.3) it's a move instruction
				type = IT_MOVE;
				defs = instr->u.MOVE.dst;
				uses = instr->u.MOVE.src;
				break;
			}
			
			//3) put information into table
			UD_enter(curr, UDInfo(uses, defs, type == IT_MOVE));

			//4) link with the previous node for falling through, if possible.
			//   Note that prev is NULL if the previous instruction is a JUMP.
			if(prev!=NULL){
				G_addEdge(prev, curr);
			}

			//5) set as previous node for next time of iteration
			prev = (type!=IT_JUMP)?curr:NULL;
		}
	}

	//(II) Iterate over the list that has all the JUMP instruction collected.
	Temp_labelList labels;
	for(; jumpListHead!=NULL; jumpListHead=jumpListHead->tail){
		curr = jumpListHead->head;
		labels = ((AS_instr)G_nodeInfo(curr))->u.OPER.jumps->labels;//no need to check its nullity again
		Temp_label label;
		G_node dest;
		// for each target it may jump to, add a corresponding edge in the graph
		for(;labels!=NULL;labels=labels->tail){
			label = labels->head;
			if(label!=NULL){
				// quickly retieve the target node using the label-node table
				dest = LT_lookup(label);
				// establish edge between this node and its jump target
				G_addEdge(curr, dest);
			}
		}
	}

	return graph;
}