*** empty log message ***

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@15 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 27 years ago
parent e36cac2a42
commit 2589bb4450
  1. 187
      jode/jode/flow/FlowBlock.java
  2. 13
      jode/jode/flow/StructuredBlock.java

@ -47,7 +47,7 @@ public class FlowBlock {
StructuredBlock lastModified;
/**
* All jumps that this flow block contains.
* All Jumps that this flow block contains.
*/
Vector successors;
@ -58,40 +58,47 @@ public class FlowBlock {
*/
Vector predecessors;
public void optimizeJumps(FlowBlock successor) {
/* remove all unconditional jumps to the successor which have the
* end of the block as normal successor.
/**
* This method optimizes the jumps to successor.
* Returns true, if all jumps could be eliminated.
*/
public boolean optimizeJumps(FlowBlock successor,
StructuredBlock structBlock) {
/* if the jump is the jump of the structBlock, skip it.
*/
/* remove all jumps to the successor which have the successor
* as getNextFlowBlock(). */
/* replace all conditional jumps to the successor, which are followed
* by a block which has the end of the block as normal successor,
* with "if (not condition) block".
*/
/* if there are jumps in a while block, which has the end of
* the block as normal successor or is followed by a
* unconditional jump to successor, replace jumps with breaks
* to the while block. If the condition of the while is true,
* and the first instruction is converted to a conditional break
* remove that break and use the condition in the while block.
/* if the successor is the dummy return instruction, replace all
* jumps with a return.
*/
/* if there are jumps in a while block or switch block and the
* while/switch block is followed by a jump to successor or has
* successor as getNextFlowBlock(), replace jump with break to
* the innermost such while/switch block.
*
* If the switch block hasn't been breaked before we could
* take some heuristics and add a jump after the switch to
* succesor, so that the above succeeds.
*
* If this is a while and the condition of the while is true,
* and this jump belongs to the first instruction in this
* while block and is inside a ConditionalBlock remove that
* ConditionalBlock an move the condition to the while block.
*/
/* if there are jumps in an switch block, which has as normal
* successor the end of this FlowBlock, replace them with a
* break to the switch block.
* if there successor isn't the end of this FlowBlock, but
* there are many, or the next rule could work (some more
* heuristics?) and there is currently no flow to the end of
* the switch block, replace all such successors with a break
* and add a new unconditional jump after the switch block. */
/* if there are unconditional jumps in an if-then block, which
/* if there are jumps in an if-then block, which
* have as normal successor the end of the if-then block, and
* the if-then block is followed by a single block, which has
* as normal successor the end of the block, then replace
* the if-then block is followed by a single block, then replace
* the if-then block with a if-then-else block and remove the
* unconditional jumps.
* unconditional jump.
*/
}
@ -162,34 +169,96 @@ public class FlowBlock {
public boolean doT1 {
/* search successor with smallest addr. */
Enumeration enum = successors.elements();
FlowBlock succ = null;
while (enum.hasMoreElements()) {
FlowBlock fb = ((Jump) enum.nextElement()).destination;
if (succ == null || fb.addr < succ.addr) {
succ = fb;
}
}
if (succ == null) {
/* There are no successors at all */
return false;
}
/* check if this successor has only this block as predecessor. */
/* if not, return false. */
if (succ.predecessors.size() != 1)
return false;
/* The switch case: if the last instruction in this block is a
* switch block, and all jumps to successor lie in a single case,
* or if all jumps
* which doesn't have the end of the block as normal
* successor, combine the successor with that block. But this
* doesn't catch all cases.
/* First find the innermost block that contains all jumps to this
* successor and the last modified block.
*/
Enumeration enum = successors.elements();
StructuredBlock structBlock = lastModified;
while(enum.hasMoreElements()) {
Jump jump = (Jump) enum.nextElement();
optimizeJumps(successor);
while (!structBlock.contains(jump.parent))
structBlock = structBlock.outer;
/* structBlock can't be null now, because the
* outermost block contains every structured block.
*/
}
/* if the successor is the dummy return instruction, replace all
* jumps with a return.
/* The switch "fall through" case: if the structBlock is a
* switch, and the successor is the address of a case, and all
* other successors are inside the block preceding that case.
*/
if (case != null) {
SwitchBlock switchBlock = (StructuredBlock) structBlock;
/* Now put the succ.block into the next case.
*/
switchBlock.replaceSubBlock(nextcase,succ.block);
/* Do the following modifications on the struct block. */
structBlock = precedingcase;
} else {
/* Prepare the unification of the blocks: Make sure that
* structBlock has a successor outside of this block. This is
* always possible, because it contains lastModified.
*/
if (structBlock.jump == null) {
/* assert(structBlock.jump.getNextFlowBlock() != null) */
structBlock.setJump(structBlock.getNextFlowBlock());
}
/* Now unify the blocks: Create a new SequentialBlock
* containing structBlock and successor.block. Then replace
* structBlock with the new sequential block.
*/
}
/* Try to eliminate as many jumps as possible.
*/
optimizeJumps(succ, structBlock);
/* Now remove the jump of the structBlock if it points to successor.
*/
if (structBlock.jump == null)
structBlock.removeJump();
/* If there are further jumps, put a do/while(0) block around
* current block and replace every necessary jump with a break
* to the do/while block. Then combine the block with a
* sequential composition. */
* structBlock and replace every remaining jump with a break
* to the do/while block.
*/
/* Set last modified to correct value.
*/
lastModified = succ.lastModified;
}
public boolean doT2() {
/* If there are no jumps to the beginning of this flow block
* or if this block has other predecessors which weren't
* considered yet, return false.
* considered yet, return false. The second condition make
* sure that the while isn't created up to the first continue.
*/
/* If there is only one jump to the beginning and it is the
@ -197,56 +266,28 @@ public class FlowBlock {
* everything but the last instruction, or the last
* instruction is a increase/decrease statement), replace the
* do/while(0) with a for(;;last_instr) resp. create a new one
* and replace breaks to do/while with continue.
* and replace breaks to do/while with continue to for.
*/
{
/* Otherwise: */
optimizeJumps(this);
/* create a new while(true) block.
*/
}
/* Try to eliminate as many jumps as possible.
*/
optimizeJumps(this, block);
/* Now remove the jump of block if it points to this.
*/
/* if there are further jumps to this, replace every jump with a
* continue to while block and return true.
*/
}
}
}
/**
* A structured block describes a structured program. There may be a
* Jump after a block (even after a inner structured block), but the
* goal is, to remove all such jumps and make a single flow block.<p>
*
* There are following types of structured blocks: <ul>
* <li>if-then-(else)-block (IfThenElseBlock)</li>
* <li>(do)-while/for-block (LoopBlock)
* <li>switch-block (SwitchBlock)
* <li>try-catch-finally-block (TryBlock)
* <li>A block consisting of sub blocks (SequentialBlock)
* </ul>
*/
public class StructuredBlock {
/** The surrounding block, or null if this is the outermost block in a
* flow block.
*/
StructuredBlock parent;
/** The flow block to which this structured block belongs.
*/
FlowBlock flow;
}
public class ConditionalJump extends Jump {
Expression condition;
StructuredBlock prev;
FlowBlock parent;
FlowBlock jump, nojump;
}
public class UnconditionalJump extends Jump {
StructuredBlock prev;
FlowBlock parent;
FlowBlock jump;
}

@ -149,7 +149,7 @@ public abstract class StructuredBlock {
FlowBlock getNextFlowBlock(StructuredBlock subBlock) {
if (jump != null)
return jump;
return jump.destination;
return getNextFlowBlock();
}
@ -164,6 +164,17 @@ public abstract class StructuredBlock {
return false;
}
/**
* Returns if this block contains the given block.
* @param child the block which should be contained by this block.
* @return false, if child is null, or is not contained in this block.
*/
boolean contains(StructuredBlock child) {
while (child != this && child != null)
child = child.outer;
return (child == this);
}
/**
* Print the source code for this structured block. This may be
* called only once, because it remembers which local variables

Loading…
Cancel
Save