| 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, because the intTypeCheck just returns its | 
 |   546   // argument. | 
 |   547   bool handleTypeConversion(instruction, name) { | 
 |   548     if (instruction is !HTypeConversion) return false; | 
 |   549     String inputName = variableNames.getName(instruction.checkedInput); | 
 |   550     if (name != inputName) return false; | 
 |   551     visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); | 
 |   552     return true; | 
 |   553   } | 
 |   554  | 
|   544   void define(HInstruction instruction) { |   555   void define(HInstruction instruction) { | 
|   545     if (isGeneratingExpression()) { |   556     if (isGeneratingExpression()) { | 
|   546       addExpressionSeparator(); |   557       addExpressionSeparator(); | 
|   547     } else { |   558     } else { | 
|   548       addIndentation(); |   559       addIndentation(); | 
|   549     } |   560     } | 
|   550     if (instruction is !HCheck && variableNames.hasName(instruction)) { |   561     if (!instruction.isControlFlow() && variableNames.hasName(instruction)) { | 
|   551       var name = variableNames.getName(instruction); |   562       var name = variableNames.getName(instruction); | 
|   552       if (!handleSimpleUpdateDefinition(instruction, name)) { |   563       if (!handleSimpleUpdateDefinition(instruction, name) | 
 |   564           && !handleTypeConversion(instruction, name)) { | 
|   553         declareInstruction(instruction); |   565         declareInstruction(instruction); | 
|   554         buffer.add(" = "); |   566         buffer.add(" = "); | 
|   555         visit(instruction, JSPrecedence.ASSIGNMENT_PRECEDENCE); |   567         visit(instruction, JSPrecedence.ASSIGNMENT_PRECEDENCE); | 
|   556       } |   568       } | 
|   557     } else { |   569     } else { | 
|   558       visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); |   570       visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); | 
|   559     } |   571     } | 
|   560     if (!isGeneratingExpression()) buffer.add(';\n'); |   572     if (!isGeneratingExpression()) buffer.add(';\n'); | 
|   561   } |   573   } | 
|   562  |   574  | 
|   563   void use(HInstruction argument, int expectedPrecedenceForArgument) { |   575   void use(HInstruction argument, int expectedPrecedenceForArgument) { | 
|   564     if (isGenerateAtUseSite(argument)) { |   576     if (isGenerateAtUseSite(argument)) { | 
|   565       visit(argument, expectedPrecedenceForArgument); |   577       visit(argument, expectedPrecedenceForArgument); | 
|   566     } else if (argument is HCheck) { |   578     } else if (argument is HCheck && argument.isControlFlow()) { | 
 |   579       // A [HCheck] that has control flow can never be used as an | 
 |   580       // expression and may not have a name. Therefore we just use the | 
 |   581       // checked instruction. | 
|   567       HCheck check = argument; |   582       HCheck check = argument; | 
|   568       use(argument.checkedInput, expectedPrecedenceForArgument); |   583       use(check.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); | 
|   578     this.expectedPrecedence = oldPrecedence; |   593     this.expectedPrecedence = oldPrecedence; | 
| (...skipping 1911 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 |