/** * Remove unreachable code * * @param ir the IR to optimize */ private void removeUnreachableCode(IR ir) { boolean removedCode = false; BasicBlock entry = ir.cfg.entry(); ir.cfg.clearDFS(); entry.sortDFS(); for (BasicBlock node = entry; node != null; ) { // save it now before removeFromCFGAndCodeOrder nulls it out!!! BasicBlock nextNode = (BasicBlock) node.getNext(); if (!node.dfsVisited()) { for (BasicBlockEnumeration e = node.getOut(); e.hasMoreElements(); ) { BasicBlock target = e.next(); if (target != node && !target.isExit() && target.dfsVisited()) { SSA.purgeBlockFromPHIs(node, target); } } ir.cfg.removeFromCFGAndCodeOrder(node); removedCode = true; } node = nextNode; } if (removedCode) { ir.cfg.compactNodeNumbering(); ir.HIRInfo.dominatorTree = null; ir.HIRInfo.dominatorsAreComputed = false; } }
/** * Print the nodes that dominate each basic block * * @param ir the IR */ private void printResults(IR ir) { if (forward) { System.out.println( "Results of dominators computation for method " + ir.method.getName() + "\n"); System.out.println(" Here's the CFG:"); System.out.println(ir.cfg); System.out.println("\n\n Here's the Dominator Info:"); } else { System.out.println( "Results of Post-Dominators computation for method " + ir.method.getName() + "\n"); System.out.println(" Here's the CFG:"); System.out.println(ir.cfg); System.out.println("\n\n Here's the Post-Dominator Info:"); } for (Enumeration<BasicBlock> bbEnum = cfg.basicBlocks(); bbEnum.hasMoreElements(); ) { BasicBlock block = bbEnum.nextElement(); // We don't compute a result for the exit node for forward direction if (!forward || !block.isExit()) { System.out.println( "Dominators of " + block + ":" + LTDominatorInfo.getInfo(block).dominators(block, ir)); } } System.out.println("\n"); }
/** * The goal of this step is to perform a DFS numbering on the CFG, starting at the root. The exit * node is not included. */ private void step1() { // allocate the vertex array, one element for each basic block, starting // at 1 vertex = new BasicBlock[cfg.numberOfNodes() + 1]; DFSCounter = 0; if (DEBUG) { System.out.println("Initializing blocks:"); } // Initialize each block with an empty set of predecessors and // a 0 for a semidominator for (Enumeration<BasicBlock> bbEnum = cfg.basicBlocks(); bbEnum.hasMoreElements(); ) { BasicBlock block = bbEnum.nextElement(); // We don't compute a result for the exit node in the forward direction if (!forward || !block.isExit()) { block.scratchObject = new LTDominatorInfo(block); if (DEBUG) { printNextNodes(block); } } } DFS(); if (DEBUG) { System.out.println("DFSCounter: " + DFSCounter + ", CFG Nodes: " + cfg.numberOfNodes()); printDFSNumbers(); } }
/** Print the result of the DFS numbering performed in Step 1 */ private void printDFSNumbers() { for (Enumeration<BasicBlock> bbEnum = cfg.basicBlocks(); bbEnum.hasMoreElements(); ) { BasicBlock block = bbEnum.nextElement(); // We don't compute a result for the exit node for forward direction if (forward && block.isExit()) { continue; } LTDominatorInfo info = (LTDominatorInfo) block.scratchObject; System.out.println(" " + block + " " + info); } // Visit each node in reverse DFS order, except for the root, which // has number 1 for (int i = 1; i <= DFSCounter; i++) { System.out.println(" Vertex: " + i + " " + vertex[i]); } }
/** * The non-recursive depth-first numbering code called from Step 1. The recursive version was too * costly on the toba benchmark on Linux/IA32. * * @param block the basic block to process */ protected void DFS(BasicBlock block) { // push node on to the emulated activation stack push(block); recurse: while (!empty()) { block = peek(); if (DEBUG) { System.out.println(" Processing (peek)" + block); } if (block == null) { if (DEBUG) { System.out.println(" Popping"); } pop(); // return continue; } // The current Dominance Frontier and SSA code assumes the exit // node will not be part of the (regular) dominator solution. // To avoid this from happening we screen it out here for forward CFG // // However, it really shouldn't be in the CFG, if it isn't a node! if (forward && block == cfg.exit()) { if (DEBUG) { System.out.println(" Popping"); } pop(); // return continue; } BasicBlockEnumeration e; e = LTDominatorInfo.getInfo(block).getEnum(); if (e == null) { if (DEBUG) { System.out.println(" Initial processing of " + block); } DFSCounter++; LTDominatorInfo.getInfo(block).setSemiDominator(DFSCounter); vertex[DFSCounter] = block; e = getNextNodes(block); } else { if (DEBUG) { System.out.println(" Resuming processing of " + block); } } while (e.hasMoreElements()) { BasicBlock next = e.next(); if (DEBUG) { System.out.println(" Inspecting next node: " + next); } // We treat the exit node as not being in the CFG for forward direction if (forward && next.isExit()) { continue; // inner loop } if (getSemi(next) == 0) { LTDominatorInfo.getInfo(next).setParent(block); // simulate a recursive call // save the enumeration state for resumption later LTDominatorInfo.getInfo(block).setEnum(e); if (DEBUG) { System.out.println(" Pushing" + next); } push(next); continue recurse; } } // while more nexts // "Pop" from the emulated activiation stack if (DEBUG) { System.out.println(" Popping"); } pop(); } // while stack not empty loop }