/** * Reverse if-convert a block. Return a new hyperblock starting with the reverse if-converted * block or null. */ private Hyperblock reverseIfConvertBlock(PredicateBlock block) { int rp = block.getPredicate(); boolean sense = block.isPredicatedOnTrue(); // Insert a label at the beginning of the block. TripsLabel lab = (TripsLabel) gen.createLabel(); gen.updateLabelIndex(lab); block.insertInstructionAtHead(lab); // Insert a branch to this block in its predecessors. for (int i = block.numInEdges() - 1; i > -1; i--) { PredicateBlock pred = (PredicateBlock) block.getInEdge(i); int rpPred = pred.getPredicate(); boolean sensePred = pred.isPredicatedOnTrue(); boolean needThunk = true; // Check if we need a thunk. if (!block.isPredicated()) { needThunk = false; } else if (pred.numOutEdges() == 1) { needThunk = false; } else if ((rp == rpPred) && (sense == sensePred)) { needThunk = false; } // Create a branch to the label and insert it. if (needThunk) { TripsBranch br = new TripsBranch(Opcodes.BRO, lab, 1, rp, sense); PredicateBlock thunk = new PredicateBlock(rp, sense); br.addTarget(lab, 0); thunk.appendInstruction(br); pred.addOutEdge(thunk); thunk.addInEdge(pred); } else { TripsBranch br = new TripsBranch(Opcodes.BRO, lab, 1, rpPred, sensePred); br.addTarget(lab, 0); pred.appendInstruction(br); } pred.deleteOutEdge(block); block.deleteInEdge(pred); } blocksReverseIfConvertedCount++; // Create the new hyperblock. BitVect predicates = removePredicates(block); Hyperblock hnew = new Hyperblock(block, predicates, regs); hnew.updateLastBlock(); return hnew; }
/** Reverse if-convert the given predicate block from the hyperblock. */ private void reverseIfConvert(Hyperblock hb, PredicateBlock start) { Stack<Node> wl = WorkArea.<Node>getStack("reverseIfConvert"); Stack<PredicateBlock> reverse = WorkArea.<PredicateBlock>getStack("reverseIfConvert"); Vector<PredicateBlock> blocks = new Vector<PredicateBlock>(); Vector<Hyperblock> hbs = new Vector<Hyperblock>(); // Find the blocks which need to be reverse if-converted. start.nextVisit(); start.setVisited(); wl.add(start); while (!wl.isEmpty()) { PredicateBlock block = (PredicateBlock) wl.pop(); block.pushOutEdges(wl); for (int i = 0; i < block.numInEdges(); i++) { PredicateBlock pred = (PredicateBlock) block.getInEdge(i); if (!pred.visited()) { blocks.add(block); break; } else if (blocks.contains(pred) && block.numInEdges() > 1) { blocks.add(block); break; } } } // Order the blocks to reverse if-convert based on their depth from the root. PredicateBlock head = hb.getFirstBlock(); Vector<PredicateBlock> wl2 = new Vector<PredicateBlock>(); head.nextVisit(); head.setVisited(); wl2.add(head); while (!wl2.isEmpty()) { int l = wl2.size(); for (int i = 0; i < l; i++) { PredicateBlock block = wl2.get(i); if (blocks.contains(block)) { blocks.remove(block); reverse.push(block); } } wl2 = hb.getNextPFGLevel(wl2); } // Remove the special "dummy" last block from the PFG. PredicateBlock last = hb.getLastBlock(); assert (last.numOutEdges() == 0 && !last.isPredicated()); if (last.getFirstInstruction() == null) { for (int i = last.numInEdges() - 1; i > -1; i--) { PredicateBlock pred = (PredicateBlock) last.getInEdge(i); pred.deleteOutEdge(last); last.deleteInEdge(pred); } reverse.remove(last); } // Reverse if-convert. while (!reverse.isEmpty()) { PredicateBlock block = reverse.pop(); Hyperblock hbn = reverseIfConvertBlock(block); hbs.add(hbn); workingSet.add(hbn); } // Update the PFG. hb.updateLastBlock(); hb.invalidateDomination(); // The dominators are now invalid. // Insert the new hyperblocks in the HFG. HashMap<Instruction, Hyperblock> entries = computeEntries(hb, hbs); hbs.add(hb); Hyperblock.computeHyperblockFlowGraph(hbs, entries); // Update the return block. Since 'hbs' is an ordered list, the // first element in the list is the hyperblock with the return // because this was the original tail of the PFG which was reverse // if-converted. if (hb == gen.getReturnBlock()) { gen.setReturnBlock(hbs.firstElement()); } WorkArea.<Node>returnStack(wl); WorkArea.<PredicateBlock>returnStack(reverse); }