/// <summary> /// Compute a pre order (ignoring back edges) of the CFG reachable from the entry node /// /// As a side effect, assigns each block its DF finishing number. /// </summary> public static FList /*<BasicBlocks>*/ Compute(ControlFlowGraph cfg) { // depth-first search bool[] markBit = new bool[cfg.BlockCount]; FList result = null; int DFTime = 0; // Use a stack to represent the state of the search. // Each stack element consists of a basic block and the // the index of the next successor of that block to process. Stack stack = new Stack(); CfgBlock[] blocks = cfg.Blocks(); CfgBlock start = cfg.Entry; // invariant: all blocks pushed on the stack are marked. markBit[start.Index] = true; stack.Push(new StackElem(start)); while (stack.Count > 0) { StackElem elem = (StackElem)stack.Peek(); CfgBlock b = elem.node; int nextChild = elem.nextChild; CfgBlock[] normalNodes = cfg.NormalSucc(b); CfgBlock[] exnNodes = cfg.ExcpSucc(b); int normalNodesCount = normalNodes.Length; int exnNodesCount = exnNodes.Length; // Is there another child to process? if (nextChild < normalNodesCount + exnNodesCount) { // Figure out the actual block. CfgBlock child; if (nextChild < normalNodesCount) { child = normalNodes[nextChild]; } else { child = exnNodes[nextChild - normalNodesCount]; } elem.nextChild = nextChild + 1; // push the child block on to the stack. if (!markBit[child.Index]) { markBit[child.Index] = true; stack.Push(new StackElem(child)); } } else { // After all children are processed, place the block // on the result. stack.Pop(); b.priority = ++DFTime; result = FList.Cons(b, result); } } return(result); }