/** * 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; }
/** Remove all the predicates which are not defined in the hyperblock. */ private BitVect removePredicates(PredicateBlock start) { BitVect predicates = new BitVect(); Stack<Node> wl = new Stack<Node>(); // Determine all the predicates defined outside this hyperblock. start.nextVisit(); start.setVisited(); wl.add(start); while (!wl.isEmpty()) { PredicateBlock block = (PredicateBlock) wl.pop(); block.pushOutEdges(wl); for (Instruction inst = block.getFirstInstruction(); inst != null; inst = inst.getNext()) { if (inst.isMarker()) { continue; } if (inst.isBranch()) { continue; } if (((TripsInstruction) inst).definesPredicate()) { predicates.set(inst.getDestRegister()); } } } // Remove the predicates. start.nextVisit(); start.setVisited(); wl.add(start); while (!wl.isEmpty()) { PredicateBlock block = (PredicateBlock) wl.pop(); block.pushOutEdges(wl); if (!block.isPredicated()) { continue; } int rp = block.getPredicate(); if (predicates.get(rp)) { continue; } block.removePredicates(); for (Instruction inst = block.getFirstInstruction(); inst != null; inst = inst.getNext()) { inst.removePredicates(); } } return predicates; }