package synthesijer.scheduler.opt; import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import synthesijer.scheduler.Op; import synthesijer.scheduler.Operand; import synthesijer.scheduler.SchedulerBoard; import synthesijer.scheduler.SchedulerInfo; import synthesijer.scheduler.SchedulerItem; import synthesijer.scheduler.SchedulerSlot; import synthesijer.scheduler.VariableOperand; public class ControlFlowGraph{ private ControlFlowGraphNode top; private ControlFlowGraphNode[] nodes; public ControlFlowGraph(SchedulerBoard board){ SchedulerSlot[] slots = board.getSlots(); if(!(slots.length > 0)) return; ArrayList<ControlFlowGraphNode> nodes = new ArrayList<>(); for(SchedulerSlot s: slots){ nodes.add(new ControlFlowGraphNode(s)); } this.nodes = nodes.toArray(new ControlFlowGraphNode[]{}); this.top = this.nodes[0]; buildAll(); } private void buildAll(){ for(ControlFlowGraphNode n: nodes){ build(n); } } private void build(ControlFlowGraphNode target){ for(ControlFlowGraphNode n : nodes){ for(int id : n.slot.getNextStep()){ if(target.slot.getStepId() == id){ target.pred.add(n); n.succ.add(target); } } } } public ControlFlowGraphBB[] getBasicBlocks(){ ArrayList<ControlFlowGraphBB> list = new ArrayList<>(); ControlFlowGraphBB bb = new ControlFlowGraphBB(); Hashtable<ControlFlowGraphNode,Boolean> table = new Hashtable<>(); list.add(bb); getBasicBlocks(list, table, top, bb); return list.toArray(new ControlFlowGraphBB[]{}); } public void getBasicBlocks(ArrayList<ControlFlowGraphBB> list, Hashtable<ControlFlowGraphNode, Boolean> table, ControlFlowGraphNode node, ControlFlowGraphBB bb){ if(table.containsKey(node)){ return; // already treated. } table.put(node, true); // make the node treated if(node.pred.size() == 1){ bb.nodes.add(node); if(node.succ.size() == 1){ getBasicBlocks(list, table, node.succ.get(0), bb); }else if(node.succ.size() > 1){ for(int i = 0; i < node.succ.size(); i++){ ControlFlowGraphBB bb0 = new ControlFlowGraphBB(); // new basic block list.add(bb0); getBasicBlocks(list, table, node.succ.get(i), bb0); } } }else{ // fork node ControlFlowGraphBB bb0 = (list.size() == 0) ? bb : new ControlFlowGraphBB(); list.add(bb0); bb0.nodes.add(node); if(node.succ.size() == 1){ getBasicBlocks(list, table, node.succ.get(0), bb0); }else if(node.succ.size() > 1){ for(int i = 0; i < node.succ.size(); i++){ ControlFlowGraphBB bb1 = new ControlFlowGraphBB(); // new basic block list.add(bb1); getBasicBlocks(list, table, node.succ.get(i), bb1); } } } } } class ControlFlowGraphNode{ final ArrayList<ControlFlowGraphNode> pred = new ArrayList<>(); final ArrayList<ControlFlowGraphNode> succ = new ArrayList<>(); final SchedulerSlot slot; public ControlFlowGraphNode(SchedulerSlot slot){ this.slot = slot; } } class ControlFlowGraphBB{ ArrayList<ControlFlowGraphNode> nodes = new ArrayList<>(); public ControlFlowGraphBB(){ } }