| 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 final JavaScriptBackend backend; | 6 final JavaScriptBackend backend; |
| 7 SsaCodeGeneratorTask(JavaScriptBackend backend) | 7 SsaCodeGeneratorTask(JavaScriptBackend backend) |
| 8 : this.backend = backend, | 8 : this.backend = backend, |
| 9 super(backend.compiler); | 9 super(backend.compiler); |
| 10 String get name() => 'SSA code generator'; | 10 String get name() => 'SSA code generator'; |
| (...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 var operation = instruction.operation.name; | 534 var operation = instruction.operation.name; |
| 535 declareInstruction(instruction); | 535 declareInstruction(instruction); |
| 536 buffer.add(' ${operation}= ${value}'); | 536 buffer.add(' ${operation}= ${value}'); |
| 537 } | 537 } |
| 538 return true; | 538 return true; |
| 539 } | 539 } |
| 540 } | 540 } |
| 541 return false; | 541 return false; |
| 542 } | 542 } |
| 543 | 543 |
| 544 // For simple type checks like i = intTypeCheck(i), we don't have to |
| 545 // emit an assignment. |
| 546 bool handleTypeConversion(instruction, name) { |
| 547 if (instruction is !HTypeConversion) return false; |
| 548 String inputName = variableNames.getName(instruction.checkedInput); |
| 549 if (name != inputName) return false; |
| 550 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); |
| 551 return true; |
| 552 } |
| 553 |
| 544 void define(HInstruction instruction) { | 554 void define(HInstruction instruction) { |
| 545 if (isGeneratingExpression()) { | 555 if (isGeneratingExpression()) { |
| 546 addExpressionSeparator(); | 556 addExpressionSeparator(); |
| 547 } else { | 557 } else { |
| 548 addIndentation(); | 558 addIndentation(); |
| 549 } | 559 } |
| 550 if (instruction is !HCheck && variableNames.hasName(instruction)) { | 560 if (instruction is !HCheckStatement && variableNames.hasName(instruction)) { |
| 551 var name = variableNames.getName(instruction); | 561 var name = variableNames.getName(instruction); |
| 552 if (!handleSimpleUpdateDefinition(instruction, name)) { | 562 if (!handleSimpleUpdateDefinition(instruction, name) |
| 563 && !handleTypeConversion(instruction, name)) { |
| 553 declareInstruction(instruction); | 564 declareInstruction(instruction); |
| 554 buffer.add(" = "); | 565 buffer.add(" = "); |
| 555 visit(instruction, JSPrecedence.ASSIGNMENT_PRECEDENCE); | 566 visit(instruction, JSPrecedence.ASSIGNMENT_PRECEDENCE); |
| 556 } | 567 } |
| 557 } else { | 568 } else { |
| 558 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); | 569 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); |
| 559 } | 570 } |
| 560 if (!isGeneratingExpression()) buffer.add(';\n'); | 571 if (!isGeneratingExpression()) buffer.add(';\n'); |
| 561 } | 572 } |
| 562 | 573 |
| 563 void use(HInstruction argument, int expectedPrecedenceForArgument) { | 574 void use(HInstruction argument, int expectedPrecedenceForArgument) { |
| 564 if (isGenerateAtUseSite(argument)) { | 575 if (isGenerateAtUseSite(argument)) { |
| 565 visit(argument, expectedPrecedenceForArgument); | 576 visit(argument, expectedPrecedenceForArgument); |
| 566 } else if (argument is HCheck) { | 577 } else if (argument is HCheckStatement) { |
| 578 // A [HCheckStatement] instruction can never be used as an |
| 579 // expression and may not have a name. Therefore we just use the |
| 580 // checked instruction. |
| 567 HCheck check = argument; | 581 HCheck check = argument; |
| 582 HInstruction checkedInput = argument.checkedInput; |
| 568 use(argument.checkedInput, expectedPrecedenceForArgument); | 583 use(argument.checkedInput, expectedPrecedenceForArgument); |
| 569 } else { | 584 } else { |
| 570 buffer.add(variableNames.getName(argument)); | 585 buffer.add(variableNames.getName(argument)); |
| 571 } | 586 } |
| 572 } | 587 } |
| 573 | 588 |
| 574 visit(HInstruction node, int expectedPrecedenceForNode) { | 589 visit(HInstruction node, int expectedPrecedenceForNode) { |
| 575 int oldPrecedence = this.expectedPrecedence; | 590 int oldPrecedence = this.expectedPrecedence; |
| 576 this.expectedPrecedence = expectedPrecedenceForNode; | 591 this.expectedPrecedence = expectedPrecedenceForNode; |
| 577 node.accept(this); | 592 node.accept(this); |
| (...skipping 1912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2490 } | 2505 } |
| 2491 | 2506 |
| 2492 void endGraph(HGraph graph) { | 2507 void endGraph(HGraph graph) { |
| 2493 if (!graph.entry.hasGuards()) return; | 2508 if (!graph.entry.hasGuards()) return; |
| 2494 indent--; // Close original case. | 2509 indent--; // Close original case. |
| 2495 indent--; | 2510 indent--; |
| 2496 addIndented('}\n'); // Close 'switch'. | 2511 addIndented('}\n'); // Close 'switch'. |
| 2497 setup.add(' }\n'); | 2512 setup.add(' }\n'); |
| 2498 } | 2513 } |
| 2499 | 2514 |
| 2500 // For instructions that reference a guard or a check, we change that | |
| 2501 // reference to the instruction they guard against. Therefore, we must | |
| 2502 // use that instruction when restoring the environment. | |
| 2503 HInstruction unwrap(argument) { | |
| 2504 while (argument is HCheck) argument = argument.checkedInput; | |
| 2505 return argument; | |
| 2506 } | |
| 2507 | |
| 2508 bool visitAndOrInfo(HAndOrBlockInformation info) => false; | 2515 bool visitAndOrInfo(HAndOrBlockInformation info) => false; |
| 2509 bool visitIfInfo(HIfBlockInformation info) => false; | 2516 bool visitIfInfo(HIfBlockInformation info) => false; |
| 2510 bool visitLoopInfo(HLoopBlockInformation info) => false; | 2517 bool visitLoopInfo(HLoopBlockInformation info) => false; |
| 2511 bool visitTryInfo(HTryBlockInformation info) => false; | 2518 bool visitTryInfo(HTryBlockInformation info) => false; |
| 2512 bool visitSequenceInfo(HStatementSequenceInformation info) => false; | 2519 bool visitSequenceInfo(HStatementSequenceInformation info) => false; |
| 2513 | 2520 |
| 2514 void visitTypeGuard(HTypeGuard node) { | 2521 void visitTypeGuard(HTypeGuard node) { |
| 2515 indent--; | 2522 indent--; |
| 2516 addIndented('case ${node.state}:\n'); | 2523 addIndented('case ${node.state}:\n'); |
| 2517 indent++; | 2524 indent++; |
| 2518 addIndented('state = 0;\n'); | 2525 addIndented('state = 0;\n'); |
| 2519 | 2526 |
| 2520 setup.add(' case ${node.state}:\n'); | 2527 setup.add(' case ${node.state}:\n'); |
| 2521 int i = 0; | 2528 int i = 0; |
| 2522 for (HInstruction input in node.inputs) { | 2529 for (HInstruction input in node.inputs) { |
| 2523 HInstruction instruction = unwrap(input); | 2530 setup.add(' ${variableNames.getName(input)} = env$i;\n'); |
| 2524 setup.add(' ${variableNames.getName(instruction)} = env$i;\n'); | |
| 2525 i++; | 2531 i++; |
| 2526 } | 2532 } |
| 2527 if (i > maxBailoutParameters) maxBailoutParameters = i; | 2533 if (i > maxBailoutParameters) maxBailoutParameters = i; |
| 2528 setup.add(' break;\n'); | 2534 setup.add(' break;\n'); |
| 2529 } | 2535 } |
| 2530 | 2536 |
| 2531 void startBailoutCase(List<HTypeGuard> bailouts1, | 2537 void startBailoutCase(List<HTypeGuard> bailouts1, |
| 2532 List<HTypeGuard> bailouts2) { | 2538 List<HTypeGuard> bailouts2) { |
| 2533 indent--; | 2539 indent--; |
| 2534 handleBailoutCase(bailouts1); | 2540 handleBailoutCase(bailouts1); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2673 startBailoutSwitch(); | 2679 startBailoutSwitch(); |
| 2674 } | 2680 } |
| 2675 } | 2681 } |
| 2676 | 2682 |
| 2677 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { | 2683 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { |
| 2678 if (labeledBlockInfo.body.start.hasGuards()) { | 2684 if (labeledBlockInfo.body.start.hasGuards()) { |
| 2679 endBailoutSwitch(); | 2685 endBailoutSwitch(); |
| 2680 } | 2686 } |
| 2681 } | 2687 } |
| 2682 } | 2688 } |
| OLD | NEW |