private CFG cloneSelf(InlinerInfo ii) { CFG selfClone = new CFG(cfg.getScope()); // clone bbs BasicBlock entry = cfg.getEntryBB(); BasicBlock exit = cfg.getExitBB(); for (BasicBlock b : cfg.getBasicBlocks()) { if ((b != entry) && (b != exit)) { selfClone.addBasicBlock(b.cloneForInlinedMethod(ii)); } } // clone edges for (BasicBlock b: cfg.getBasicBlocks()) { if ((b != entry) && (b != exit)) { BasicBlock rb = ii.getRenamedBB(b); for (Edge<BasicBlock> e : cfg.getOutgoingEdges(b)) { BasicBlock destination = e.getDestination().getData(); if (destination != exit) selfClone.addEdge(rb, ii.getRenamedBB(destination), e.getType()); } } } return selfClone; }
public void addGlobalEnsureBB(BasicBlock geb) { assert globalEnsureBB == null: "CFG for scope " + getScope() + " already has a global ensure block."; addBasicBlock(geb); addEdge(geb, getExitBB(), EdgeType.EXIT); for (BasicBlock b: getBasicBlocks()) { if (b != geb && !bbIsProtected(b) && b != getEntryBB()) { addEdge(b, geb, EdgeType.EXCEPTION); setRescuerBB(b, geb); } } globalEnsureBB = geb; }
public void addGlobalEnsureBB(BasicBlock geb) { assert globalEnsureBB == null: "CFG for scope " + getScope() + " already has a global ensure block."; globalEnsureBB = geb; addEdge(geb, getExitBB(), EdgeType.EXIT); for (BasicBlock b: getBasicBlocks()) { if (b != geb && !bbIsProtected(b)) { addEdge(b, geb, EdgeType.EXCEPTION); setRescuerBB(b, geb); setEnsurerBB(b, geb); } } // We are not creating a global exception region and adding it to the list of // exc. regions because in graph form, we dont know what the "last BB" is. // That requires a linearized form of the CFG's bbs. So, the JIT can add // a special case for this global exception block since it has access to the // linearized form. }
IRScope hostScope = cfg.getScope(); if (hostScope.getNearestMethod() == scope) return; BasicBlock mEntry = methodCFG.getEntryBB(); BasicBlock mExit = methodCFG.getExitBB(); List<BasicBlock> methodBBs = new ArrayList<BasicBlock>(); for (BasicBlock b: methodCFG.getBasicBlocks()) methodBBs.add(b); for (BasicBlock b : selfClone.getBasicBlocks()) { cfg.addBasicBlock(b); for (Edge<BasicBlock> e : selfClone.getOutgoingEdges(b)) { cfg.addEdge(b, e.getDestination().getData(), e.getType()); for (BasicBlock b : methodCFG.getBasicBlocks()) { if (b != mEntry && b != mExit) { cfg.addBasicBlock(b.cloneForInlinedMethod(ii)); for (BasicBlock x : methodCFG.getBasicBlocks()) { if (x != mEntry && x != mExit) { BasicBlock rx = ii.getRenamedBB(x); for (Edge<BasicBlock> e : methodCFG.getOutgoingEdges(x)) { BasicBlock b = e.getDestination().getData(); if (b != mExit) cfg.addEdge(rx, ii.getRenamedBB(b), e.getType()); for (BasicBlock x: cfg.getBasicBlocks()) { for (Instr i: x.getInstrs()) { if (i == call) { System.out.println("----------------------------------");
List<BasicBlock> methodBBs = new ArrayList<>(methodToInline.getBasicBlocks()); for (BasicBlock b : selfClone.getBasicBlocks()) { cfg.addBasicBlock(b); for (Edge<BasicBlock> e : selfClone.getOutgoingEdges(b)) { cfg.addEdge(b, e.getDestination().getData(), e.getType()); for (BasicBlock b : methodToInline.getBasicBlocks()) { if (!b.isEntryBB() && !b.isExitBB()) cfg.addBasicBlock(b.cloneForInlining(ii)); for (BasicBlock x : methodToInline.getBasicBlocks()) { if (x.isEntryBB() || x.isExitBB()) continue; for (Edge<BasicBlock> e : methodToInline.getOutgoingEdges(x)) { BasicBlock b = e.getDestination().getData(); if (!b.isExitBB()) cfg.addEdge(rx, ii.getRenamedBB(b), e.getType()); assert methodToInline.outDegree(methodToInline.getEntryBB()) == 2: "Entry BB of inlinee method does not have outdegree 2: " + methodToInline.toStringGraph(); for (BasicBlock destination : methodToInline.getOutgoingDestinations(methodToInline.getEntryBB())) { if (destination.isExitBB()) continue; cfg.addEdge(beforeInlineBB, dstBB, CFG.EdgeType.FALL_THROUGH); for (Edge<BasicBlock> e : methodToInline.getIncomingEdges(methodToInline.getExitBB())) { BasicBlock source = e.getSource().getData(); if (source.isEntryBB()) continue; BasicBlock rescuerOfSplitBB = cfg.getRescuerBBFor(afterInlineBB); if (rescuerOfSplitBB != null) {
BasicBlock splitBB = yieldBB.splitAtInstruction(yield, cfg.getScope().getNewLabel(), false); cfg.addBasicBlock(splitBB); for (Edge<BasicBlock> e : cfg.getOutgoingEdges(yieldBB)) { cfg.addEdge(splitBB, e.getDestination().getData(), e.getType()); cfg.removeAllOutgoingEdgesForBB(yieldBB); BasicBlock cEntry = closureCFG.getEntryBB(); BasicBlock cExit = closureCFG.getExitBB(); for (BasicBlock b : closureCFG.getBasicBlocks()) { if (b != cEntry && b != cExit) { cfg.addBasicBlock(b.cloneForInlinedClosure(ii)); for (BasicBlock b : closureCFG.getBasicBlocks()) { if (b != cEntry && b != cExit) { BasicBlock bClone = ii.getRenamedBB(b); for (Edge<BasicBlock> e : closureCFG.getOutgoingEdges(b)) { BasicBlock edst = e.getDestination().getData(); if (edst != cExit) cfg.addEdge(bClone, ii.getRenamedBB(edst), e.getType()); for (Edge<BasicBlock> e : closureCFG.getOutgoingEdges(cEntry)) { BasicBlock destination = e.getDestination().getData(); if (destination != cExit) { cfg.addEdge(yieldBB, ii.getRenamedBB(destination), CFG.EdgeType.FALL_THROUGH); for (Edge<BasicBlock> e : closureCFG.getIncomingEdges(cExit)) { BasicBlock source = e.getSource().getData(); if (source != cEntry) {
CFG newCFG = new CFG(clonedScope); Map<BasicBlock, BasicBlock> cloneBBMap = new HashMap<>(); for (BasicBlock bb: getBasicBlocks()) { // clone bbs BasicBlock newBB = bb.clone(info, newCFG); newCFG.addBasicBlock(newBB); cloneBBMap.put(bb, newBB); for (BasicBlock bb: getBasicBlocks()) { BasicBlock newSource = cloneBBMap.get(bb); for (Edge<BasicBlock> edge : getOutgoingEdges(bb)) { BasicBlock newDestination = cloneBBMap.get(edge.getDestination().getData()); newCFG.addEdge(newSource, newDestination, edge.getType()); newCFG.setRescuerBB(cloneBBMap.get(bb), cloneBBMap.get(rescuerMap.get(bb)));
BasicBlock closureGEB = closureCFG.getGlobalEnsureBB(); for (BasicBlock b : closureCFG.getBasicBlocks()) { if (!b.isEntryBB() && !b.isExitBB() && b != closureGEB) cfg.addBasicBlock(b.cloneForInlining(ii)); for (BasicBlock b : closureCFG.getBasicBlocks()) { if (b.isEntryBB() || b.isExitBB()) continue; for (Edge<BasicBlock> e : closureCFG.getOutgoingEdges(b)) { BasicBlock edst = e.getDestination().getData(); if (!edst.isExitBB() && edst != closureGEB) cfg.addEdge(bClone, ii.getRenamedBB(edst), e.getType()); for (Edge<BasicBlock> e : closureCFG.getOutgoingEdges(closureCFG.getEntryBB())) { BasicBlock destination = e.getDestination().getData(); if (!destination.isExitBB() && destination != closureGEB) { cfg.addEdge(beforeInlineBB, ii.getRenamedBB(destination), CFG.EdgeType.FALL_THROUGH); for (Edge<BasicBlock> e : closureCFG.getIncomingEdges(closureCFG.getExitBB())) { BasicBlock source = e.getSource().getData(); if (source.isEntryBB()) continue; BasicBlock rescuerOfSplitBB = cfg.getRescuerBBFor(afterInlineBB); if (rescuerOfSplitBB != null) { cfg.addEdge(clonedSource, rescuerOfSplitBB, EdgeType.EXCEPTION); } else { cfg.addEdge(clonedSource, cfg.getExitBB(), EdgeType.EXIT); cfg.addEdge(clonedSource, afterInlineBB, e.getType()); BasicBlock yieldBBrescuer = cfg.getRescuerBBFor(beforeInlineBB);
private BasicBlock createPrologueBlock(CFG cfg) { BasicBlock entryBB = cfg.getEntryBB(); BasicBlock oldStart = cfg.getOutgoingDestinationOfType(entryBB, CFG.EdgeType.FALL_THROUGH); BasicBlock prologueBB = new BasicBlock(cfg, cfg.getScope().getNewLabel()); cfg.removeEdge(entryBB, oldStart); cfg.addBasicBlock(prologueBB); cfg.addEdge(entryBB, prologueBB, CFG.EdgeType.FALL_THROUGH); cfg.addEdge(prologueBB, oldStart, CFG.EdgeType.FALL_THROUGH); // If there's already a GEB, make sure we have an edge to it and use it to rescue these instrs if (cfg.getGlobalEnsureBB() != null) { BasicBlock geb = cfg.getGlobalEnsureBB(); cfg.addEdge(prologueBB, geb, CFG.EdgeType.EXCEPTION); cfg.setRescuerBB(prologueBB, geb); } return prologueBB; }
private boolean mergeBBs(BasicBlock a, BasicBlock b) { BasicBlock aR = getRescuerBBFor(a); BasicBlock bR = getRescuerBBFor(b); removeEdge(a, b); for (Edge<BasicBlock> e : getOutgoingEdges(b)) { addEdge(a, e.getDestination().getData(), e.getType()); removeBB(b); setRescuerBB(a, bR); BasicBlock aE = getEnsurerBBFor(a); BasicBlock bE = getEnsurerBBFor(b); if ((aE == null) && (bE != null)) { setRescuerBB(a, bE); setEnsurerBB(a, bE);
private boolean mergeBBs(BasicBlock a, BasicBlock b) { BasicBlock aR = getRescuerBBFor(a); BasicBlock bR = getRescuerBBFor(b); removeEdge(a, b); for (Edge<BasicBlock> e : getOutgoingEdges(b)) { addEdge(a, e.getDestination().getData(), e.getType()); for (Edge<BasicBlock> e : getIncomingEdges(b)) { BasicBlock fixupBB = e.getSource().getData(); removeEdge(fixupBB, b); addEdge(fixupBB, a, e.getType()); removeBB(b); setRescuerBB(a, bR);
entryBB = createBB(nestedExceptionRegions); BasicBlock firstBB = createBB(nestedExceptionRegions); if (iop == Operation.LABEL) { Label l = ((LabelInstr) i).label; newBB = createBB(l, nestedExceptionRegions); newBB = createBB(nestedExceptionRegions); Set<Label> retAddrs = retAddrMap.get(((JumpIndirectInstr) i).getJumpTarget()); for (Label l : retAddrs) { addEdge(currBB, l, forwardRefs); if (tgt != null) addEdge(currBB, tgt, forwardRefs); } else if (iop != Operation.LABEL) { currBB.addInstr(i); addEdge(tgtBB, tgtLbl, forwardRefs); } else { Set<Label> addrs = retAddrMap.get(v); Operand closureArg = ((CallBase) i).getClosureArg(getScope().getManager().getNil()); if (closureArg instanceof WrappedIRClosure) { ((WrappedIRClosure) closureArg).getClosure().buildCFG(); setRescuerBB(b, firstRescueBB); graph.addEdge(b, firstRescueBB, EdgeType.EXCEPTION); if (ensureBlockBB != null) {
BasicBlock geb = cfg.getGlobalEnsureBB(); for (BasicBlock bb: cfg.getBasicBlocks()) { if (cfg.getRescuerBBFor(bb) == null) { scopeHasUnrescuedExceptions = true; break; BasicBlock entryBB = cfg.getEntryBB(); geb.addInstr(new ReceiveExceptionInstr(exc, false)); // No need to check type since it is not used before rethrowing geb.addInstr(new ThrowExceptionInstr(exc)); cfg.addGlobalEnsureBB(geb); BasicBlock exitBB = cfg.getExitBB(); for (BasicBlock bb: cfg.getBasicBlocks()) { ListIterator<Instr> instrs = bb.getInstrs().listIterator(); while (instrs.hasNext()) {
entryBB = createBB(nestedExceptionRegions); BasicBlock firstBB = createBB(nestedExceptionRegions); if (iop == Operation.LABEL) { Label l = ((LabelInstr) i).getLabel(); newBB = createBB(l, nestedExceptionRegions); newBB = createBB(nestedExceptionRegions); } else if (i instanceof MultiBranchInstr) { Label[] tgts = ((MultiBranchInstr) i).getJumpTargets(); for (Label l : tgts) addEdge(currBB, l, forwardRefs); } else if (i instanceof JumpInstr) { tgt = ((JumpInstr) i).getJumpTarget(); if (tgt != null) addEdge(currBB, tgt, forwardRefs); } else if (iop != Operation.LABEL) { currBB.addInstr(i); setRescuerBB(b, firstRescueBB); graph.addEdge(b, firstRescueBB, EdgeType.EXCEPTION); buildExitBasicBlock(nestedExceptionRegions, firstBB, returnBBs, exceptionBBs, nextBBIsFallThrough, currBB, entryBB); optimize(returnBBs); // remove useless cfg edges & orphaned bbs
private void connectOuterEdges(BasicBlock beforeInlineBB, BasicBlock afterInlineBB) { cfg.addBasicBlock(afterInlineBB); for (Edge<BasicBlock> e : cfg.getOutgoingEdges(beforeInlineBB)) { cfg.addEdge(afterInlineBB, e.getDestination().getData(), e.getType()); } cfg.removeAllOutgoingEdgesForBB(beforeInlineBB); }
Operand rv = ((ReturnInstr)first).getReturnValue(); if (rv instanceof Variable) { for (Edge<BasicBlock> e : getIncomingEdges(retBB)) { BasicBlock srcBB = e.getSource().getData(); List<Instr> srcInstrs = srcBB.getInstrs(); srcInstrs.set(n-1, new ReturnInstr(((CopyInstr)last).getSource())); toRemove.add(e); addEdge(srcBB, exitBB, EdgeType.EXIT); deleteOrphanedBlocks(graph); collapseStraightLineBBs();
BasicBlock entryBB = cfg.getEntryBB(); Variable savedViz = null, savedFrame = null; if (scope instanceof IRClosure) { BasicBlock geb = cfg.getGlobalEnsureBB(); boolean gebProcessed = false; if (geb == null) { geb.addInstr(new ReceiveJRubyExceptionInstr(exc)); // JRuby Implementation exception handling geb.addInstr(new ThrowExceptionInstr(exc)); cfg.addGlobalEnsureBB(geb); for (BasicBlock bb: cfg.getBasicBlocks()) { Instr i = null; ListIterator<Instr> instrs = bb.getInstrs().listIterator();
BasicBlock geb = cfg.getGlobalEnsureBB(); if (geb == null) { geb = new BasicBlock(cfg, new Label("_GLOBAL_ENSURE_BLOCK")); cfg.addGlobalEnsureBB(geb); } else {
private BasicBlock createBB(Stack<ExceptionRegion> nestedExceptionRegions) { return createBB(scope.getNewLabel(), nestedExceptionRegions); }