| 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 | 9 |
| 10 String buildJavaScriptFunction(FunctionElement element, | 10 String buildJavaScriptFunction(FunctionElement element, |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 static final String TEMPORARY_PREFIX = 't'; | 138 static final String TEMPORARY_PREFIX = 't'; |
| 139 | 139 |
| 140 final Compiler compiler; | 140 final Compiler compiler; |
| 141 final WorkItem work; | 141 final WorkItem work; |
| 142 final StringBuffer buffer; | 142 final StringBuffer buffer; |
| 143 final String parameters; | 143 final String parameters; |
| 144 | 144 |
| 145 final Map<Element, String> parameterNames; | 145 final Map<Element, String> parameterNames; |
| 146 final Map<int, String> names; | 146 final Map<int, String> names; |
| 147 final Set<String> usedNames; | 147 final Set<String> usedNames; |
| 148 final Set<HInstruction> declaredInstructions; |
| 148 final Map<String, int> prefixes; | 149 final Map<String, int> prefixes; |
| 149 final Set<HInstruction> generateAtUseSite; | 150 final Set<HInstruction> generateAtUseSite; |
| 150 final Map<HPhi, String> logicalOperations; | 151 final Map<HPhi, String> logicalOperations; |
| 151 final Map<Element, ElementAction> breakAction; | 152 final Map<Element, ElementAction> breakAction; |
| 152 final Map<Element, ElementAction> continueAction; | 153 final Map<Element, ElementAction> continueAction; |
| 153 final Equivalence<HPhi> phiEquivalence; | 154 final Equivalence<HPhi> phiEquivalence; |
| 154 | 155 |
| 155 Element equalsNullElement; | 156 Element equalsNullElement; |
| 156 Element boolifiedEqualsNullElement; | 157 Element boolifiedEqualsNullElement; |
| 157 int indent = 0; | 158 int indent = 0; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 183 return generateAtUseSite.contains(instruction); | 184 return generateAtUseSite.contains(instruction); |
| 184 } | 185 } |
| 185 | 186 |
| 186 SsaCodeGenerator(this.compiler, | 187 SsaCodeGenerator(this.compiler, |
| 187 this.work, | 188 this.work, |
| 188 this.parameters, | 189 this.parameters, |
| 189 this.parameterNames) | 190 this.parameterNames) |
| 190 : names = new Map<int, String>(), | 191 : names = new Map<int, String>(), |
| 191 prefixes = new Map<String, int>(), | 192 prefixes = new Map<String, int>(), |
| 192 usedNames = new Set<String>(), | 193 usedNames = new Set<String>(), |
| 194 declaredInstructions = new Set<HInstruction>(), |
| 193 buffer = new StringBuffer(), | 195 buffer = new StringBuffer(), |
| 194 generateAtUseSite = new Set<HInstruction>(), | 196 generateAtUseSite = new Set<HInstruction>(), |
| 195 logicalOperations = new Map<HPhi, String>(), | 197 logicalOperations = new Map<HPhi, String>(), |
| 196 breakAction = new Map<Element, ElementAction>(), | 198 breakAction = new Map<Element, ElementAction>(), |
| 197 continueAction = new Map<Element, ElementAction>(), | 199 continueAction = new Map<Element, ElementAction>(), |
| 198 phiEquivalence = new Equivalence<HPhi>(), | 200 phiEquivalence = new Equivalence<HPhi>(), |
| 199 unsignedShiftPrecedences = JSPrecedence.binary['>>>'] { | 201 unsignedShiftPrecedences = JSPrecedence.binary['>>>'] { |
| 200 | 202 |
| 201 for (final name in parameterNames.getValues()) { | 203 for (final name in parameterNames.getValues()) { |
| 202 prefixes[name] = 0; | 204 prefixes[name] = 0; |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 String prefix = TEMPORARY_PREFIX; | 444 String prefix = TEMPORARY_PREFIX; |
| 443 String name = '${prefix}${prefixes[prefix]++}'; | 445 String name = '${prefix}${prefixes[prefix]++}'; |
| 444 while (usedNames.contains(name)) { | 446 while (usedNames.contains(name)) { |
| 445 name = '${prefix}${prefixes[prefix]++}'; | 447 name = '${prefix}${prefixes[prefix]++}'; |
| 446 } | 448 } |
| 447 String result = JsNames.getValid(name); | 449 String result = JsNames.getValid(name); |
| 448 usedNames.add(result); | 450 usedNames.add(result); |
| 449 return result; | 451 return result; |
| 450 } | 452 } |
| 451 | 453 |
| 452 bool temporaryExists(HInstruction instruction) { | |
| 453 return names.containsKey(instruction.id); | |
| 454 } | |
| 455 | |
| 456 String newName(int id, String name) { | 454 String newName(int id, String name) { |
| 457 String result = JsNames.getValid(name); | 455 String result = JsNames.getValid(name); |
| 458 names[id] = result; | 456 names[id] = result; |
| 459 usedNames.add(result); | 457 usedNames.add(result); |
| 460 return result; | 458 return result; |
| 461 } | 459 } |
| 462 | 460 |
| 463 /** | 461 /** |
| 464 * Only visits the arguments starting at inputs[HInvoke.ARGUMENTS_OFFSET]. | 462 * Only visits the arguments starting at inputs[HInvoke.ARGUMENTS_OFFSET]. |
| 465 */ | 463 */ |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 buffer.add(variableName); | 507 buffer.add(variableName); |
| 510 if (!isGeneratingDeclaration()) { | 508 if (!isGeneratingDeclaration()) { |
| 511 delayedVarDecl = delayedVarDecl.prepend(variableName); | 509 delayedVarDecl = delayedVarDecl.prepend(variableName); |
| 512 } | 510 } |
| 513 } else { | 511 } else { |
| 514 buffer.add("var "); | 512 buffer.add("var "); |
| 515 buffer.add(variableName); | 513 buffer.add(variableName); |
| 516 } | 514 } |
| 517 } | 515 } |
| 518 | 516 |
| 517 void declareInstruction(HInstruction instruction) { |
| 518 declaredInstructions.add(instruction); |
| 519 String name = temporary(instruction); |
| 520 declareVariable(name); |
| 521 } |
| 522 |
| 519 bool needsNewVariable(HInstruction instruction) { | 523 bool needsNewVariable(HInstruction instruction) { |
| 520 bool needsVar = !instruction.usedBy.isEmpty(); | 524 bool needsVar = !instruction.usedBy.isEmpty(); |
| 521 if (needsVar && instruction is HCheck) { | 525 if (needsVar && instruction is HCheck) { |
| 522 HCheck check = instruction; | 526 HCheck check = instruction; |
| 523 HInstruction input = check.checkedInput; | 527 HInstruction input = check.checkedInput; |
| 524 // We only need a new var if [input] is generated at use site | 528 // We only need a new var if [input] is generated at use site |
| 525 // but is not a trivial code motion invariant instruction like | 529 // but is not a trivial code motion invariant instruction like |
| 526 // for parameters or this. | 530 // for parameters or this. |
| 527 // | 531 // |
| 528 // For example: | 532 // For example: |
| (...skipping 15 matching lines...) Expand all Loading... |
| 544 // var a = FooTypeCheck(foo()); | 548 // var a = FooTypeCheck(foo()); |
| 545 // print(a); | 549 // print(a); |
| 546 // print(a); | 550 // print(a); |
| 547 needsVar = isGenerateAtUseSite(input) && !input.isCodeMotionInvariant(); | 551 needsVar = isGenerateAtUseSite(input) && !input.isCodeMotionInvariant(); |
| 548 } | 552 } |
| 549 return needsVar; | 553 return needsVar; |
| 550 } | 554 } |
| 551 | 555 |
| 552 void define(HInstruction instruction) { | 556 void define(HInstruction instruction) { |
| 553 if (needsNewVariable(instruction)) { | 557 if (needsNewVariable(instruction)) { |
| 554 String name = temporary(instruction); | 558 declareInstruction(instruction); |
| 555 declareVariable(name); | |
| 556 buffer.add(" = "); | 559 buffer.add(" = "); |
| 557 visit(instruction, JSPrecedence.ASSIGNMENT_PRECEDENCE); | 560 visit(instruction, JSPrecedence.ASSIGNMENT_PRECEDENCE); |
| 558 } else { | 561 } else { |
| 559 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); | 562 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); |
| 560 } | 563 } |
| 561 } | 564 } |
| 562 | 565 |
| 563 void use(HInstruction argument, int expectedPrecedenceForArgument) { | 566 void use(HInstruction argument, int expectedPrecedenceForArgument) { |
| 564 if (argument is HCheck) { | 567 if (argument is HCheck) { |
| 565 HCheck instruction = argument; | 568 HCheck instruction = argument; |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1023 if (isGeneratingExpression()) { | 1026 if (isGeneratingExpression()) { |
| 1024 addExpressionSeparator(); | 1027 addExpressionSeparator(); |
| 1025 } else { | 1028 } else { |
| 1026 addIndentation(); | 1029 addIndentation(); |
| 1027 } | 1030 } |
| 1028 if (temporaryNamesOfPhis !== null && | 1031 if (temporaryNamesOfPhis !== null && |
| 1029 canonicalPhi !== value && | 1032 canonicalPhi !== value && |
| 1030 temporaryNamesOfPhis.containsKey(canonicalPhi)) { | 1033 temporaryNamesOfPhis.containsKey(canonicalPhi)) { |
| 1031 // This is the assignment to the temporary. | 1034 // This is the assignment to the temporary. |
| 1032 declareVariable(temporaryNamesOfPhis[canonicalPhi]); | 1035 declareVariable(temporaryNamesOfPhis[canonicalPhi]); |
| 1033 } else if (!temporaryExists(canonicalPhi)) { | 1036 } else if (!declaredInstructions.contains(canonicalPhi)) { |
| 1034 declareVariable(temporary(canonicalPhi)); | 1037 declareInstruction(canonicalPhi); |
| 1035 } else { | 1038 } else { |
| 1036 buffer.add(temporary(canonicalPhi)); | 1039 buffer.add(temporary(canonicalPhi)); |
| 1037 } | 1040 } |
| 1038 buffer.add(" = "); | 1041 buffer.add(" = "); |
| 1039 bool isLogicalOperation = logicalOperations.containsKey(canonicalPhi); | 1042 bool isLogicalOperation = logicalOperations.containsKey(canonicalPhi); |
| 1040 if (isLogicalOperation) { | 1043 if (isLogicalOperation) { |
| 1041 emitLogicalOperation(canonicalPhi, logicalOperations[canonicalPhi]); | 1044 emitLogicalOperation(canonicalPhi, logicalOperations[canonicalPhi]); |
| 1042 } else if (canonicalPhi === value) { | 1045 } else if (canonicalPhi === value) { |
| 1043 buffer.add(temporaryNamesOfPhis[value]); | 1046 buffer.add(temporaryNamesOfPhis[value]); |
| 1044 } else { | 1047 } else { |
| (...skipping 1553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2598 startBailoutSwitch(); | 2601 startBailoutSwitch(); |
| 2599 } | 2602 } |
| 2600 } | 2603 } |
| 2601 | 2604 |
| 2602 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { | 2605 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { |
| 2603 if (labeledBlockInfo.body.start.hasGuards()) { | 2606 if (labeledBlockInfo.body.start.hasGuards()) { |
| 2604 endBailoutSwitch(); | 2607 endBailoutSwitch(); |
| 2605 } | 2608 } |
| 2606 } | 2609 } |
| 2607 } | 2610 } |
| OLD | NEW |