| 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 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 declaredVariables.add(variableName); | 468 declaredVariables.add(variableName); |
| 469 buffer.add("var "); | 469 buffer.add("var "); |
| 470 generationState = STATE_DECLARATION; | 470 generationState = STATE_DECLARATION; |
| 471 } else { | 471 } else { |
| 472 generationState = STATE_EXPRESSION; | 472 generationState = STATE_EXPRESSION; |
| 473 } | 473 } |
| 474 | 474 |
| 475 } else if (!isVariableDeclared(variableName)) { | 475 } else if (!isVariableDeclared(variableName)) { |
| 476 if (!isGeneratingDeclaration()) { | 476 if (!isGeneratingDeclaration()) { |
| 477 delayedVariableDeclarations.add(variableName); | 477 delayedVariableDeclarations.add(variableName); |
| 478 } else { | |
| 479 declaredVariables.add(variableName); | |
| 480 } | 478 } |
| 479 // No matter if we are declaring the variable now or if we are |
| 480 // delaying the declaration we can treat the variable as |
| 481 // being declared from this point on. |
| 482 declaredVariables.add(variableName); |
| 481 } | 483 } |
| 482 } else if (!isVariableDeclared(variableName)) { | 484 } else if (!isVariableDeclared(variableName)) { |
| 483 declaredVariables.add(variableName); | 485 declaredVariables.add(variableName); |
| 484 buffer.add("var "); | 486 buffer.add("var "); |
| 485 } | 487 } |
| 486 buffer.add(variableName); | 488 buffer.add(variableName); |
| 487 } | 489 } |
| 488 | 490 |
| 489 void declareInstruction(HInstruction instruction) { | 491 void declareInstruction(HInstruction instruction) { |
| 490 declareVariable(variableNames.getName(instruction)); | 492 declareVariable(variableNames.getName(instruction)); |
| 491 } | 493 } |
| 492 | 494 |
| 495 // For simple updates of the form 'i = i op constant' generate |
| 496 // 'i op= constant' instead. |
| 497 bool handleSimpleUpdateDefinition(HInstruction instruction, String name) { |
| 498 // If the variable is not declared the short update syntax cannot |
| 499 // be used since it is a declaration and not an update. |
| 500 if (!isVariableDeclared(name)) return false; |
| 501 |
| 502 // Check that the operation is one of +, *, - or /. Record whether |
| 503 // or not the operation is commutative. |
| 504 var isCommutative = false; |
| 505 if (instruction is HAdd || instruction is HMultiply) { |
| 506 isCommutative = true; |
| 507 } else if (instruction is !HSubtract && instruction is !HDivide) { |
| 508 return false; |
| 509 } |
| 510 |
| 511 // Is it a builtin operation involving constant numbers? |
| 512 if (instruction.builtin && instruction.inputs.length == 3) { |
| 513 var left = instruction.inputs[1]; |
| 514 var right = instruction.inputs[2]; |
| 515 if (left.isConstantNumber() && isCommutative) { |
| 516 var tmp = right; |
| 517 right = left; |
| 518 left = tmp; |
| 519 } else if (!right.isConstantNumber()) { |
| 520 return false; |
| 521 } |
| 522 // Right is constant number. |
| 523 var value = right.constant.value; |
| 524 // Check that left has the same name as the definition and emit |
| 525 // the short update definition if it is. |
| 526 if (variableNames.getName(left) == name) { |
| 527 if (instruction is HAdd && right.constant.value == 1) { |
| 528 buffer.add('++'); |
| 529 declareInstruction(instruction); |
| 530 } else if (instruction is HSubtract && right.constant.value == 1) { |
| 531 buffer.add('--'); |
| 532 declareInstruction(instruction); |
| 533 } else { |
| 534 var operation = instruction.operation.name; |
| 535 declareInstruction(instruction); |
| 536 buffer.add(' ${operation}= ${value}'); |
| 537 } |
| 538 return true; |
| 539 } |
| 540 } |
| 541 return false; |
| 542 } |
| 543 |
| 493 void define(HInstruction instruction) { | 544 void define(HInstruction instruction) { |
| 494 if (isGeneratingExpression()) { | 545 if (isGeneratingExpression()) { |
| 495 addExpressionSeparator(); | 546 addExpressionSeparator(); |
| 496 } else { | 547 } else { |
| 497 addIndentation(); | 548 addIndentation(); |
| 498 } | 549 } |
| 499 if (instruction is !HCheck && variableNames.hasName(instruction)) { | 550 if (instruction is !HCheck && variableNames.hasName(instruction)) { |
| 500 declareInstruction(instruction); | 551 var name = variableNames.getName(instruction); |
| 501 buffer.add(" = "); | 552 if (!handleSimpleUpdateDefinition(instruction, name)) { |
| 502 visit(instruction, JSPrecedence.ASSIGNMENT_PRECEDENCE); | 553 declareInstruction(instruction); |
| 554 buffer.add(" = "); |
| 555 visit(instruction, JSPrecedence.ASSIGNMENT_PRECEDENCE); |
| 556 } |
| 503 } else { | 557 } else { |
| 504 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); | 558 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); |
| 505 } | 559 } |
| 506 if (!isGeneratingExpression()) buffer.add(';\n'); | 560 if (!isGeneratingExpression()) buffer.add(';\n'); |
| 507 } | 561 } |
| 508 | 562 |
| 509 void use(HInstruction argument, int expectedPrecedenceForArgument) { | 563 void use(HInstruction argument, int expectedPrecedenceForArgument) { |
| 510 if (isGenerateAtUseSite(argument)) { | 564 if (isGenerateAtUseSite(argument)) { |
| 511 visit(argument, expectedPrecedenceForArgument); | 565 visit(argument, expectedPrecedenceForArgument); |
| 512 } else if (argument is HCheck) { | 566 } else if (argument is HCheck) { |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 890 } | 944 } |
| 891 // Flow based traversal. | 945 // Flow based traversal. |
| 892 if (node.isLoopHeader() && | 946 if (node.isLoopHeader() && |
| 893 node.loopInformation.loopBlockInformation !== currentBlockInformation) { | 947 node.loopInformation.loopBlockInformation !== currentBlockInformation) { |
| 894 beginLoop(node); | 948 beginLoop(node); |
| 895 } | 949 } |
| 896 iterateBasicBlock(node); | 950 iterateBasicBlock(node); |
| 897 } | 951 } |
| 898 | 952 |
| 899 void emitAssignment(String destination, String source) { | 953 void emitAssignment(String destination, String source) { |
| 900 if (isGeneratingExpression()) { | 954 if (isGeneratingExpression()) { |
| 901 addExpressionSeparator(); | 955 addExpressionSeparator(); |
| 902 } else { | 956 } else { |
| 903 addIndentation(); | 957 addIndentation(); |
| 904 } | 958 } |
| 905 declareVariable(destination); | 959 declareVariable(destination); |
| 906 buffer.add(' = $source'); | 960 buffer.add(' = $source'); |
| 907 if (!isGeneratingExpression()) { | 961 if (!isGeneratingExpression()) { |
| 908 buffer.add(';\n'); | 962 buffer.add(';\n'); |
| 909 } | 963 } |
| 910 } | 964 } |
| (...skipping 1610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2521 startBailoutSwitch(); | 2575 startBailoutSwitch(); |
| 2522 } | 2576 } |
| 2523 } | 2577 } |
| 2524 | 2578 |
| 2525 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { | 2579 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { |
| 2526 if (labeledBlockInfo.body.start.hasGuards()) { | 2580 if (labeledBlockInfo.body.start.hasGuards()) { |
| 2527 endBailoutSwitch(); | 2581 endBailoutSwitch(); |
| 2528 } | 2582 } |
| 2529 } | 2583 } |
| 2530 } | 2584 } |
| OLD | NEW |