Chromium Code Reviews| Index: frog/leg/ssa/codegen.dart |
| diff --git a/frog/leg/ssa/codegen.dart b/frog/leg/ssa/codegen.dart |
| index 222ced5db3b35fc15fb38744d745150a70897a4d..89241acdfaabc3c94cd9c6dc6e47d44ec86d0f52 100644 |
| --- a/frog/leg/ssa/codegen.dart |
| +++ b/frog/leg/ssa/codegen.dart |
| @@ -211,12 +211,43 @@ class SsaCodeGenerator implements HVisitor { |
| return node.accept(this); |
| } |
| + void handleLabeledBlock(HBasicBlock node) { |
| + HLabeledBlockInformation labeledBlockInfo = node.labeledBlockInformation; |
| + if (labeledBlockInfo.start === node) { |
| + addIndentation(); |
| + for (SourceString label in labeledBlockInfo.labels) { |
| + addLabel(label); |
| + buffer.add(":"); |
| + } |
| + buffer.add("{\n"); |
| + indent++; |
| + } else { |
| + assert(labeledBlockInfo.end === node); |
| + assert((){ |
| + // Check that this block is (transitively) dominated by the start block. |
| + HBasicBlock block = node; |
| + while (block.dominator !== null) { |
| + block = block.dominator; |
| + if (block === labeledBlockInfo.start) return true; |
| + } |
| + return false; |
| + }); |
| + indent--; |
| + addIndentation(); |
| + buffer.add("}\n"); |
| + } |
| + } |
| + |
| visitBasicBlock(HBasicBlock node) { |
| currentBlock = node; |
| - // While loop will be closed by the conditional loop-branch. |
| - // TODO(floitsch): HACK HACK HACK. |
| - if (currentBlock.isLoopHeader()) beginLoop(node); |
| + if (node.hasLabeledBlockInformation()) { |
| + handleLabeledBlock(node); |
| + } else if (currentBlock.isLoopHeader()) { |
| + // While loop will be closed by the conditional loop-branch. |
| + // TODO(floitsch): HACK HACK HACK. |
| + beginLoop(node); |
| + } |
| HInstruction instruction = node.first; |
| while (instruction != null) { |
| @@ -350,6 +381,33 @@ class SsaCodeGenerator implements HVisitor { |
| visitBasicBlock(dominated[0]); |
| } |
| + void addLabel(SourceString label) { |
|
floitsch
2012/02/20 19:01:54
to many addLabels and similar: sometimes with pref
Lasse Reichstein Nielsen
2012/02/21 13:53:56
There are two addLabels, one for optimized code (a
|
| + buffer.add(label.toString()); |
| + } |
| + |
| + visitBreak(HBreak node) { |
| + assert(currentBlock.successors.length == 1); |
| + addIndentation(); |
| + buffer.add("break"); |
| + if (node.label !== null) { |
| + buffer.add(" "); |
| + addLabel(node.label); |
| + } |
| + buffer.add(";\n"); |
| + List<HBasicBlock> dominated = currentBlock.dominatedBlocks; |
| + // No block finishing with a 'throw' can have more than |
|
floitsch
2012/02/20 19:01:54
s/throw/break.
Lasse Reichstein Nielsen
2012/02/21 13:53:56
Done.
|
| + // one dominated block (since it has only one successor). |
| + // If the successor is dominated by another block, then the other block |
| + // is responsible for visiting the successor. |
| + if (dominated.isEmpty()) return; |
| + if (dominated.length > 2) unreachable(); |
| + if (dominated.length == 2 && currentBlock !== currentGraph.entry) { |
| + unreachable(); |
| + } |
| + assert(dominated[0] == currentBlock.successors[0]); |
| + visitBasicBlock(dominated[0]); |
| + } |
| + |
| visitTry(HTry node) { |
| addIndentation(); |
| buffer.add('try {\n'); |
| @@ -427,7 +485,6 @@ class SsaCodeGenerator implements HVisitor { |
| // too. The if happens to dominate the exit-block. |
| assert(!node.hasElse); |
| assert(dominatedCount == 3); |
| - assert(dominated.last().isExitBlock()); |
| visitBasicBlock(dominated[1]); |
|
floitsch
2012/02/20 19:01:54
This doesn't look right. It seems that the if can
Lasse Reichstein Nielsen
2012/02/21 13:53:56
You are right. All this complication has been redu
|
| visitBasicBlock(dominated[2]); |
| } |
| @@ -579,13 +636,11 @@ class SsaCodeGenerator implements HVisitor { |
| } |
| endLoop(node.block); |
| visitBasicBlock(branchBlock.successors[1]); |
| - // TODO(floitsch): with labeled breaks we can have more dominated blocks. |
| - assert(dominated.length <= 3); |
| - if (dominated.length == 3) { |
| - // This happens when the body contains a 'return', and the exit-block is |
| - // not dominated by a dominator of the while loop. |
| - assert(dominated[2].isExitBlock()); |
| - visitBasicBlock(dominated[2]); |
| + // With labeled breaks we can have more dominated blocks. |
| + if (dominated.length >= 3) { |
| + for (int i = 2; i < dominated.length; i++) { |
| + visitBasicBlock(dominated[i]); |
| + } |
| } |
| } |
| @@ -896,6 +951,9 @@ class SsaOptimizedCodeGenerator extends SsaCodeGenerator { |
| void beginLoop(HBasicBlock block) { |
| addIndentation(); |
| + for (SourceString label in block.loopInformation.labels) { |
| + buffer.add("${label.stringValue}:"); |
| + } |
| buffer.add('while (true) {\n'); |
| indent++; |
| } |
| @@ -1057,6 +1115,10 @@ class SsaUnoptimizedCodeGenerator extends SsaCodeGenerator { |
| buffer.add('}\n'); // Close 'switch'. |
| } |
| + void addLabel(SourceString label) { |
| + buffer.add("\$$label"); |
| + } |
| + |
| void beginLoop(HBasicBlock block) { |
| // TODO(ngeoffray): Don't put labels on loops that don't bailout. |
| String newLabel = pushLabel(); |
| @@ -1065,6 +1127,10 @@ class SsaUnoptimizedCodeGenerator extends SsaCodeGenerator { |
| } |
| addIndentation(); |
| + for (SourceString label in block.loopInformation.labels) { |
| + addLabel(label); |
| + buffer.add(":"); |
| + } |
| buffer.add('$newLabel: while (true) {\n'); |
| indent++; |