/** * Remove critical edges. A critical edge is an edge from a block with more than one successor to * a block with more than one predecessor. Critical edges can hinder code motion and should be * removed. */ private void removeCriticalEdges() { LinkedList list = new LinkedList(); for (BasicBlock bb = firstBB; bb != null; bb = bb.getNext()) { if (bb.getOutEdgesNumber() > 1) { Iterator outEdges = bb.getOutEdges(); while (outEdges.hasNext()) { Edge outEdge = (Edge) outEdges.next(); BasicBlock succ = (BasicBlock) outEdge.getTarget(); if (succ.getInEdgesNumber() > 1 && !succ.isFirstBlockSubroutine() && !succ.isCatchBlock()) { list.addLast(outEdge); } } } } while (!list.isEmpty()) { Edge edge = (Edge) list.removeFirst(); BasicBlock source = (BasicBlock) edge.getSource(); BasicBlock target = (BasicBlock) edge.getTarget(); if (source.getOutEdgesNumber() > 1 && target.getInEdgesNumber() > 1) { // insert a new block in the CFG between source and target BasicBlock insert = new BasicBlock(graph); edge.getSource().changeEdgeTarget(edge, insert); insert.addDefaultNextBlock(target); // insert the new block before target in the trace target.insertBefore(insert); for (int i = 0; i < exceptionHandlers.length; ++i) { if (exceptionHandlers[i].contains(target)) { exceptionHandlers[i].addProtectedBlock(insert); insert.addExceptionNextBlock(target); } } } } }
/** * Find the blocks protected by each ExceptionHandler. Add "exception edges" in the control flow * graph. Add a basic block before the block which catch the exception. This last block store the * exception in a variable. * * <p>Modification 02/04/2002 : add an exception edge between the blocks before the first block * protected and the catch block. * * @param numBlocks an array containing the number of basic block for each instruction. * @param insts the instructions * @param bbs the basic blocks */ private void findExceptionBlocks(short[] numBlocks, Instruction[] insts, BasicBlock[] bbs) { // shows if we had ever add a block for the catch block boolean[] marqued = new boolean[bbs.length]; for (int i = 0; i < exceptionHandlers.length; ++i) { ExceptionHandler handle = exceptionHandlers[i]; int numBlock = numBlocks[handle.getHandle()]; BasicBlock catchBlock = bbs[numBlock]; if (!marqued[numBlock]) { // add a new block // if the first instruction is the saving of the // exception put this instruction in the // new block else this saving will be added during // the 3-adress code generation BasicBlock newBlock; Instruction first = insts[catchBlock.getStart()]; if (first instanceof LocalVarInstruction && ((LocalVarInstruction) first).isStore()) { int instructionLine = catchBlock.getStart(); newBlock = new BasicBlock(instructionLine, instructionLine, graph); // remove this instruction from the next block catchBlock.setStart(instructionLine + 1); } else { newBlock = new BasicBlock(graph); } newBlock.setCatchBlock(true); catchBlock.insertBefore(newBlock); newBlock.addDefaultNextBlock(catchBlock); bbs[numBlock] = newBlock; catchBlock = newBlock; marqued[numBlock] = true; } handle.setHandlerBlock(catchBlock); } for (int i = 0; i < exceptionHandlers.length; ++i) { ExceptionHandler handle = exceptionHandlers[i]; BasicBlock catchBlock = handle.getHandlerBlock(); int numInst = handle.getStart(); int instEnd = handle.getEnd(); int numBlock = -1; // MODIFICATION 02/04/2002 if (numInst <= instEnd) { BasicBlock first = bbs[numBlocks[numInst]]; if (catchBlock != first) { // this is possible ! Iterator preds = first.getPredecessors(); while (preds.hasNext()) { BasicBlock pred = (BasicBlock) preds.next(); pred.addExceptionNextBlock(catchBlock); } } } // END MODIFICATION 02/04/2002 numBlock = -1; for (; numInst <= instEnd; ++numInst) { if (numBlocks[numInst] != numBlock) { numBlock = numBlocks[numInst]; // add blocks in exception handler. BasicBlock bb = bbs[numBlock]; handle.addProtectedBlock(bb); // add exception edges bb.addExceptionNextBlock(catchBlock); // if it's a catch block add also the next block if (marqued[numBlock]) { BasicBlock next = bb.getNext(); handle.addProtectedBlock(next); next.addExceptionNextBlock(catchBlock); } } } } }