used gets now calculated at propagateUsage

incr/init renamed to incr/init-Block/Instr


git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@789 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent 778fdc2607
commit 97fe374b0f
  1. 139
      jode/jode/flow/LoopBlock.java

@ -51,13 +51,22 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
*/ */
VariableStack condStack; VariableStack condStack;
/** /**
* The init instruction, only valid if type == FOR or POSSFOR * The init instruction block, only valid if type == POSSFOR
*/ */
InstructionBlock init; InstructionBlock initBlock;
/** /**
* The increase instruction, only valid if type == FOR or POSSFOR. * The increase instruction block, only valid if type == POSSFOR.
*/ */
InstructionBlock incr; InstructionBlock incrBlock;
/**
* The init instruction, only valid if type == FOR.
*/
Expression initInstr;
/**
* The increase instruction, only valid if type == FOR.
*/
Expression incrInstr;
/** /**
* True, if the initializer is a declaration. * True, if the initializer is a declaration.
@ -84,17 +93,22 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
*/ */
VariableStack continueStack; VariableStack continueStack;
/*{ invariant { type == POSSFOR || type == FOR || incr == null /*{ invariant { type == POSSFOR || (incrBlock == null && initBlock == null)
:: "(while/do while) with incr"; :: "(while/do while) with incr";
type == FOR || init == null type == FOR || (incrInstr == null && initInstr == null)
:: "(while/do while/poss for) with init"; :: "(while/do while/poss for) with init";
(type != FOR && type != POSSFOR) || incr != null type != POSSFOR || incrBlock != null
:: "(possible) for without incr"; :: "possible for without incr";
type != FOR || incrInstr != null
:: "for without incr";
type != POSSFOR || type != POSSFOR ||
(incr.getInstruction() instanceof CombineableOperator) incrBlock.getInstruction() instanceof CombineableOperator
:: "possible for with invalid incr"; :: "possible for with invalid incr";
init == null || initBlock == null ||
(init.getInstruction() instanceof CombinableOperator) (initBlock.getInstruction() instanceof CombinableOperator)
:: "Initializer is not combinableOperator";
initInstr == null ||
(initInstr instanceof CombinableOperator)
:: "Initializer is not combinableOperator"; :: "Initializer is not combinableOperator";
cond != null && cond.getType() == Type.tBoolean cond != null && cond.getType() == Type.tBoolean
:: "invalid condition type"; :: "invalid condition type";
@ -128,10 +142,13 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
body.setFlowBlock(flowBlock); body.setFlowBlock(flowBlock);
} }
public void setInit(InstructionBlock init) { public void setInit(InstructionBlock initBlock) {
this.init = init; if (type == POSSFOR) {
if (type == FOR) this.initBlock = initBlock;
init.removeBlock(); } else if (type == FOR) {
this.initInstr = initBlock.getInstruction();
initBlock.removeBlock();
}
} }
public boolean conditionMatches(CombineableOperator combinable) { public boolean conditionMatches(CombineableOperator combinable) {
@ -149,23 +166,24 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
/* We can now say, if this is a for block or not. /* We can now say, if this is a for block or not.
*/ */
if (cond.containsMatchingLoad((CombineableOperator) if (cond.containsMatchingLoad((CombineableOperator)
incr.getInstruction())) { incrBlock.getInstruction())) {
type = FOR; type = FOR;
incr.removeBlock(); incrInstr = incrBlock.getInstruction();
if (init != null) { incrBlock.removeBlock();
if (cond.containsMatchingLoad((CombineableOperator) if (initBlock != null) {
init.getInstruction())) if (cond.containsMatchingLoad
init.removeBlock(); ((CombineableOperator) initBlock.getInstruction())) {
else initInstr = initBlock.getInstruction();
init = null; initBlock.removeBlock();
}
} }
} else { } else {
/* This is not a for block, as it seems first. Make /* This is not a for block, as it seems first. Make
* it a while block again, and forget about init and * it a while block again, and forget about init and
* incr. */ * incr. */
type = WHILE; type = WHILE;
init = incr = null;
} }
initBlock = incrBlock = null;
} }
mayChangeJump = false; mayChangeJump = false;
} }
@ -183,10 +201,8 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
* loop-block. This is the initializer for for-blocks. * loop-block. This is the initializer for for-blocks.
*/ */
public void removeLocallyDeclareable(VariableSet set) { public void removeLocallyDeclareable(VariableSet set) {
if (type == FOR && init != null if (type == FOR && initInstr instanceof StoreInstruction) {
&& init.getInstruction() instanceof StoreInstruction) { StoreInstruction storeOp = (StoreInstruction) initInstr;
StoreInstruction storeOp =
(StoreInstruction) init.getInstruction();
if (storeOp.getLValue() instanceof LocalStoreOperator) { if (storeOp.getLValue() instanceof LocalStoreOperator) {
LocalInfo local = LocalInfo local =
((LocalStoreOperator) storeOp.getLValue()).getLocalInfo(); ((LocalStoreOperator) storeOp.getLValue()).getLocalInfo();
@ -196,12 +212,14 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
} }
public VariableSet propagateUsage() { public VariableSet propagateUsage() {
if (used == null)
used = new VariableSet(); /*XXX*/
if (type == FOR) { if (type == FOR) {
if (init != null) incrInstr.fillInGenSet(null, used);
used.unionExact(init.used); if (initInstr != null)
if (incr != null) initInstr.fillInGenSet(null, used);
used.unionExact(incr.used);
} }
cond.fillInGenSet(null, used);
VariableSet allUse = (VariableSet) used.clone(); VariableSet allUse = (VariableSet) used.clone();
allUse.unionExact(bodyBlock.propagateUsage()); allUse.unionExact(bodyBlock.propagateUsage());
return allUse; return allUse;
@ -229,6 +247,30 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
return new StructuredBlock[] { bodyBlock }; return new StructuredBlock[] { bodyBlock };
} }
/**
* Check if this is an local store instruction to a not yet declared
* variable. In that case mark this as declaration and return the
* variable.
*/
public void checkDeclaration(VariableSet declareSet) {
if (initInstr instanceof StoreInstruction
&& (((StoreInstruction)initInstr).getLValue()
instanceof LocalStoreOperator)) {
StoreInstruction storeOp = (StoreInstruction) initInstr;
LocalInfo local =
((LocalStoreOperator) storeOp.getLValue()).getLocalInfo();
if (declareSet.contains(local)) {
/* Special case: This is a variable assignment, and
* the variable has not been declared before. We can
* change this to a initializing variable declaration.
*/
isDeclaration = true;
storeOp.getSubExpressions()[1].makeInitializer();
declareSet.removeElement(local);
}
}
}
/** /**
* Make the declarations, i.e. initialize the declare variable * Make the declarations, i.e. initialize the declare variable
* to correct values. This will declare every variable that * to correct values. This will declare every variable that
@ -237,8 +279,8 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
*/ */
public void makeDeclaration(VariableSet done) { public void makeDeclaration(VariableSet done) {
super.makeDeclaration(done); super.makeDeclaration(done);
if (type == FOR && init != null) if (type == FOR && initInstr != null)
init.checkDeclaration(declare); checkDeclaration(declare);
} }
public void dumpSource(TabbedPrintWriter writer) public void dumpSource(TabbedPrintWriter writer)
@ -274,21 +316,21 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
break; break;
case FOR: case FOR:
writer.print("for ("); writer.print("for (");
if (init != null) { if (initInstr != null) {
if (init.isDeclaration) { if (isDeclaration) {
writer.printType(((LocalStoreOperator) writer.printType(((LocalStoreOperator)
((CombineableOperator) ((CombineableOperator) initInstr)
init.getInstruction()).getLValue()) .getLValue())
.getLocalInfo().getType().getHint()); .getLocalInfo().getType().getHint());
writer.print(" "); writer.print(" ");
} }
init.getInstruction().dumpExpression(writer); initInstr.dumpExpression(writer);
} else } else
writer.print("/**/"); writer.print("/**/");
writer.print("; "); writer.print("; ");
cond.dumpExpression(writer); cond.dumpExpression(writer);
writer.print("; "); writer.print("; ");
incr.getInstruction().dumpExpression(writer); incrInstr.dumpExpression(writer);
writer.print(")"); writer.print(")");
break; break;
} }
@ -411,7 +453,7 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
public void removePush() { public void removePush() {
if (condStack != null) if (condStack != null)
cond = condStack.mergeIntoExpression(cond, used); cond = condStack.mergeIntoExpression(cond);
bodyBlock.removePush(); bodyBlock.removePush();
} }
@ -427,9 +469,9 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
public void removeOnetimeLocals() { public void removeOnetimeLocals() {
cond = cond.removeOnetimeLocals(); cond = cond.removeOnetimeLocals();
if (type == FOR) { if (type == FOR) {
if (init != null) if (initInstr != null)
init.removeOnetimeLocals(); initInstr.removeOnetimeLocals();
incr.removeOnetimeLocals(); incrInstr.removeOnetimeLocals();
} }
super.removeOnetimeLocals(); super.removeOnetimeLocals();
} }
@ -470,15 +512,16 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
public void simplify() { public void simplify() {
cond = cond.simplify(); cond = cond.simplify();
if (type == FOR) { if (type == FOR) {
incr.simplify(); incrInstr.simplify();
if (init != null) if (initInstr != null)
init.simplify(); initInstr.simplify();
} }
super.simplify(); super.simplify();
} }
public boolean doTransformations() { public boolean doTransformations() {
return init == null && (type == FOR || type == POSSFOR) return ((initBlock == null && type == POSSFOR)
|| (initInstr == null && type == FOR))
&& CreateForInitializer.transform(this, flowBlock.lastModified); && CreateForInitializer.transform(this, flowBlock.lastModified);
} }
} }

Loading…
Cancel
Save