use appendBlock instead of sequentialT1

clean ups and fixes for in/out analysis


git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1073 379699f6-c40d-0410-875b-85095c16579e
branch_1_1
jochen 26 years ago
parent d4b15f7b44
commit ba4e13803b
  1. 174
      jode/jode/flow/FlowBlock.java
  2. 4
      jode/jode/flow/TransformExceptionHandlers.java

@ -60,14 +60,16 @@ import jode.util.SimpleSet;
*/ */
public class FlowBlock { public class FlowBlock {
public static FlowBlock END_OF_METHOD = public static FlowBlock END_OF_METHOD;
new FlowBlock(null, Integer.MAX_VALUE, 0, new EmptyBlock()); public static FlowBlock NEXT_BY_ADDR;
public static FlowBlock NEXT_BY_ADDR =
new FlowBlock(null, -1, 0, new DescriptionBlock("FALL THROUGH"));
static { static {
END_OF_METHOD = new FlowBlock(null, Integer.MAX_VALUE);
END_OF_METHOD.appendBlock(new EmptyBlock(), 0);
END_OF_METHOD.label = "END_OF_METHOD"; END_OF_METHOD.label = "END_OF_METHOD";
NEXT_BY_ADDR = new FlowBlock(null, -1);
NEXT_BY_ADDR.appendBlock(new DescriptionBlock("FALL THROUGH"), 0);
NEXT_BY_ADDR.label = "NEXT_BY_ADDR"; NEXT_BY_ADDR.label = "NEXT_BY_ADDR";
} }
@ -182,33 +184,9 @@ public class FlowBlock {
/** /**
* The default constructor. Creates a new empty flowblock. * The default constructor. Creates a new empty flowblock.
*/ */
public FlowBlock(MethodAnalyzer method, int addr, int length) { public FlowBlock(MethodAnalyzer method, int addr) {
this.method = method;
this.addr = addr;
this.length = length;
}
/**
* The default constructor. Creates a new flowblock containing
* only the given structured block.
*/
public FlowBlock(MethodAnalyzer method, int addr, int length,
StructuredBlock block) {
this.method = method; this.method = method;
this.addr = addr; this.addr = addr;
this.length = length;
setBlock(block);
}
public void setBlock(StructuredBlock block) {
if (this.block != null)
throw new jode.AssertError("FlowBlock.setBlock called twice");
this.block = block;
lastModified = block;
block.setFlowBlock(this);
block.fillInGenSet(in, gen);
block.fillSuccessors();
checkConsistent();
} }
public final int getNextAddr() { public final int getNextAddr() {
@ -692,7 +670,7 @@ public class FlowBlock {
SuccessorInfo succSuccInfo = (SuccessorInfo) i.next(); SuccessorInfo succSuccInfo = (SuccessorInfo) i.next();
succSuccInfo.gen.mergeGenKill(gens, succSuccInfo.kill); succSuccInfo.gen.mergeGenKill(gens, succSuccInfo.kill);
if (successor != this) if (successor != this)
succSuccInfo.kill.addAll(kills); succSuccInfo.kill.mergeKill(kills);
} }
this.in.addAll(newIn); this.in.addAll(newIn);
this.gen.addAll(successor.gen); this.gen.addAll(successor.gen);
@ -829,47 +807,58 @@ public class FlowBlock {
} }
} }
public void appendBlock(StructuredBlock block, int length) {
/** SlotSet succIn = new SlotSet();
* This is a special T2 transformation, that does also succeed, if
* the jumps in the flow block are not yet resolved. But it has
* a special precondition: The succ must be a simple instruction block,
* mustn't have another predecessor and all structured blocks in this
* flow block must be simple instruction blocks.
* @param succ The successing structured block that should be merged.
* @param length the length of the structured block.
*/
public void doSequentialT2(StructuredBlock succ, int length) {
checkConsistent();
if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_FLOW) != 0) {
GlobalOptions.err.println("merging sequentialBlock: "+this);
GlobalOptions.err.println("and: "+succ);
}
SlotSet succIn = new SlotSet();
SlotSet succKill = new SlotSet(); SlotSet succKill = new SlotSet();
VariableSet succGen = new VariableSet(); VariableSet succGen = new VariableSet();
succ.fillInGenSet(succIn, succKill); block.fillInGenSet(succIn, succKill);
succGen.addAll(succKill); succGen.addAll(succKill);
SuccessorInfo succInfo = (SuccessorInfo) successors.get(NEXT_BY_ADDR); if (this.block == null) {
succIn.merge(succInfo.gen); this.block = block;
succIn.removeAll(succInfo.kill); lastModified = block;
block.setFlowBlock(this);
succGen.mergeGenKill(succInfo.gen, succKill); block.fillSuccessors();
succKill.addAll(succInfo.kill); this.length = length;
this.in.addAll(succIn);
this.gen.addAll(succKill); in = succIn;
gen = succGen;
removeSuccessor(lastModified.jump); for (Iterator i = successors.values().iterator(); i.hasNext();) {
lastModified.removeJump(); SuccessorInfo info = (SuccessorInfo) i.next();
lastModified = lastModified.appendBlock(succ); info.gen = new VariableSet();
succ.fillSuccessors(); info.kill = new SlotSet();
succInfo = (SuccessorInfo) successors.get(NEXT_BY_ADDR); info.gen.addAll(succGen);
succInfo.gen = succGen; info.kill.addAll(succKill);
succInfo.kill = succKill; }
this.length += length; } else {
checkConsistent(); checkConsistent();
doTransformations(); if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_FLOW) != 0) {
GlobalOptions.err.println("appending Block: "+block);
}
SuccessorInfo succInfo
= (SuccessorInfo) successors.get(NEXT_BY_ADDR);
succIn.merge(succInfo.gen);
succIn.removeAll(succInfo.kill);
succGen.mergeGenKill(succInfo.gen, succKill);
succKill.mergeKill(succInfo.kill);
this.in.addAll(succIn);
this.gen.addAll(succKill);
removeSuccessor(lastModified.jump);
lastModified.removeJump();
lastModified = lastModified.appendBlock(block);
block.fillSuccessors();
succInfo = (SuccessorInfo) successors.get(NEXT_BY_ADDR);
succInfo.gen = succGen;
succInfo.kill = succKill;
this.length += length;
checkConsistent();
doTransformations();
}
checkConsistent();
} }
/** /**
@ -925,6 +914,12 @@ public class FlowBlock {
checkConsistent(); checkConsistent();
succ.checkConsistent(); succ.checkConsistent();
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_ANALYZE) != 0)
GlobalOptions.err.println
("T2(["+addr+","+getNextAddr()+"],["
+succ.addr+","+succ.getNextAddr()+"])");
SuccessorInfo succInfo = (SuccessorInfo) successors.remove(succ); SuccessorInfo succInfo = (SuccessorInfo) successors.remove(succ);
/* Update the in/out-Vectors now */ /* Update the in/out-Vectors now */
@ -1051,6 +1046,8 @@ public class FlowBlock {
checkConsistent(); checkConsistent();
if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_ANALYZE) != 0)
GlobalOptions.err.println("T1(["+addr+","+getNextAddr()+"])");
SuccessorInfo succInfo = (SuccessorInfo) successors.remove(this); SuccessorInfo succInfo = (SuccessorInfo) successors.remove(this);
/* Update the in/out-Vectors now */ /* Update the in/out-Vectors now */
@ -1203,11 +1200,12 @@ public class FlowBlock {
GlobalOptions.err.println("before Transformation: "+this); GlobalOptions.err.println("before Transformation: "+this);
while (lastModified instanceof SequentialBlock) { while (lastModified instanceof SequentialBlock) {
if (!lastModified.getSubBlocks()[0].doTransformations()) if (lastModified.getSubBlocks()[0].doTransformations())
lastModified = lastModified.getSubBlocks()[1]; continue;
lastModified = lastModified.getSubBlocks()[1];
} }
while (lastModified.doTransformations()) while (lastModified.doTransformations())
/* empty */; { /* empty */ }
if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_FLOW) != 0) if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_FLOW) != 0)
GlobalOptions.err.println("after Transformation: "+this); GlobalOptions.err.println("after Transformation: "+this);
@ -1274,9 +1272,6 @@ public class FlowBlock {
if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_FLOW) != 0) if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_FLOW) != 0)
GlobalOptions.err.println("after T1: "+this); GlobalOptions.err.println("after T1: "+this);
if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_ANALYZE) != 0)
GlobalOptions.err.println("T1("+addr+","+getNextAddr()
+") succeeded");
/* T1 transformation succeeded. This may /* T1 transformation succeeded. This may
* make another T2 analysis in the previous * make another T2 analysis in the previous
* block possible. * block possible.
@ -1301,20 +1296,17 @@ public class FlowBlock {
} else { } else {
if ((nextByAddr == succ || succ.nextByAddr == this) if ((nextByAddr == succ || succ.nextByAddr == this)
/* Only do T2 transformation if the blocks are /* Only do T2 transformation if the blocks are
* adjacent. */ * adjacent.
*/
&& doT2(succ)) { && doT2(succ)) {
/* T2 transformation succeeded. */ /* T2 transformation succeeded. */
changed = true; changed = true;
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_FLOW) != 0)
GlobalOptions.err.println("after T2: "+this);
if ((GlobalOptions.debuggingFlags if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_ANALYZE) != 0) & GlobalOptions.DEBUG_FLOW) != 0)
GlobalOptions.err.println GlobalOptions.err.println("after T2: "+this);
("T2("+addr+","+getNextAddr()+") succeeded"); break;
break; }
}
/* Check if all predecessors of succ /* Check if all predecessors of succ
* lie in range [start,end). Otherwise * lie in range [start,end). Otherwise
@ -1363,6 +1355,9 @@ public class FlowBlock {
* @param end the end of the address range. * @param end the end of the address range.
*/ */
public boolean analyzeSwitch(int start, int end) { public boolean analyzeSwitch(int start, int end) {
if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_ANALYZE) != 0)
GlobalOptions.err.println("analyzeSwitch("+start+", "+end+")");
SwitchBlock switchBlock = (SwitchBlock) lastModified; SwitchBlock switchBlock = (SwitchBlock) lastModified;
boolean changed = false; boolean changed = false;
@ -1453,6 +1448,11 @@ public class FlowBlock {
if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_FLOW) != 0) if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_FLOW) != 0)
GlobalOptions.err.println("after analyzeSwitch: "+this); GlobalOptions.err.println("after analyzeSwitch: "+this);
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_ANALYZE) != 0)
GlobalOptions.err.println
("analyzeSwitch done: " + start + " - " + end + "; "
+ addr + " - " + getNextAddr());
checkConsistent(); checkConsistent();
return changed; return changed;
} }
@ -1504,10 +1504,6 @@ public class FlowBlock {
SuccessorInfo info = (SuccessorInfo) successors.get(jump.destination); SuccessorInfo info = (SuccessorInfo) successors.get(jump.destination);
if (info == null) { if (info == null) {
info = new SuccessorInfo(); info = new SuccessorInfo();
info.gen = new VariableSet();
info.kill = new SlotSet();
block.fillInGenSet(null, info.kill);
info.gen.addAll(info.kill);
info.jumps = jump; info.jumps = jump;
if (jump.destination != END_OF_METHOD) if (jump.destination != END_OF_METHOD)
jump.destination.predecessors.add(this); jump.destination.predecessors.add(this);

@ -859,8 +859,8 @@ public class TransformExceptionHandlers {
*/ */
EmptyBlock jump = new EmptyBlock(new Jump(catchFlow)); EmptyBlock jump = new EmptyBlock(new Jump(catchFlow));
FlowBlock newFlow = new FlowBlock(catchFlow.method, FlowBlock newFlow = new FlowBlock(catchFlow.method,
catchFlow.getAddr(), 0); catchFlow.getAddr());
newFlow.setBlock(jump); newFlow.appendBlock(jump, 0);
catchFlow.prevByAddr.nextByAddr = newFlow; catchFlow.prevByAddr.nextByAddr = newFlow;
newFlow.nextByAddr = catchFlow; newFlow.nextByAddr = catchFlow;
catchFlow = newFlow; catchFlow = newFlow;

Loading…
Cancel
Save