replace broken ExpandedControlFlowGraph with hopefully somewhat less broken ExplodedControlFlowGraph
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@1499 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
2c4fd1fc93
commit
b9465e1bcc
|
@ -40,8 +40,8 @@ import com.ibm.wala.ipa.slicer.Statement.Kind;
|
|||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAInvokeInstruction;
|
||||
import com.ibm.wala.ssa.analysis.ExpandedControlFlowGraph;
|
||||
import com.ibm.wala.ssa.analysis.ExpandedControlFlowGraph.SingleInstructionBasicBlock;
|
||||
import com.ibm.wala.ssa.analysis.ExplodedControlFlowGraph;
|
||||
import com.ibm.wala.ssa.analysis.ExplodedControlFlowGraph.ExplodedBasicBlock;
|
||||
import com.ibm.wala.util.collections.Filter;
|
||||
import com.ibm.wala.util.collections.FilterIterator;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
|
@ -104,12 +104,11 @@ public class HeapReachingDefs {
|
|||
}
|
||||
System.err.println("Reaching Defs " + node);
|
||||
if (VERBOSE) {
|
||||
// System.err.println("Reaching Defs " + node);
|
||||
System.err.println(statements.size());
|
||||
}
|
||||
|
||||
// create a control flow graph with one instruction per basic block.
|
||||
ExpandedControlFlowGraph cfg = new ExpandedControlFlowGraph(ir);
|
||||
ExplodedControlFlowGraph cfg = ExplodedControlFlowGraph.make(ir);
|
||||
|
||||
// create a mapping between statements and integers, used in bit vectors
|
||||
// shortly
|
||||
|
@ -137,11 +136,11 @@ public class HeapReachingDefs {
|
|||
final Map<Statement, OrdinalSet<Statement>> delegate = HashMapFactory.make();
|
||||
|
||||
private final HeapExclusions exclusions;
|
||||
|
||||
|
||||
private final CallGraph cg;
|
||||
|
||||
RDMap(BitVectorSolver<IBasicBlock> solver, OrdinalSetMapping<Statement> domain, CGNode node, ExtendedHeapModel h,
|
||||
PointerAnalysis pa, Map<CGNode, OrdinalSet<PointerKey>> mod, ExpandedControlFlowGraph cfg,
|
||||
PointerAnalysis pa, Map<CGNode, OrdinalSet<PointerKey>> mod, ExplodedControlFlowGraph cfg,
|
||||
Map<Integer, NormalStatement> ssaInstructionIndex2Statement, HeapExclusions exclusions, CallGraph cg) {
|
||||
if (VERBOSE) {
|
||||
System.err.println("Init pointer Key mod ");
|
||||
|
@ -160,7 +159,7 @@ public class HeapReachingDefs {
|
|||
|
||||
private void eagerPopulate(Map<PointerKey, MutableIntSet> pointerKeyMod, BitVectorSolver<IBasicBlock> solver,
|
||||
OrdinalSetMapping<Statement> domain, CGNode node, ExtendedHeapModel h, PointerAnalysis pa,
|
||||
Map<CGNode, OrdinalSet<PointerKey>> mod, ExpandedControlFlowGraph cfg,
|
||||
Map<CGNode, OrdinalSet<PointerKey>> mod, ExplodedControlFlowGraph cfg,
|
||||
Map<Integer, NormalStatement> ssaInstruction2Statement) {
|
||||
for (Statement s : domain) {
|
||||
delegate.put(s, computeResult(s, pointerKeyMod, solver, domain, node, h, pa, mod, cfg, ssaInstruction2Statement));
|
||||
|
@ -169,11 +168,6 @@ public class HeapReachingDefs {
|
|||
|
||||
/**
|
||||
* For each pointerKey, which statements may def it
|
||||
*
|
||||
* @param domain
|
||||
* @param node
|
||||
* @param h
|
||||
* @param pa
|
||||
*/
|
||||
private Map<PointerKey, MutableIntSet> initPointerKeyMod(OrdinalSetMapping<Statement> domain, CGNode node, ExtendedHeapModel h,
|
||||
PointerAnalysis pa) {
|
||||
|
@ -285,7 +279,7 @@ public class HeapReachingDefs {
|
|||
*/
|
||||
private OrdinalSet<Statement> computeResult(Statement s, Map<PointerKey, MutableIntSet> pointerKeyMod,
|
||||
BitVectorSolver<IBasicBlock> solver, OrdinalSetMapping<Statement> domain, CGNode node, ExtendedHeapModel h,
|
||||
PointerAnalysis pa, Map<CGNode, OrdinalSet<PointerKey>> mod, ExpandedControlFlowGraph cfg,
|
||||
PointerAnalysis pa, Map<CGNode, OrdinalSet<PointerKey>> mod, ExplodedControlFlowGraph cfg,
|
||||
Map<Integer, NormalStatement> ssaInstructionIndex2Statement) {
|
||||
switch (s.getKind()) {
|
||||
case NORMAL:
|
||||
|
@ -367,7 +361,7 @@ public class HeapReachingDefs {
|
|||
*/
|
||||
private static Map<Statement, OrdinalSet<Statement>> makeResult(BitVectorSolver<IBasicBlock> solver,
|
||||
OrdinalSetMapping<Statement> domain, CGNode node, ExtendedHeapModel h, PointerAnalysis pa,
|
||||
Map<CGNode, OrdinalSet<PointerKey>> mod, ExpandedControlFlowGraph cfg,
|
||||
Map<CGNode, OrdinalSet<PointerKey>> mod, ExplodedControlFlowGraph cfg,
|
||||
Map<Integer, NormalStatement> ssaInstructionIndex2Statement, HeapExclusions exclusions, CallGraph cg) {
|
||||
|
||||
return new RDMap(solver, domain, node, h, pa, mod, cfg, ssaInstructionIndex2Statement, exclusions, cg);
|
||||
|
@ -447,7 +441,7 @@ public class HeapReachingDefs {
|
|||
|
||||
private final CGNode node;
|
||||
|
||||
private final ExpandedControlFlowGraph cfg;
|
||||
private final ExplodedControlFlowGraph cfg;
|
||||
|
||||
private final OrdinalSetMapping<Statement> domain;
|
||||
|
||||
|
@ -466,7 +460,7 @@ public class HeapReachingDefs {
|
|||
*/
|
||||
private final IBinaryNaturalRelation heapReturnCaller = new BasicNaturalRelation();
|
||||
|
||||
public RD(CGNode node, ExpandedControlFlowGraph cfg, PointerAnalysis pa, OrdinalSetMapping<Statement> domain,
|
||||
public RD(CGNode node, ExplodedControlFlowGraph cfg, PointerAnalysis pa, OrdinalSetMapping<Statement> domain,
|
||||
Map<Integer, NormalStatement> ssaInstructionIndex2Statement, HeapExclusions exclusions) {
|
||||
this.node = node;
|
||||
this.cfg = cfg;
|
||||
|
@ -491,7 +485,7 @@ public class HeapReachingDefs {
|
|||
}
|
||||
|
||||
public UnaryOperator getEdgeTransferFunction(IBasicBlock src, IBasicBlock dst) {
|
||||
SingleInstructionBasicBlock s = (SingleInstructionBasicBlock) src;
|
||||
ExplodedBasicBlock s = (ExplodedBasicBlock) src;
|
||||
if (s.getInstruction() != null && !(s.getInstruction() instanceof SSAInvokeInstruction)
|
||||
&& !cfg.getNormalSuccessors(src).contains(dst)) {
|
||||
// if the edge only happens due to exceptional control flow, then no
|
||||
|
@ -538,7 +532,7 @@ public class HeapReachingDefs {
|
|||
* @return int set representing the heap def statements that are gen'ed by
|
||||
* the basic block. null if none.
|
||||
*/
|
||||
IntSet gen(SingleInstructionBasicBlock b) {
|
||||
IntSet gen(ExplodedBasicBlock b) {
|
||||
if (b.isEntryBlock()) {
|
||||
return heapEntryStatements();
|
||||
} else {
|
||||
|
@ -588,7 +582,7 @@ public class HeapReachingDefs {
|
|||
* @return int set representing the heap def statements that are killed by
|
||||
* the basic block. null if none.
|
||||
*/
|
||||
BitVector kill(SingleInstructionBasicBlock b) {
|
||||
BitVector kill(ExplodedBasicBlock b) {
|
||||
SSAInstruction s = b.getInstruction();
|
||||
if (s == null) {
|
||||
return null;
|
||||
|
|
|
@ -28,8 +28,7 @@ import com.ibm.wala.util.collections.HashSetFactory;
|
|||
import com.ibm.wala.util.debug.Trace;
|
||||
|
||||
/**
|
||||
*
|
||||
* Eliminate dead assignnments (phis) from an SSA IR.
|
||||
* Eliminate dead assignments (phis) from an SSA IR.
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
|
@ -84,8 +83,6 @@ public class DeadAssignmentElimination {
|
|||
}
|
||||
|
||||
/**
|
||||
* @author sfink
|
||||
*
|
||||
* A dataflow system which computes whether or not a value is dead
|
||||
*/
|
||||
private static class DeadValueSystem extends DefaultFixedPointSolver {
|
||||
|
|
|
@ -1,144 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package com.ibm.wala.ssa.analysis;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.ssa.SSACFG;
|
||||
import com.ibm.wala.ssa.SSACFG.BasicBlock;
|
||||
import com.ibm.wala.ssa.analysis.ExpandedControlFlowGraph.SingleInstructionBasicBlock;
|
||||
|
||||
/**
|
||||
* @author Eran Yahav (yahave)
|
||||
*
|
||||
*/
|
||||
public class ExpandedCFGDotWriter {
|
||||
|
||||
public static void write(String fileName, ExpandedControlFlowGraph cfg) throws IllegalArgumentException {
|
||||
if (cfg == null) {
|
||||
throw new IllegalArgumentException("cfg cannot be null");
|
||||
}
|
||||
StringBuffer result = new StringBuffer();
|
||||
result.append(dotOutput(cfg));
|
||||
try {
|
||||
FileWriter fw = new FileWriter(fileName, false);
|
||||
fw.write(result.toString());
|
||||
fw.close();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error writing dot file");
|
||||
}
|
||||
}
|
||||
|
||||
public static void write(String fileName, SSACFG cfg) {
|
||||
if (cfg == null) {
|
||||
throw new IllegalArgumentException("cfg cannot be null");
|
||||
}
|
||||
StringBuffer result = new StringBuffer();
|
||||
result.append(dotOutput(cfg));
|
||||
try {
|
||||
FileWriter fw = new FileWriter(fileName, false);
|
||||
fw.write(result.toString());
|
||||
fw.close();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error writing dot file");
|
||||
}
|
||||
}
|
||||
|
||||
private static StringBuffer dotOutput(ExpandedControlFlowGraph cfg) {
|
||||
StringBuffer result = new StringBuffer("digraph \"ExpandedControlFlowGraph:\" {\n");
|
||||
result.append("center=true;fontsize=12;node [fontsize=12];edge [fontsize=12]; \n");
|
||||
|
||||
// create nodes for basic-blocks
|
||||
for (Iterator it = cfg.iterator(); it.hasNext();) {
|
||||
|
||||
SingleInstructionBasicBlock bb = (SingleInstructionBasicBlock) it.next();
|
||||
result.append(dotOutput(bb));
|
||||
if (bb.isEntryBlock()) {
|
||||
result.append(" [color=green]\n");
|
||||
} else if (bb.isExitBlock()) {
|
||||
result.append(" [color=red]\n");
|
||||
} else {
|
||||
result.append("\n");
|
||||
}
|
||||
|
||||
}
|
||||
// create edges
|
||||
for (Iterator it = cfg.iterator(); it.hasNext();) {
|
||||
SingleInstructionBasicBlock bb = (SingleInstructionBasicBlock) it.next();
|
||||
for (Iterator succIt = cfg.getSuccNodes(bb); succIt.hasNext();) {
|
||||
SingleInstructionBasicBlock succ = (SingleInstructionBasicBlock) succIt.next();
|
||||
result.append(dotOutput(bb));
|
||||
result.append(" -> ");
|
||||
result.append(dotOutput(succ));
|
||||
|
||||
result.append("\n");
|
||||
}
|
||||
}
|
||||
// close digraph
|
||||
result.append("}");
|
||||
return result;
|
||||
}
|
||||
|
||||
private static StringBuffer dotOutput(SSACFG cfg) {
|
||||
StringBuffer result = new StringBuffer("digraph \"ControlFlowGraph:\" {\n");
|
||||
result.append("center=true;fontsize=12;node [fontsize=12];edge [fontsize=12]; \n");
|
||||
|
||||
// create nodes for basic-blocks
|
||||
for (Iterator it = cfg.iterator(); it.hasNext();) {
|
||||
|
||||
BasicBlock bb = (BasicBlock) it.next();
|
||||
result.append(dotOutput(bb));
|
||||
if (bb.isEntryBlock()) {
|
||||
result.append(" [color=green]\n");
|
||||
} else if (bb.isExitBlock()) {
|
||||
result.append(" [color=red]\n");
|
||||
} else {
|
||||
result.append("\n");
|
||||
}
|
||||
|
||||
}
|
||||
// create edges
|
||||
for (Iterator it = cfg.iterator(); it.hasNext();) {
|
||||
BasicBlock bb = (BasicBlock) it.next();
|
||||
for (Iterator succIt = cfg.getSuccNodes(bb); succIt.hasNext();) {
|
||||
BasicBlock succ = (BasicBlock) succIt.next();
|
||||
result.append(dotOutput(bb));
|
||||
result.append(" -> ");
|
||||
result.append(dotOutput(succ));
|
||||
result.append("\n");
|
||||
}
|
||||
}
|
||||
// close digraph
|
||||
result.append("}");
|
||||
return result;
|
||||
}
|
||||
|
||||
private static StringBuffer dotOutput(BasicBlock bb) {
|
||||
StringBuffer result = new StringBuffer();
|
||||
result.append("\"");
|
||||
result.append(bb.getNumber());
|
||||
result.append("\"");
|
||||
return result;
|
||||
}
|
||||
|
||||
private static StringBuffer dotOutput(SingleInstructionBasicBlock bb) {
|
||||
StringBuffer result = new StringBuffer();
|
||||
result.append("\"");
|
||||
result.append(bb.getNumber());
|
||||
result.append("-");
|
||||
result.append(bb.getInstruction());
|
||||
result.append("\"");
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,418 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package com.ibm.wala.ssa.analysis;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||
import com.ibm.wala.cfg.IBasicBlock;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.shrikeBT.IInstruction;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.util.collections.EmptyIterator;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.collections.NonNullSingletonIterator;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.intset.BitVector;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
import com.ibm.wala.util.intset.SimpleVector;
|
||||
|
||||
/**
|
||||
* A view of a control flow graph where each basic block corresponds to exactly
|
||||
* one SSA instruction index.
|
||||
*
|
||||
* Prototype: Not terribly efficient.
|
||||
*/
|
||||
public class ExplodedControlFlowGraph implements ControlFlowGraph {
|
||||
|
||||
private final IR ir;
|
||||
|
||||
private final SimpleVector<IBasicBlock> normalNodes = new SimpleVector<IBasicBlock>();
|
||||
|
||||
private final Collection<IBasicBlock> allNodes = HashSetFactory.make();
|
||||
|
||||
private final ExplodedBasicBlock entry;
|
||||
|
||||
private final ExplodedBasicBlock exit;
|
||||
|
||||
private ExplodedControlFlowGraph(IR ir) {
|
||||
this.ir = ir;
|
||||
this.entry = new ExplodedBasicBlock(-2, ir.getControlFlowGraph().entry());
|
||||
this.exit = new ExplodedBasicBlock(-2, ir.getControlFlowGraph().exit());
|
||||
createNodes();
|
||||
}
|
||||
|
||||
private void createNodes() {
|
||||
allNodes.add(entry);
|
||||
allNodes.add(exit);
|
||||
for (IBasicBlock b : ir.getControlFlowGraph()) {
|
||||
for (int i = b.getFirstInstructionIndex(); i <= b.getLastInstructionIndex(); i++) {
|
||||
ExplodedBasicBlock bb = new ExplodedBasicBlock(i, b);
|
||||
normalNodes.set(i, bb);
|
||||
allNodes.add(bb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ExplodedControlFlowGraph make(IR ir) {
|
||||
return new ExplodedControlFlowGraph(ir);
|
||||
}
|
||||
|
||||
public IBasicBlock entry() {
|
||||
return entry;
|
||||
}
|
||||
|
||||
public IBasicBlock exit() {
|
||||
return exit;
|
||||
}
|
||||
|
||||
public IBasicBlock getBlockForInstruction(int index) {
|
||||
return normalNodes.get(index);
|
||||
}
|
||||
|
||||
public BitVector getCatchBlocks() {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection<IBasicBlock> getExceptionalPredecessors(IBasicBlock b) {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection<IBasicBlock> getExceptionalSuccessors(IBasicBlock b) {
|
||||
assert b != null;
|
||||
if (b.equals(exit)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
ExplodedBasicBlock eb = (ExplodedBasicBlock) b;
|
||||
if (eb.isEntryBlock() || eb.instructionIndex == eb.original.getLastInstructionIndex()) {
|
||||
List<IBasicBlock> result = new ArrayList<IBasicBlock>();
|
||||
for (IBasicBlock s : ir.getControlFlowGraph().getExceptionalSuccessors(eb.original)) {
|
||||
if (s.equals(ir.getControlFlowGraph().exit())) {
|
||||
result.add(exit());
|
||||
} else {
|
||||
assert normalNodes.get(s.getFirstInstructionIndex()) != null;
|
||||
result.add(normalNodes.get(s.getFirstInstructionIndex()));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
public IInstruction[] getInstructions() {
|
||||
return ir.getInstructions();
|
||||
}
|
||||
|
||||
public IMethod getMethod() {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection<IBasicBlock> getNormalPredecessors(IBasicBlock b) {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection<IBasicBlock> getNormalSuccessors(IBasicBlock b) {
|
||||
assert b != null;
|
||||
if (b.equals(exit)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
ExplodedBasicBlock eb = (ExplodedBasicBlock) b;
|
||||
if (eb.isEntryBlock() || eb.instructionIndex == eb.original.getLastInstructionIndex()) {
|
||||
List<IBasicBlock> result = new ArrayList<IBasicBlock>();
|
||||
for (IBasicBlock s : ir.getControlFlowGraph().getNormalSuccessors(eb.original)) {
|
||||
if (s.equals(ir.getControlFlowGraph().exit())) {
|
||||
result.add(exit());
|
||||
} else {
|
||||
assert normalNodes.get(s.getFirstInstructionIndex()) != null;
|
||||
result.add(normalNodes.get(s.getFirstInstructionIndex()));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
assert normalNodes.get(eb.instructionIndex + 1) != null;
|
||||
return Collections.singleton(normalNodes.get(eb.instructionIndex + 1));
|
||||
}
|
||||
}
|
||||
|
||||
public int getProgramCounter(int index) {
|
||||
Assertions.UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void removeNodeAndEdges(IBasicBlock N) throws UnsupportedOperationException {
|
||||
Assertions.UNREACHABLE();
|
||||
|
||||
}
|
||||
|
||||
public void addNode(IBasicBlock n) {
|
||||
Assertions.UNREACHABLE();
|
||||
|
||||
}
|
||||
|
||||
public boolean containsNode(IBasicBlock N) {
|
||||
Assertions.UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getNumberOfNodes() {
|
||||
return allNodes.size();
|
||||
}
|
||||
|
||||
public Iterator<IBasicBlock> iterator() {
|
||||
return allNodes.iterator();
|
||||
}
|
||||
|
||||
public void removeNode(IBasicBlock n) {
|
||||
Assertions.UNREACHABLE();
|
||||
|
||||
}
|
||||
|
||||
public void addEdge(IBasicBlock src, IBasicBlock dst) {
|
||||
Assertions.UNREACHABLE();
|
||||
|
||||
}
|
||||
|
||||
public int getPredNodeCount(IBasicBlock N) {
|
||||
ExplodedBasicBlock b = (ExplodedBasicBlock) N;
|
||||
if (b.isEntryBlock()) {
|
||||
return 0;
|
||||
}
|
||||
if (b.equals(exit) || b.instructionIndex == b.original.getFirstInstructionIndex()) {
|
||||
return ir.getControlFlowGraph().getPredNodeCount(b.original);
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public Iterator<? extends IBasicBlock> getPredNodes(IBasicBlock N) {
|
||||
ExplodedBasicBlock b = (ExplodedBasicBlock) N;
|
||||
if (b.isEntryBlock()) {
|
||||
return EmptyIterator.instance();
|
||||
}
|
||||
if (b.equals(exit) || b.instructionIndex == b.original.getFirstInstructionIndex()) {
|
||||
List<IBasicBlock> result = new ArrayList<IBasicBlock>();
|
||||
for (Iterator<IBasicBlock> it = ir.getControlFlowGraph().getPredNodes(b.original); it.hasNext();) {
|
||||
IBasicBlock s = it.next();
|
||||
if (s.isEntryBlock()) {
|
||||
result.add(entry);
|
||||
} else {
|
||||
assert normalNodes.get(s.getLastInstructionIndex()) != null;
|
||||
result.add(normalNodes.get(s.getLastInstructionIndex()));
|
||||
}
|
||||
}
|
||||
return result.iterator();
|
||||
} else {
|
||||
assert normalNodes.get(b.instructionIndex - 1) != null;
|
||||
return NonNullSingletonIterator.make(normalNodes.get(b.instructionIndex - 1));
|
||||
}
|
||||
}
|
||||
|
||||
public int getSuccNodeCount(IBasicBlock N) {
|
||||
Assertions.UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Iterator<? extends IBasicBlock> getSuccNodes(IBasicBlock N) {
|
||||
assert N != null;
|
||||
if (N.equals(exit)) {
|
||||
return EmptyIterator.instance();
|
||||
}
|
||||
ExplodedBasicBlock b = (ExplodedBasicBlock) N;
|
||||
if (b.isEntryBlock() || b.instructionIndex == b.original.getLastInstructionIndex()) {
|
||||
List<IBasicBlock> result = new ArrayList<IBasicBlock>();
|
||||
for (Iterator<IBasicBlock> it = ir.getControlFlowGraph().getSuccNodes(b.original); it.hasNext();) {
|
||||
IBasicBlock s = it.next();
|
||||
if (s.equals(ir.getControlFlowGraph().exit())) {
|
||||
result.add(exit());
|
||||
} else {
|
||||
assert normalNodes.get(s.getFirstInstructionIndex()) != null;
|
||||
result.add(normalNodes.get(s.getFirstInstructionIndex()));
|
||||
}
|
||||
}
|
||||
return result.iterator();
|
||||
} else {
|
||||
assert normalNodes.get(b.instructionIndex + 1) != null;
|
||||
return NonNullSingletonIterator.make(normalNodes.get(b.instructionIndex + 1));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasEdge(IBasicBlock src, IBasicBlock dst) {
|
||||
Assertions.UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
|
||||
public void removeAllIncidentEdges(IBasicBlock node) throws UnsupportedOperationException {
|
||||
Assertions.UNREACHABLE();
|
||||
|
||||
}
|
||||
|
||||
public void removeEdge(IBasicBlock src, IBasicBlock dst) throws UnsupportedOperationException {
|
||||
Assertions.UNREACHABLE();
|
||||
|
||||
}
|
||||
|
||||
public void removeIncomingEdges(IBasicBlock node) throws UnsupportedOperationException {
|
||||
Assertions.UNREACHABLE();
|
||||
|
||||
}
|
||||
|
||||
public void removeOutgoingEdges(IBasicBlock node) throws UnsupportedOperationException {
|
||||
Assertions.UNREACHABLE();
|
||||
|
||||
}
|
||||
|
||||
public int getMaxNumber() {
|
||||
Assertions.UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
public IBasicBlock getNode(int number) {
|
||||
if (number == 0) {
|
||||
return entry();
|
||||
} else if (number == getNumberOfNodes() -1) {
|
||||
return exit();
|
||||
} else {
|
||||
return normalNodes.get(number);
|
||||
}
|
||||
}
|
||||
|
||||
public int getNumber(IBasicBlock N) {
|
||||
Assertions.UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Iterator<IBasicBlock> iterateNodes(IntSet s) {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
public IntSet getPredNodeNumbers(IBasicBlock node) {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
public IntSet getSuccNodeNumbers(IBasicBlock node) {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
public class ExplodedBasicBlock implements IBasicBlock {
|
||||
|
||||
private final int instructionIndex;
|
||||
|
||||
private final IBasicBlock original;
|
||||
|
||||
public ExplodedBasicBlock(int instructionIndex, IBasicBlock original) {
|
||||
this.instructionIndex = instructionIndex;
|
||||
this.original = original;
|
||||
assert original != null;
|
||||
}
|
||||
|
||||
public int getFirstInstructionIndex() {
|
||||
return instructionIndex;
|
||||
}
|
||||
|
||||
public int getLastInstructionIndex() {
|
||||
return instructionIndex;
|
||||
}
|
||||
|
||||
public IMethod getMethod() {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getNumber() {
|
||||
if (isEntryBlock()) {
|
||||
return 0;
|
||||
} else if (isExitBlock()) {
|
||||
return getNumberOfNodes() -1;
|
||||
} else {
|
||||
return instructionIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCatchBlock() {
|
||||
Assertions.UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isEntryBlock() {
|
||||
return original.isEntryBlock();
|
||||
}
|
||||
|
||||
public boolean isExitBlock() {
|
||||
return original.isExitBlock();
|
||||
}
|
||||
|
||||
public int getGraphNodeId() {
|
||||
Assertions.UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setGraphNodeId(int number) {
|
||||
Assertions.UNREACHABLE();
|
||||
|
||||
}
|
||||
|
||||
public Iterator<IInstruction> iterator() {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + instructionIndex;
|
||||
result = prime * result + ((original == null) ? 0 : original.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final ExplodedBasicBlock other = (ExplodedBasicBlock) obj;
|
||||
if (instructionIndex != other.instructionIndex)
|
||||
return false;
|
||||
if (original == null) {
|
||||
if (other.original != null)
|
||||
return false;
|
||||
} else if (!original.equals(other.original))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public SSAInstruction getInstruction() {
|
||||
if (isEntryBlock() || isExitBlock()) {
|
||||
return null;
|
||||
} else {
|
||||
return ir.getInstructions()[instructionIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue