lot of changes for new early operand merging

now also detects 1.0 as ++ or --


git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@431 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent 25e2f38ce9
commit 7c30104a69
  1. 198
      jode/jode/flow/CreatePrePostIncExpression.java

@ -31,129 +31,131 @@ public class CreatePrePostIncExpression {
public static boolean createLocalPrePostInc(InstructionContainer ic, public static boolean createLocalPrePostInc(InstructionContainer ic,
StructuredBlock last) { StructuredBlock last) {
/* Situations:
*
* PUSH local_x -> PUSH local_x++
* IINC local_x, +/-1
*
* IINC local_x, +/-1
* PUSH local_x -> PUSH ++local_x
*/
if (last.outer instanceof SequentialBlock if (!(last.outer instanceof SequentialBlock)
&& last.outer.getSubBlocks()[0] instanceof InstructionBlock) { || !(last.outer.getSubBlocks()[0] instanceof InstructionBlock))
return false;
Expression instr1 = ((InstructionBlock)
last.outer.getSubBlocks()[0]) Expression instr1 = ((InstructionBlock)
.getInstruction(); last.outer.getSubBlocks()[0]).getInstruction();
Expression instr2 = ic.getInstruction(); Expression instr2 = ic.getInstruction();
IIncOperator iinc; IIncOperator iinc;
LocalLoadOperator load; LocalLoadOperator load;
boolean isPost; boolean isPost;
if (instr1 instanceof IIncOperator if (instr1 instanceof IIncOperator
&& instr2 instanceof LocalLoadOperator) { && instr2 instanceof LocalLoadOperator) {
iinc = (IIncOperator) instr1; iinc = (IIncOperator) instr1;
load = (LocalLoadOperator) instr2; load = (LocalLoadOperator) instr2;
isPost = false; isPost = false;
} else if (instr1 instanceof LocalLoadOperator } else if (instr1 instanceof LocalLoadOperator
&& instr2 instanceof IIncOperator) { && instr2 instanceof IIncOperator) {
load = (LocalLoadOperator) instr1; load = (LocalLoadOperator) instr1;
iinc = (IIncOperator) instr2; iinc = (IIncOperator) instr2;
isPost = true; isPost = true;
} else } else
return false; return false;
int op; int op;
if (iinc.getOperatorIndex() == iinc.ADD_OP + iinc.OPASSIGN_OP) if (iinc.getOperatorIndex() == iinc.ADD_OP + iinc.OPASSIGN_OP)
op = Operator.INC_OP; op = Operator.INC_OP;
else if (iinc.getOperatorIndex() == iinc.NEG_OP + iinc.OPASSIGN_OP) else if (iinc.getOperatorIndex() == iinc.NEG_OP + iinc.OPASSIGN_OP)
op = Operator.DEC_OP; op = Operator.DEC_OP;
else else
return false; return false;
if (iinc.getValue().equals("-1")) if (iinc.getValue().equals("-1"))
op ^= 1; op ^= 1;
else if (!iinc.getValue().equals("1")) else if (!iinc.getValue().equals("1"))
return false; return false;
if (!iinc.matches(load)) if (!iinc.matches(load))
return false; return false;
Type type = load.getType().intersection(Type.tUInt); Type type = load.getType().intersection(Type.tUInt);
Operator ppop = Operator ppop =
new LocalPrePostFixOperator(type, op, iinc, isPost); new LocalPrePostFixOperator(type, op, iinc, isPost);
ic.setInstruction(ppop); ic.setInstruction(ppop);
ic.moveDefinitions(last.outer, last); ic.moveDefinitions(last.outer, last);
last.replace(last.outer); last.replace(last.outer);
return true; return true;
}
return false;
} }
public static boolean createPostInc(InstructionContainer ic, public static boolean createPostInc(InstructionContainer ic,
StructuredBlock last) { StructuredBlock last) {
/* Situation: /* Situation:
* *
* PUSH load/storeOps PUSH load/storeOps * PUSH load/storeOps (optional/
* DUP load/storeOps PUSH store++/-- * not checked) PUSH load/storeOps
* load (unresolved) * DUP load/storeOps (optional) PUSH store++/--
* DUP -> * PUSH load(stack)
* PUSH +/-1 * DUP_X(storeOps count) ->
* IADD/SUB * store(stack) = stack_0 +/- 1
* store (unresolved)
*
* load (no params) -> PUSH store++/--
* DUP
* PUSH +/-1
* store IADD/SUB
*/ */
if (!(ic.getInstruction().getOperator() instanceof StoreInstruction) if (!(ic.getInstruction() instanceof ComplexExpression)
|| !(ic.getInstruction().getOperator() instanceof StoreInstruction)
|| !(ic.getInstruction().isVoid())) || !(ic.getInstruction().isVoid()))
return false; return false;
ComplexExpression storeExpr = (ComplexExpression) ic.getInstruction();
StoreInstruction store = StoreInstruction store =
(StoreInstruction) ic.getInstruction().getOperator(); (StoreInstruction) ic.getInstruction().getOperator();
/* Make sure that the lvalue part of the store is
if (!(last.outer instanceof SequentialBlock)) * not yet resolved (and not that the rvalue part
* should also have 1 remaining operand)
*/
int storeParams = store.getLValueOperandCount();
if (storeExpr.getOperandCount() != storeParams + 1
|| !(storeExpr.getSubExpressions()[storeParams]
instanceof ComplexExpression))
return false;
if (storeParams > 0) {
for (int i=0; i< storeParams; i++) {
if (!(storeExpr.getSubExpressions()[i] instanceof NopOperator))
return false;
}
}
ComplexExpression binExpr = (ComplexExpression)
storeExpr.getSubExpressions()[storeParams];
if (!(binExpr instanceof ComplexExpression)
|| !(binExpr.getOperator() instanceof BinaryOperator)
|| !(binExpr.getSubExpressions()[0] instanceof NopOperator)
|| !(binExpr.getSubExpressions()[1] instanceof ConstOperator))
return false; return false;
SequentialBlock sb = (SequentialBlock)last.outer;
Expression binOp; BinaryOperator binOp = (BinaryOperator) binExpr.getOperator();
if (store.getLValueOperandCount() == 0) { ConstOperator constOp = (ConstOperator) binExpr.getSubExpressions()[1];
if (!(ic.getInstruction() instanceof ComplexExpression))
return false;
binOp = ((ComplexExpression) ic.getInstruction())
.getSubExpressions()[0];
} else {
if (!(sb.subBlocks[0] instanceof InstructionBlock)
|| !(sb.outer instanceof SequentialBlock))
return false;
binOp = ((InstructionBlock) sb.subBlocks[0])
.getInstruction();
sb = (SequentialBlock) sb.outer;
}
if (!(binOp instanceof BinaryOperator))
return false;
int op; int op;
if (binOp.getOperator().getOperatorIndex() == store.ADD_OP) if (binOp.getOperatorIndex() == store.ADD_OP)
op = Operator.INC_OP; op = Operator.INC_OP;
else if (binOp.getOperator().getOperatorIndex() == store.NEG_OP) else if (binOp.getOperatorIndex() == store.NEG_OP)
op = Operator.DEC_OP; op = Operator.DEC_OP;
else else
return false; return false;
if (!(sb.subBlocks[0] instanceof InstructionBlock)) if (constOp.getValue().equals("-1")
return false; || constOp.getValue().equals("-1.0"))
InstructionBlock ib = (InstructionBlock) sb.subBlocks[0];
if (!(ib.getInstruction() instanceof ConstOperator))
return false;
ConstOperator constOp = (ConstOperator) ib.getInstruction();
if (constOp.getValue().equals("-1"))
op ^= 1; op ^= 1;
else if (!constOp.getValue().equals("1")) else if (!constOp.getValue().equals("1")
&& !constOp.getValue().equals("-1.0"))
return false; return false;
if (!(sb.outer instanceof SequentialBlock)) if (!(last.outer instanceof SequentialBlock))
return false; return false;
sb = (SequentialBlock) sb.outer; SequentialBlock sb = (SequentialBlock)last.outer;
if (!(sb.subBlocks[0] instanceof SpecialBlock)) if (!(sb.subBlocks[0] instanceof SpecialBlock))
return false; return false;
@ -168,7 +170,7 @@ public class CreatePrePostIncExpression {
sb = (SequentialBlock) sb.outer; sb = (SequentialBlock) sb.outer;
if (!(sb.subBlocks[0] instanceof InstructionBlock)) if (!(sb.subBlocks[0] instanceof InstructionBlock))
return false; return false;
ib = (InstructionBlock) sb.subBlocks[0]; InstructionBlock ib = (InstructionBlock) sb.subBlocks[0];
if (!(ib.getInstruction() instanceof Operator) if (!(ib.getInstruction() instanceof Operator)
|| !store.matches((Operator) ib.getInstruction())) || !store.matches((Operator) ib.getInstruction()))

Loading…
Cancel
Save