# HG changeset patch # User Stefan Anzinger # Date 1432022014 -7200 # Node ID b148be759cf6bed02b6f40a2d4d187739858dbdb # Parent c435184ca071a1cdbc28b533ee6dd20910ac7c1e ControlFlowGraph.computeLoopBlocks removed recursion; simulating stack diff -r c435184ca071 -r b148be759cf6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Tue May 19 09:51:55 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Tue May 19 09:53:34 2015 +0200 @@ -305,20 +305,53 @@ } } - private static void computeLoopBlocks(Block block, Loop loop) { - if (block.getLoop() == loop) { - return; - } - assert block.loop == loop.getParent(); - block.loop = loop; + private static void computeLoopBlocks(Block ablock, Loop aloop) { + final int process = 0; + final int stepOut = 1; + class Frame { + final Iterator blocks; + final Loop loop; + final Frame parent; - assert !loop.getBlocks().contains(block); - loop.getBlocks().add(block); + public Frame(Iterator blocks, Loop loop, Frame parent) { + super(); + this.blocks = blocks; + this.loop = loop; + this.parent = parent; + } + } + int state = process; + Frame c = new Frame(Arrays.asList(ablock).iterator(), aloop, null); + while (c != null) { + int nextState = state; + if (state == process) { + Loop loop = c.loop; + Block block = c.blocks.next(); + if (block.getLoop() == loop) { + nextState = stepOut; + } else { + assert block.loop == loop.getParent(); + block.loop = c.loop; - if (block != loop.getHeader()) { - for (Block pred : block.getPredecessors()) { - computeLoopBlocks(pred, loop); + assert !c.loop.getBlocks().contains(block); + c.loop.getBlocks().add(block); + + if (block != c.loop.getHeader()) { + c = new Frame(block.getPredecessors().iterator(), loop, c); + } else { + nextState = stepOut; + } + } + } else if (state == stepOut) { + if (c.blocks.hasNext()) { + nextState = process; + } else { + c = c.parent; + } + } else { + GraalInternalError.shouldNotReachHere(); } + state = nextState; } }