public String toStringInstrs() { StringBuilder buf = new StringBuilder(toString()); Collection<Edge<BasicBlock>> outs = cfg.getOutgoingEdges(this); if (!outs.isEmpty()) { for (Edge<BasicBlock> edge : outs) { buf.append(" -" + edge.getType() + "->" + edge.getDestination().getID()); } } buf.append('\n'); for (Instr instr : getInstrs()) { buf.append('\t').append(instr).append('\n'); } return buf.toString(); } }
public String toStringInstrs() { StringBuilder buf = new StringBuilder(toString()); Collection<Edge<BasicBlock>> outs = cfg.getOutgoingEdges(this); if (!outs.isEmpty()) { for (Edge<BasicBlock> edge : outs) { buf.append(" -" + edge.getType() + "->" + edge.getDestination().getID()); } } buf.append('\n'); for (Instr instr : getInstrs()) { buf.append('\t').append(instr).append('\n'); } return buf.toString(); } }
public void collapseStraightLineBBs() { // Collect cfgs in a list first since the cfg/graph API returns an iterator // over live data. But, basic block merging modifies that live data. // // SSS FIXME: So, we need a cfg/graph API that returns an iterator over // frozen data rather than live data. List<BasicBlock> cfgBBs = new ArrayList<BasicBlock>(); for (BasicBlock b: getBasicBlocks()) cfgBBs.add(b); Set<BasicBlock> mergedBBs = new HashSet<BasicBlock>(); for (BasicBlock b: cfgBBs) { if (!mergedBBs.contains(b) && (outDegree(b) == 1)) { for (Edge<BasicBlock> e : getOutgoingEdges(b)) { BasicBlock outB = e.getDestination().getData(); if ((e.getType() != EdgeType.EXCEPTION) && (inDegree(outB) == 1) && (mergeBBs(b, outB) == true)) { mergedBBs.add(outB); } } } } }
public void collapseStraightLineBBs() { // Collect cfgs in a list first since the cfg/graph API returns an iterator // over live data. But, basic block merging modifies that live data. // // SSS FIXME: So, we need a cfg/graph API that returns an iterator over // frozen data rather than live data. List<BasicBlock> cfgBBs = new ArrayList<BasicBlock>(); for (BasicBlock b: getBasicBlocks()) cfgBBs.add(b); Set<BasicBlock> mergedBBs = new HashSet<BasicBlock>(); for (BasicBlock b: cfgBBs) { if (!mergedBBs.contains(b) && (outDegree(b) == 1)) { for (Edge<BasicBlock> e : getOutgoingEdges(b)) { BasicBlock outB = e.getDestination().getData(); if ((e.getType() != EdgeType.EXCEPTION) && (inDegree(outB) == 1) && (mergeBBs(b, outB) == true)) { mergedBBs.add(outB); } } } } }
for (Edge<BasicBlock> edge : getOutgoingEdges(bb)) { BasicBlock newDestination = cloneBBMap.get(edge.getDestination().getData()); newCFG.addEdge(newSource, newDestination, edge.getType());
public void collapseStraightLineBBs() { // Collect cfgs in a list first since the cfg/graph API returns an iterator // over live data. But, basic block merging modifies that live data. // // SSS FIXME: So, we need a cfg/graph API that returns an iterator over // frozen data rather than live data. List<BasicBlock> cfgBBs = new ArrayList<>(); for (BasicBlock b: getBasicBlocks()) cfgBBs.add(b); Set<BasicBlock> mergedBBs = new HashSet<>(); for (BasicBlock b: cfgBBs) { if (!mergedBBs.contains(b) && outDegree(b) == 1) { for (Edge<BasicBlock> e : getOutgoingEdges(b)) { BasicBlock outB = e.getDestination().getData(); // 1:1 BBs can just be one since there is only one place to go. An empty entering any BB can merge // since the empty one does nothing (Note: mergeBBs uses empty as destination impl-wise but outcome // is the same). if (e.getType() != EdgeType.EXCEPTION && (inDegree(outB) == 1 || b.isEmpty()) && mergeBBs(b, outB)) { mergedBBs.add(outB); } } } } }
public void collapseStraightLineBBs() { // Collect cfgs in a list first since the cfg/graph API returns an iterator // over live data. But, basic block merging modifies that live data. // // SSS FIXME: So, we need a cfg/graph API that returns an iterator over // frozen data rather than live data. List<BasicBlock> cfgBBs = new ArrayList<>(); for (BasicBlock b: getBasicBlocks()) cfgBBs.add(b); Set<BasicBlock> mergedBBs = new HashSet<>(); for (BasicBlock b: cfgBBs) { if (!mergedBBs.contains(b) && outDegree(b) == 1) { for (Edge<BasicBlock> e : getOutgoingEdges(b)) { BasicBlock outB = e.getDestination().getData(); // 1:1 BBs can just be one since there is only one place to go. An empty entering any BB can merge // since the empty one does nothing (Note: mergeBBs uses empty as destination impl-wise but outcome // is the same). if (e.getType() != EdgeType.EXCEPTION && (inDegree(outB) == 1 || b.isEmpty()) && mergeBBs(b, outB)) { mergedBBs.add(outB); } } } } }
for (Edge<BasicBlock> e : getOutgoingEdges(x)) { BasicBlock b = e.getDestination().getData(); clone.addEdge(rx, cloneBBMap.get(b), e.getType());
for (Edge<BasicBlock> e : getOutgoingEdges(x)) { BasicBlock b = e.getDestination().getData(); clone.addEdge(rx, cloneBBMap.get(b), e.getType());
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); }
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); }
public void computeDataFlowInfoBackward(List<U> workList, BitSet bbSet) { for (Edge<BasicBlock> e: getCFG().getOutgoingEdges(basicBlock)) { compute_MEET(e, problem.getFlowGraphNode(e.getDestination().getData())); } initSolution(); // Initialize computation // Apply transfer function (analysis-specific) based on new facts after computing MEET List<Instr> instrs = basicBlock.getInstrs(); ListIterator<Instr> it = instrs.listIterator(instrs.size()); while (it.hasPrevious()) { Instr i = it.previous(); // System.out.println("TF: Processing: " + i); applyTransferFunction(i); } // If the solution has changed, add "dsts" to the work list. // No duplicates please which is why we have bbset. if (solutionChanged()) { for (BasicBlock b: getCFG().getIncomingSources(basicBlock)) { processDestBB(workList, bbSet, b); } } finalizeSolution(); // Any post-computation cleanup }
public void computeDataFlowInfoBackward(List<U> workList, BitSet bbSet) { for (Edge<BasicBlock> e: getCFG().getOutgoingEdges(basicBlock)) { compute_MEET(e, problem.getFlowGraphNode(e.getDestination().getData())); } initSolution(); // Initialize computation // Apply transfer function (analysis-specific) based on new facts after computing MEET List<Instr> instrs = basicBlock.getInstrs(); ListIterator<Instr> it = instrs.listIterator(instrs.size()); while (it.hasPrevious()) { Instr i = it.previous(); // System.out.println("TF: Processing: " + i); applyTransferFunction(i); } // If the solution has changed, add "dsts" to the work list. // No duplicates please which is why we have bbset. if (solutionChanged()) { for (BasicBlock b: getCFG().getIncomingSources(basicBlock)) { processDestBB(workList, bbSet, b); } } finalizeSolution(); // Any post-computation cleanup }
private void addMissingJumps() { for (BasicBlock bb: cfg.getBasicBlocks()) { boolean fallThrough = false; Label jumpLabel = null; for (Edge<BasicBlock> edge : cfg.getOutgoingEdges(bb)) { if (edge.getType() == EdgeType.FALL_THROUGH) { // Assume next BB will be correct fallThrough = true; } else if (edge.getType() == EdgeType.REGULAR || edge.getType() == EdgeType.EXIT) { // Not sure if we can have regular and fallthrough but only add regular if no fallthrough if (fallThrough) continue; jumpLabel = edge.getDestination().getData().getLabel(); } } if (fallThrough) continue; // we know this will just go to next BB already so no missing jump. if (jumpLabel == null) continue; // last instr does not transfer control so nothing to add. Instr lastInstr = bb.getLastInstr(); if (lastInstr != null && !lastInstr.transfersControl()) { bb.addInstr(new JumpInstr(jumpLabel)); } } }
private void addMissingJumps() { for (BasicBlock bb: cfg.getBasicBlocks()) { boolean fallThrough = false; Label jumpLabel = null; for (Edge<BasicBlock> edge : cfg.getOutgoingEdges(bb)) { if (edge.getType() == EdgeType.FALL_THROUGH) { // Assume next BB will be correct fallThrough = true; } else if (edge.getType() == EdgeType.REGULAR || edge.getType() == EdgeType.EXIT) { // Not sure if we can have regular and fallthrough but only add regular if no fallthrough if (fallThrough) continue; jumpLabel = edge.getDestination().getData().getLabel(); } } if (fallThrough) continue; // we know this will just go to next BB already so no missing jump. if (jumpLabel == null) continue; // last instr does not transfer control so nothing to add. Instr lastInstr = bb.getLastInstr(); if (lastInstr != null && !lastInstr.transfersControl()) { bb.addInstr(new JumpInstr(jumpLabel)); } } }
private CFG cloneSelf(InlineCloneInfo ii) { CFG selfClone = new CFG(hostScope); // clone bbs for (BasicBlock b : cfg.getBasicBlocks()) { if (!b.isEntryBB() && !b.isExitBB()) selfClone.addBasicBlock(b.cloneForInlining(ii)); } // clone edges for (BasicBlock b: cfg.getBasicBlocks()) { if (b.isEntryBB() || b.isExitBB()) continue; BasicBlock rb = ii.getRenamedBB(b); for (Edge<BasicBlock> e : cfg.getOutgoingEdges(b)) { BasicBlock destination = e.getDestination().getData(); if (!destination.isExitBB()) selfClone.addEdge(rb, ii.getRenamedBB(destination), e.getType()); } } return selfClone; }
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; }
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; }
private CFG cloneSelf(InlineCloneInfo ii) { CFG selfClone = new CFG(hostScope); // clone bbs for (BasicBlock b : cfg.getBasicBlocks()) { if (!b.isEntryBB() && !b.isExitBB()) selfClone.addBasicBlock(b.cloneForInlining(ii)); } // clone edges for (BasicBlock b: cfg.getBasicBlocks()) { if (b.isEntryBB() || b.isExitBB()) continue; BasicBlock rb = ii.getRenamedBB(b); for (Edge<BasicBlock> e : cfg.getOutgoingEdges(b)) { BasicBlock destination = e.getDestination().getData(); if (!destination.isExitBB()) selfClone.addEdge(rb, ii.getRenamedBB(destination), e.getType()); } } return selfClone; }
for (Edge e: problem.getScope().cfg().getOutgoingEdges(basicBlock)) { BasicBlock b = (BasicBlock)e.getDestination().getData(); compute_MEET(e, b, problem.getFlowGraphNode(b));