From f5d6e8d75151a4427a4e43ac115243e4f0018acd Mon Sep 17 00:00:00 2001 From: Ioannis Tsakpinis Date: Fri, 7 Dec 2012 00:27:32 +0200 Subject: [PATCH] KT-3141 Use iteration instead of recursion in traverseInstructionsInReverseOrder and traverseNextInstructions. --- .../lang/cfg/pseudocode/PseudocodeImpl.java | 53 ++++++++++++++----- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/PseudocodeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/PseudocodeImpl.java index ca13f276ac4..4e539b36ea1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/PseudocodeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/PseudocodeImpl.java @@ -177,16 +177,29 @@ public class PseudocodeImpl implements Pseudocode { return reversedInstructions; } - private static void traverseInstructionsInReverseOrder(@NotNull Instruction instruction, + private static void traverseInstructionsInReverseOrder(@NotNull Instruction rootInstruction, @NotNull LinkedHashSet instructions) { - if (instructions.contains(instruction)) return; - instructions.add(instruction); - for (Instruction previousInstruction : instruction.getPreviousInstructions()) { - traverseInstructionsInReverseOrder(previousInstruction, instructions); + Deque stack = Queues.newArrayDeque(); + stack.push(rootInstruction); + + List previousInstructions = Lists.newArrayList(); + while ( !stack.isEmpty() ) { + final Instruction instruction = stack.pop(); + + if ( instructions.contains(instruction) ) + continue; + + instructions.add(instruction); + + // Reverse iteration order to match the original recursive order. + previousInstructions.addAll(instruction.getPreviousInstructions()); + for (Instruction previousInstruction : Lists.reverse(previousInstructions)) { + stack.push(previousInstruction); + } + previousInstructions.clear(); } } - //for tests only @NotNull public List getAllInstructions() { @@ -363,12 +376,28 @@ public class PseudocodeImpl implements Pseudocode { return visited; } - private void traverseNextInstructions(@NotNull Instruction instruction, @NotNull Set visited) { - if (visited.contains(instruction)) return; - visited.add(instruction); - for (Instruction nextInstruction : instruction.getNextInstructions()) { - if (nextInstruction == null) continue; //todo it might be null on incomplete code - traverseNextInstructions(nextInstruction, visited); + private static void traverseNextInstructions(@NotNull Instruction rootInstruction, @NotNull Set visited) { + Deque stack = Queues.newArrayDeque(); + stack.push(rootInstruction); + + List nextInstructions = Lists.newArrayList(); + while (!stack.isEmpty()) { + final Instruction instruction = stack.pop(); + + if (visited.contains(instruction)) + continue; + + visited.add(instruction); + + // Reverse iteration order to match the original recursive order. + nextInstructions.addAll(instruction.getNextInstructions()); + for (Instruction nextInstruction : Lists.reverse(nextInstructions)) { + if ( nextInstruction == null ) + continue; + + stack.push(nextInstruction); + } + nextInstructions.clear(); } }