Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 class SsaCodeGeneratorTask extends CompilerTask { | 5 class SsaCodeGeneratorTask extends CompilerTask { |
| 6 SsaCodeGeneratorTask(Compiler compiler) : super(compiler); | 6 SsaCodeGeneratorTask(Compiler compiler) : super(compiler); |
| 7 String get name() => 'SSA code generator'; | 7 String get name() => 'SSA code generator'; |
| 8 | 8 |
| 9 String generate(WorkItem work, HGraph graph) { | 9 String generate(WorkItem work, HGraph graph) { |
| 10 return measure(() { | 10 return measure(() { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 94 final Map<Element, String> parameterNames; | 94 final Map<Element, String> parameterNames; |
| 95 final Map<int, String> names; | 95 final Map<int, String> names; |
| 96 final Map<String, int> prefixes; | 96 final Map<String, int> prefixes; |
| 97 | 97 |
| 98 Element equalsNullElement; | 98 Element equalsNullElement; |
| 99 int indent = 0; | 99 int indent = 0; |
| 100 int expectedPrecedence = JSPrecedence.STATEMENT_PRECEDENCE; | 100 int expectedPrecedence = JSPrecedence.STATEMENT_PRECEDENCE; |
| 101 HGraph currentGraph; | 101 HGraph currentGraph; |
| 102 HBasicBlock currentBlock; | 102 HBasicBlock currentBlock; |
| 103 | 103 |
| 104 // Records a block-information that is being handled specially. | |
| 105 // Used to break bad recursion. | |
|
ngeoffray
2012/03/06 11:17:37
What's a bad recursion?
Lasse Reichstein Nielsen
2012/03/08 09:02:02
Infinite recursion, recursing on the same input ag
| |
| 106 HLabeledBlockInformation currentBlockInformation; | |
| 107 // The subgraph is used to delimit traversal for some constructions, e.g., | |
| 108 // if branches. | |
| 104 SubGraph subGraph; | 109 SubGraph subGraph; |
| 105 | 110 |
| 106 SsaCodeGenerator(this.compiler, | 111 SsaCodeGenerator(this.compiler, |
| 107 this.work, | 112 this.work, |
| 108 this.buffer, | 113 this.buffer, |
| 109 this.parameters, | 114 this.parameters, |
| 110 this.parameterNames) | 115 this.parameterNames) |
| 111 : names = new Map<int, String>(), | 116 : names = new Map<int, String>(), |
| 112 prefixes = new Map<String, int>() { | 117 prefixes = new Map<String, int>() { |
| 113 for (final name in parameterNames.getValues()) { | 118 for (final name in parameterNames.getValues()) { |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 226 } | 231 } |
| 227 } | 232 } |
| 228 | 233 |
| 229 visit(HInstruction node, int expectedPrecedence) { | 234 visit(HInstruction node, int expectedPrecedence) { |
| 230 int oldPrecedence = this.expectedPrecedence; | 235 int oldPrecedence = this.expectedPrecedence; |
| 231 this.expectedPrecedence = expectedPrecedence; | 236 this.expectedPrecedence = expectedPrecedence; |
| 232 node.accept(this); | 237 node.accept(this); |
| 233 this.expectedPrecedence = oldPrecedence; | 238 this.expectedPrecedence = oldPrecedence; |
| 234 } | 239 } |
| 235 | 240 |
| 236 void handleLabeledBlock(HBasicBlock node) { | 241 void handleLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { |
| 237 HLabeledBlockInformation labeledBlockInfo = node.labeledBlockInformation; | 242 addIndentation(); |
| 238 if (labeledBlockInfo.start === node) { | 243 for (SourceString label in labeledBlockInfo.labels) { |
| 239 addIndentation(); | 244 addLabel(label); |
| 240 for (SourceString label in labeledBlockInfo.labels) { | 245 buffer.add(":"); |
| 241 addLabel(label); | |
| 242 buffer.add(":"); | |
| 243 } | |
| 244 buffer.add("{\n"); | |
| 245 indent++; | |
| 246 } else { | |
| 247 assert(labeledBlockInfo.end === node); | |
| 248 assert((){ | |
| 249 // Check that this block is (transitively) dominated by the start block. | |
| 250 HBasicBlock block = node; | |
| 251 while (block.dominator !== null) { | |
| 252 block = block.dominator; | |
| 253 if (block === labeledBlockInfo.start) return true; | |
| 254 } | |
| 255 return false; | |
| 256 }); | |
| 257 indent--; | |
| 258 addIndentation(); | |
| 259 buffer.add("}\n"); | |
| 260 } | 246 } |
| 247 buffer.add("{\n"); | |
| 248 indent++; | |
| 249 | |
| 250 visitSubGraph(labeledBlockInfo.body); | |
| 251 | |
| 252 indent--; | |
| 253 addIndentation(); | |
| 254 buffer.add("}\n"); | |
| 255 | |
| 256 visitBasicBlock(labeledBlockInfo.joinBlock); | |
| 261 } | 257 } |
| 262 | 258 |
| 263 | 259 |
| 264 visitBasicBlock(HBasicBlock node) { | 260 visitBasicBlock(HBasicBlock node) { |
| 261 // Abort traversal if we are leaving the currently active sub-graph. | |
| 265 if (!subGraph.contains(node)) return; | 262 if (!subGraph.contains(node)) return; |
| 266 | 263 |
| 264 // If this node has special behavior attached, handle it. | |
| 265 // If we reach here again while handling the attached information, | |
| 266 // e.g., because we call visitSubGraph on a subgraph starting here, | |
| 267 // don't handle it again. | |
|
ngeoffray
2012/03/06 11:17:37
How can you end up doing this? Should we re-design
Lasse Reichstein Nielsen
2012/03/08 09:02:02
For a labeled expression, the "HLabeledBlockInform
| |
| 268 if (node.hasLabeledBlockInformation() && | |
| 269 node.labeledBlockInformation !== currentBlockInformation) { | |
| 270 HLabeledBlockInformation oldBlockInformation = currentBlockInformation; | |
| 271 currentBlockInformation = node.labeledBlockInformation; | |
| 272 handleLabeledBlock(currentBlockInformation); | |
| 273 currentBlockInformation = oldBlockInformation; | |
| 274 return; | |
| 275 } | |
| 276 | |
| 267 currentBlock = node; | 277 currentBlock = node; |
| 268 | 278 if (node.isLoopHeader()) { |
| 269 if (node.hasLabeledBlockInformation()) { | |
| 270 handleLabeledBlock(node); | |
| 271 } else if (currentBlock.isLoopHeader()) { | |
| 272 // While loop will be closed by the conditional loop-branch. | 279 // While loop will be closed by the conditional loop-branch. |
| 273 // TODO(floitsch): HACK HACK HACK. | 280 // TODO(floitsch): HACK HACK HACK. |
| 274 beginLoop(node); | 281 beginLoop(node); |
| 275 } | 282 } |
| 276 | |
| 277 HInstruction instruction = node.first; | 283 HInstruction instruction = node.first; |
| 278 while (instruction != null) { | 284 while (instruction != null) { |
| 279 if (instruction is HGoto || instruction is HExit || instruction is HTry) { | 285 if (instruction is HGoto || instruction is HExit || instruction is HTry) { |
| 280 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); | 286 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); |
| 281 return; | 287 return; |
| 282 } else if (!instruction.generateAtUseSite()) { | 288 } else if (!instruction.generateAtUseSite()) { |
| 283 if (instruction is !HIf && instruction is !HBailoutTarget) { | 289 if (instruction is !HIf && instruction is !HBailoutTarget) { |
| 284 addIndentation(); | 290 addIndentation(); |
| 285 } | 291 } |
| 286 if (instruction.usedBy.isEmpty() || instruction is HLocal) { | 292 if (instruction.usedBy.isEmpty() || instruction is HLocal) { |
| (...skipping 1108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1395 startBailoutSwitch(); | 1401 startBailoutSwitch(); |
| 1396 } | 1402 } |
| 1397 } | 1403 } |
| 1398 | 1404 |
| 1399 void endElse(HIf node) { | 1405 void endElse(HIf node) { |
| 1400 if (node.elseBlock.hasBailouts()) { | 1406 if (node.elseBlock.hasBailouts()) { |
| 1401 endBailoutSwitch(); | 1407 endBailoutSwitch(); |
| 1402 } | 1408 } |
| 1403 } | 1409 } |
| 1404 } | 1410 } |
| OLD | NEW |