From aec2d9ac5e856d02f5261502ecb1068522761aef Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 15 Mar 1999 18:02:25 +0000 Subject: [PATCH] removeOnetimeLocals git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@432 379699f6-c40d-0410-875b-85095c16579e --- jode/jode/flow/FlowBlock.java | 6 +++ jode/jode/flow/InstructionContainer.java | 15 +++++++ jode/jode/flow/LoopBlock.java | 19 +++++++++ jode/jode/flow/SequentialBlock.java | 50 ++++++++++++++++++++++++ jode/jode/flow/StructuredBlock.java | 15 +++++++ 5 files changed, 105 insertions(+) diff --git a/jode/jode/flow/FlowBlock.java b/jode/jode/flow/FlowBlock.java index a84b652..fc7fa38 100644 --- a/jode/jode/flow/FlowBlock.java +++ b/jode/jode/flow/FlowBlock.java @@ -1468,6 +1468,12 @@ public class FlowBlock { } } + public void removeOnetimeLocals() { + block.removeOnetimeLocals(); + if (nextByAddr != null) + nextByAddr.removeOnetimeLocals(); + } + public void makeDeclaration(VariableSet param) { in.merge(param); in.subtract(param); diff --git a/jode/jode/flow/InstructionContainer.java b/jode/jode/flow/InstructionContainer.java index 74af55f..768b530 100644 --- a/jode/jode/flow/InstructionContainer.java +++ b/jode/jode/flow/InstructionContainer.java @@ -46,6 +46,21 @@ public abstract class InstructionContainer extends StructuredBlock { setJump(jump); } + /** + * This method should remove local variables that are only written + * and read one time directly after another.
+ * + * This is especially important for stack locals, that are created + * when there are unusual swap or dup instructions, but also makes + * inlined functions more pretty (but not that close to the + * bytecode). + */ + public void removeOnetimeLocals() { + if (instr != null) + instr = instr.removeOnetimeLocals(); + super.removeOnetimeLocals(); + } + /** * Fill all in variables into the given VariableSet. * @param in The VariableSet, the in variables should be stored to. diff --git a/jode/jode/flow/LoopBlock.java b/jode/jode/flow/LoopBlock.java index 2fabaf9..1d62b72 100644 --- a/jode/jode/flow/LoopBlock.java +++ b/jode/jode/flow/LoopBlock.java @@ -387,6 +387,25 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock { bodyBlock.removePush(); } + /** + * This method should remove local variables that are only written + * and read one time directly after another.
+ * + * This is especially important for stack locals, that are created + * when there are unusual swap or dup instructions, but also makes + * inlined functions more pretty (but not that close to the + * bytecode). + */ + public void removeOnetimeLocals() { + cond = cond.removeOnetimeLocals(); + if (type == FOR) { + if (init != null) + init.removeOnetimeLocals(); + incr.removeOnetimeLocals(); + } + super.removeOnetimeLocals(); + } + /** * Replace all breaks to block with a continue to this. * @param block the breakable block where the breaks originally diff --git a/jode/jode/flow/SequentialBlock.java b/jode/jode/flow/SequentialBlock.java index c1dc8ad..e30551a 100644 --- a/jode/jode/flow/SequentialBlock.java +++ b/jode/jode/flow/SequentialBlock.java @@ -17,6 +17,7 @@ */ package jode.flow; import jode.decompiler.TabbedPrintWriter; +import jode.expr.LocalStoreOperator; /** * A sequential block combines exactly two structured blocks to a new @@ -67,6 +68,55 @@ public class SequentialBlock extends StructuredBlock { return null; } + /** + * This method should remove local variables that are only written + * and read one time directly after another.
+ * + * This is especially important for stack locals, that are created + * when there are unusual swap or dup instructions, but also makes + * inlined functions more pretty (but not that close to the + * bytecode). + */ + public void removeOnetimeLocals() { + StructuredBlock secondBlock = subBlocks[1]; + if (secondBlock instanceof SequentialBlock) + secondBlock = ((SequentialBlock)secondBlock).subBlocks[0]; + if (subBlocks[0] instanceof InstructionBlock + && secondBlock instanceof InstructionContainer) { + InstructionBlock first = (InstructionBlock) subBlocks[0]; + InstructionContainer second = (InstructionContainer) secondBlock; + /* check if subBlocks[0] writes to a local, second reads + * that local, the local is only used by this two blocks, + * and there are no side effects. In that case replace + * the LoadLocal with the righthandside of subBlocks[0] + * and replace subBlocks[1] with this block. Call + * removeOnetimelLocals on subBlocks[1] afterwards and + * return. + */ + + if (first.getInstruction().getOperator() + instanceof LocalStoreOperator) { + LocalStoreOperator store = (LocalStoreOperator) + first.getInstruction().getOperator(); + if (store.getLocalInfo().getUseCount() == 2 + && (second.getInstruction().canCombine + (first.getInstruction()) > 0)) { + System.err.println("before: "+first+second); + + second.setInstruction(second.getInstruction() + .combine(first.getInstruction())); + System.err.println("after: "+second); + StructuredBlock sb = subBlocks[1]; + sb.moveDefinitions(this, sb); + sb.replace(this); + sb.removeOnetimeLocals(); + return; + } + } + } + super.removeOnetimeLocals(); + } + /** * Returns the block where the control will normally flow to, when * the given sub block is finished (not ignoring the jump diff --git a/jode/jode/flow/StructuredBlock.java b/jode/jode/flow/StructuredBlock.java index 91c92fa..c670fa9 100644 --- a/jode/jode/flow/StructuredBlock.java +++ b/jode/jode/flow/StructuredBlock.java @@ -390,6 +390,21 @@ public abstract class StructuredBlock { subBlocks[i].removePush(); } + /** + * This method should remove local variables that are only written + * and read one time directly after another.
+ * + * This is especially important for stack locals, that are created + * when there are unusual swap or dup instructions, but also makes + * inlined functions more pretty (but not that close to the + * bytecode). + */ + public void removeOnetimeLocals() { + StructuredBlock[] subBlocks = getSubBlocks(); + for (int i=0; i< subBlocks.length; i++) + subBlocks[i].removeOnetimeLocals(); + } + /** * Make the declarations, i.e. initialize the declare variable * to correct values. This will declare every variable that