public BasicBlock getOrCreateRenamedBB(BasicBlock bb) { BasicBlock renamedBB = getRenamedBB(bb); if (renamedBB == null) { renamedBB = new BasicBlock(hostCFG, getRenamedLabel(bb.getLabel())); if (bb.isRescueEntry()) renamedBB.markRescueEntryBB(); bbRenameMap.put(bb, renamedBB); } return renamedBB; }
public BasicBlock splitAtInstruction(Instr splitPoint, Label newLabel, boolean includeSplitPointInstr) { BasicBlock newBB = new BasicBlock(cfg, newLabel); int idx = 0; int numInstrs = instrs.size(); boolean found = false; for (Instr i: instrs) { if (i == splitPoint) found = true; // Move instructions from split point into the new bb if (found) { if (includeSplitPointInstr || i != splitPoint) newBB.addInstr(i); } else { idx++; } } // Remove all instructions from current bb that were moved over. for (int j = 0; j < numInstrs-idx; j++) { instrs.remove(idx); } return newBB; }
protected FlowGraphNode getFlowGraphNode(BasicBlock b) { return basicBlockToFlowGraph.get(b.getID()); }
@Override public boolean solutionChanged() { // At the beginning of the scope and rescue block entries, required loads can be discarded // since all these loads will be executed there. if (basicBlock.isEntryBB() || basicBlock.isRescueEntry()) reqdLoads.clear(); //System.out.println("\n For CFG " + getCFG() + " BB " + _bb.getID()); //System.out.println("\t--> IN reqd loads : " + java.util.Arrays.toString(_inReqdLoads.toArray())); //System.out.println("\t--> OUT reqd loads : " + java.util.Arrays.toString(_outReqdLoads.toArray())); return !outRequiredLoads.equals(reqdLoads); }
if (aR == bR || a.isEmpty() || b.isEmpty()) { Instr lastInstr = a.getLastInstr(); if (lastInstr instanceof JumpInstr) a.removeInstr(lastInstr); a.swallowBB(b); Instr fixupLastInstr = fixupBB.getLastInstr(); if (fixupLastInstr instanceof JumpTargetInstr) { ((JumpTargetInstr) fixupLastInstr).setJumpTarget(a.getLabel());
entryBB.insertInstr(insertIndex++, new SaveBindingVisibilityInstr(savedViz)); entryBB.insertInstr(insertIndex++, new PushBlockFrameInstr(savedFrame, scope.getName())); entryBB.insertInstr(insertIndex++, new PushBlockBindingInstr()); entryBB.insertInstr(insertIndex++, new UpdateBlockExecutionStateInstr(Self.SELF)); int arityValue = sig.arityValue(); if (arityValue == 0) { prologueBB.addInstr(PrepareNoBlockArgsInstr.INSTANCE); } else { if (sig.isFixed()) { if (arityValue == 1) { prologueBB.addInstr(PrepareSingleBlockArgInstr.INSTANCE); } else { prologueBB.addInstr(PrepareBlockArgsInstr.INSTANCE); prologueBB.addInstr(PrepareBlockArgsInstr.INSTANCE); if (requireFrame) { if (scope.needsOnlyBackref()) { entryBB.addInstr(new PushBackrefFrameInstr()); } else { entryBB.addInstr(new PushMethodFrameInstr( scope.getName(), scope.isScriptScope() ? Visibility.PRIVATE : Visibility.PUBLIC)); if (requireBinding) entryBB.addInstr(new PushMethodBindingInstr());
current.addInstr(new ReturnInstr(cfg.getScope().getManager().getNil())); continue; Instr lastInstr = current.getLastInstr(); if (lastInstr instanceof JumpInstr) { // if jumping to next BB then remove it tryAndRemoveUnneededJump(list.get(i + 1), cfg, lastInstr, current); Instr lastInstr = current.getLastInstr(); current.addInstr(new JumpInstr(target.getLabel()));
if (scope.bindingHasEscaped() || scope.usesBackrefOrLastline() || scopeHasLocalVarStores || scopeHasUnrescuedExceptions) { entryBB.addInstr(new PushFrameInstr()); entryBB.addInstr(new PushBindingInstr(scope)); geb = new BasicBlock(cfg, new Label("_GLOBAL_ENSURE_BLOCK")); 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); ListIterator<Instr> instrs = bb.getInstrs().listIterator(); while (instrs.hasNext()) { Instr i = instrs.next(); if ((bb == exitBB) && !bb.isEmpty()) {
BasicBlock current = list[i]; if (current.isExitBB()) { // exit not last current.addInstr(new ReturnInstr(cfg.getManager().getNil())); continue; Instr lastInstr = current.getLastInstr(); if (lastInstr instanceof JumpInstr) { // if jumping to next BB then remove it tryAndRemoveUnneededJump(list[i + 1], cfg, lastInstr, current); if (!current.isExitBB()) { Instr lastInstr = current.getLastInstr(); current.addInstr(new JumpInstr(target.getLabel()));
public BasicBlock cloneForInlining(InlineCloneInfo ii) { BasicBlock clonedBB = ii.getOrCreateRenamedBB(this); for (Instr i: getInstrs()) { Instr clonedInstr = i.clone(ii); if (clonedInstr != null) { clonedBB.addInstr(clonedInstr); if (clonedInstr instanceof YieldInstr) { ii.recordYieldSite(clonedBB, (YieldInstr)clonedInstr); } else if (i instanceof NonlocalReturnInstr && clonedInstr instanceof CopyInstr) { // non-local returns assign to method return variable but must jump to proper exit point clonedBB.addInstr(new JumpInstr(ii.getHostScope().getCFG().getExitBB().getLabel())); // FIXME: enebo...I see no guarantee that this copy will be part of a return? This behavior is // masked in any case I can see with optimization to not use a copy but convert non-local to local return. } } } return clonedBB; }
private static void addJumpIfNextNotDestination(CFG cfg, BasicBlock next, Instr lastInstr, BasicBlock current) { Iterator<BasicBlock> outs = cfg.getOutgoingDestinations(current).iterator(); BasicBlock target = outs.hasNext() ? outs.next() : null; if (target != null && !outs.hasNext()) { if ((target != next) && ((lastInstr == null) || !lastInstr.getOperation().transfersControl())) { current.addInstr(new JumpInstr(target.getLabel())); } } }
public BasicBlock cloneForInlinedClosure(InlinerInfo ii) { // Update cfg for this bb IRScope hostScope = ii.getInlineHostScope(); BasicBlock clonedBB = ii.getOrCreateRenamedBB(this); // Process instructions for (Instr i: getInstrs()) { Instr clonedInstr = i.cloneForInlinedClosure(ii); if (clonedInstr != null) { clonedBB.addInstr(clonedInstr); if (clonedInstr instanceof CallBase) { CallBase call = (CallBase)clonedInstr; Operand block = call.getClosureArg(null); if (block instanceof WrappedIRClosure) hostScope.addClosure(((WrappedIRClosure)block).getClosure()); } } } return clonedBB; }
} else if (iop.endsBasicBlock()) { bbEnded = true; currBB.addInstr(i); Label tgt = null; nextBBIsFallThrough = false; currBB.addInstr(i); BasicBlock firstRescueBB = bbMap.get(rescueLabel); firstRescueBB.markRescueEntryBB(); if (b.canRaiseExceptions()) { setRescuerBB(b, firstRescueBB); graph.addEdge(b, firstRescueBB, EdgeType.EXCEPTION);
@Override public void compute_MEET(Edge e, StoreLocalVarPlacementNode pred) { // Ignore rescue entries -- dirty vars are handled specially for these if (!pred.basicBlock.isRescueEntry()) inDirtyVars.addAll(pred.outDirtyVars); }
} else if (iop.endsBasicBlock()) { bbEnded = true; currBB.addInstr(i); Label tgt; nextBBIsFallThrough = false; currBB.addInstr(i); firstRescueBB.markRescueEntryBB();
private void printInlineSplitBBs(BasicBlock beforeBB, BasicBlock afterBB) { LOG.info("---------------------------------- SPLIT BB (start) --------"); LOG.info("Before:" + beforeBB.getLabel()); LOG.info(beforeBB.toStringInstrs()); LOG.info("After:" + afterBB.getLabel()); LOG.info(afterBB.toStringInstrs()); printInlineCFG(cfg, ""); LOG.info("---------------------------------- SPLIT BB (end) -----------"); }
private BasicBlock createBB(Label label, Stack<ExceptionRegion> nestedExceptionRegions) { BasicBlock basicBlock = new BasicBlock(this, label); addBasicBlock(basicBlock); if (!nestedExceptionRegions.empty()) nestedExceptionRegions.peek().addBB(basicBlock); return basicBlock; }
public void removeBB(BasicBlock b) { if (b == globalEnsureBB) globalEnsureBB = null; graph.removeVertexFor(b); bbMap.remove(b.getLabel()); rescuerMap.remove(b); }