| 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 interface OptimizationPhase { |     5 interface OptimizationPhase { | 
|     6   String get name(); |     6   String get name(); | 
|     7   void visitGraph(HGraph graph); |     7   void visitGraph(HGraph graph); | 
|     8 } |     8 } | 
|     9  |     9  | 
|    10 class SsaOptimizerTask extends CompilerTask { |    10 class SsaOptimizerTask extends CompilerTask { | 
|    11   final JavaScriptBackend backend; |    11   final JavaScriptBackend backend; | 
|    12   SsaOptimizerTask(JavaScriptBackend backend) |    12   SsaOptimizerTask(JavaScriptBackend backend) | 
|    13     : this.backend = backend, |    13     : this.backend = backend, | 
|    14       super(backend.compiler); |    14       super(backend.compiler); | 
|    15   String get name() => 'SSA optimizer'; |    15   String get name() => 'SSA optimizer'; | 
|    16   Compiler get compiler() => backend.compiler; |    16   Compiler get compiler() => backend.compiler; | 
|    17  |    17  | 
|    18   void runPhases(HGraph graph, List<OptimizationPhase> phases) { |    18   void runPhases(HGraph graph, List<OptimizationPhase> phases) { | 
|    19     for (OptimizationPhase phase in phases) { |    19     for (OptimizationPhase phase in phases) { | 
|    20       phase.visitGraph(graph); |    20       phase.visitGraph(graph); | 
|    21       compiler.tracer.traceGraph(phase.name, graph); |    21       compiler.tracer.traceGraph(phase.name, graph); | 
|    22     } |    22     } | 
|    23   } |    23   } | 
|    24  |    24  | 
|    25   void optimize(WorkItem work, HGraph graph) { |    25   void optimize(WorkItem work, HGraph graph) { | 
 |    26     FoldingOperations foldingOperations = | 
 |    27         compiler.constantHandler.foldingOperations; | 
|    26     measure(() { |    28     measure(() { | 
|    27       List<OptimizationPhase> phases = <OptimizationPhase>[ |    29       List<OptimizationPhase> phases = <OptimizationPhase>[ | 
|    28           // Run trivial constant folding first to optimize |    30           // Run trivial constant folding first to optimize | 
|    29           // some patterns useful for type conversion. |    31           // some patterns useful for type conversion. | 
|    30           new SsaConstantFolder(backend, work), |    32           new SsaConstantFolder(foldingOperations, backend, work), | 
|    31           new SsaTypeConversionInserter(compiler), |    33           new SsaTypeConversionInserter(compiler), | 
|    32           new SsaTypePropagator(compiler), |    34           new SsaTypePropagator(compiler), | 
|    33           new SsaCheckInserter(backend), |    35           new SsaCheckInserter(backend), | 
|    34           new SsaConstantFolder(backend, work), |    36           new SsaConstantFolder(foldingOperations, backend, work), | 
|    35           new SsaRedundantPhiEliminator(), |    37           new SsaRedundantPhiEliminator(), | 
|    36           new SsaDeadPhiEliminator(), |    38           new SsaDeadPhiEliminator(), | 
|    37           new SsaGlobalValueNumberer(compiler), |    39           new SsaGlobalValueNumberer(compiler), | 
|    38           new SsaCodeMotion(), |    40           new SsaCodeMotion(), | 
|    39           new SsaDeadCodeEliminator(), |    41           new SsaDeadCodeEliminator(), | 
|    40           new SsaRegisterRecompilationCandidates(backend, work)]; |    42           new SsaRegisterRecompilationCandidates(backend, work)]; | 
|    41       runPhases(graph, phases); |    43       runPhases(graph, phases); | 
|    42     }); |    44     }); | 
|    43   } |    45   } | 
|    44  |    46  | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|    86 } |    88 } | 
|    87  |    89  | 
|    88 /** |    90 /** | 
|    89  * If both inputs to known operations are available execute the operation at |    91  * If both inputs to known operations are available execute the operation at | 
|    90  * compile-time. |    92  * compile-time. | 
|    91  */ |    93  */ | 
|    92 class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |    94 class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { | 
|    93   final String name = "SsaConstantFolder"; |    95   final String name = "SsaConstantFolder"; | 
|    94   final JavaScriptBackend backend; |    96   final JavaScriptBackend backend; | 
|    95   final WorkItem work; |    97   final WorkItem work; | 
 |    98   final FoldingOperations foldingOperations; | 
|    96   HGraph graph; |    99   HGraph graph; | 
|    97   Compiler get compiler() => backend.compiler; |   100   Compiler get compiler() => backend.compiler; | 
|    98  |   101  | 
|    99   SsaConstantFolder(this.backend, this.work); |   102   SsaConstantFolder(this.foldingOperations, this.backend, this.work); | 
|   100  |   103  | 
|   101   void visitGraph(HGraph visitee) { |   104   void visitGraph(HGraph visitee) { | 
|   102     graph = visitee; |   105     graph = visitee; | 
|   103     visitDominatorTree(visitee); |   106     visitDominatorTree(visitee); | 
|   104   } |   107   } | 
|   105  |   108  | 
|   106   visitBasicBlock(HBasicBlock block) { |   109   visitBasicBlock(HBasicBlock block) { | 
|   107     HInstruction instruction = block.first; |   110     HInstruction instruction = block.first; | 
|   108     while (instruction !== null) { |   111     while (instruction !== null) { | 
|   109       HInstruction next = instruction.next; |   112       HInstruction next = instruction.next; | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   158       return graph.addConstantBool(!isTrue); |   161       return graph.addConstantBool(!isTrue); | 
|   159     } else if (input is HNot) { |   162     } else if (input is HNot) { | 
|   160       return input.inputs[0]; |   163       return input.inputs[0]; | 
|   161     } |   164     } | 
|   162     return node; |   165     return node; | 
|   163   } |   166   } | 
|   164  |   167  | 
|   165   HInstruction visitInvokeUnary(HInvokeUnary node) { |   168   HInstruction visitInvokeUnary(HInvokeUnary node) { | 
|   166     HInstruction operand = node.operand; |   169     HInstruction operand = node.operand; | 
|   167     if (operand is HConstant) { |   170     if (operand is HConstant) { | 
|   168       UnaryOperation operation = node.operation; |   171       UnaryOperation operation = node.operation(foldingOperations); | 
|   169       HConstant receiver = operand; |   172       HConstant receiver = operand; | 
|   170       Constant folded = operation.fold(receiver.constant); |   173       Constant folded = operation.fold(receiver.constant); | 
|   171       if (folded !== null) return graph.addConstant(folded); |   174       if (folded !== null) return graph.addConstant(folded); | 
|   172     } |   175     } | 
|   173     return node; |   176     return node; | 
|   174   } |   177   } | 
|   175  |   178  | 
|   176   HInstruction visitInvokeInterceptor(HInvokeInterceptor node) { |   179   HInstruction visitInvokeInterceptor(HInvokeInterceptor node) { | 
|   177     HInstruction input = node.inputs[1]; |   180     HInstruction input = node.inputs[1]; | 
|   178     if (node.isLengthGetter()) { |   181     if (node.isLengthGetter()) { | 
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   312     if (!node.receiver.canBePrimitive()) { |   315     if (!node.receiver.canBePrimitive()) { | 
|   313       Selector selector = new Selector.indexSet(); |   316       Selector selector = new Selector.indexSet(); | 
|   314       return fromInterceptorToDynamicInvocation(node, selector); |   317       return fromInterceptorToDynamicInvocation(node, selector); | 
|   315     } |   318     } | 
|   316     return node; |   319     return node; | 
|   317   } |   320   } | 
|   318  |   321  | 
|   319   HInstruction visitInvokeBinary(HInvokeBinary node) { |   322   HInstruction visitInvokeBinary(HInvokeBinary node) { | 
|   320     HInstruction left = node.left; |   323     HInstruction left = node.left; | 
|   321     HInstruction right = node.right; |   324     HInstruction right = node.right; | 
 |   325     BinaryOperation operation = node.operation(foldingOperations); | 
|   322     if (left is HConstant && right is HConstant) { |   326     if (left is HConstant && right is HConstant) { | 
|   323       BinaryOperation operation = node.operation; |  | 
|   324       HConstant op1 = left; |   327       HConstant op1 = left; | 
|   325       HConstant op2 = right; |   328       HConstant op2 = right; | 
|   326       Constant folded = operation.fold(op1.constant, op2.constant); |   329       Constant folded = operation.fold(op1.constant, op2.constant); | 
|   327       if (folded !== null) return graph.addConstant(folded); |   330       if (folded !== null) return graph.addConstant(folded); | 
|   328     } |   331     } | 
|   329  |   332  | 
|   330     if (!left.canBePrimitive() |   333     if (!left.canBePrimitive() | 
|   331         && node.operation.isUserDefinable() |   334         && operation.isUserDefinable() | 
|   332         // The equals operation is being optimized in visitEquals. |   335         // The equals operation is being optimized in visitEquals. | 
|   333         && node.operation !== const EqualsOperation()) { |   336         && node is! HEquals) { | 
|   334       Selector selector = new Selector.binaryOperator(node.operation.name); |   337       Selector selector = new Selector.binaryOperator(operation.name); | 
|   335       return fromInterceptorToDynamicInvocation(node, selector); |   338       return fromInterceptorToDynamicInvocation(node, selector); | 
|   336     } |   339     } | 
|   337     return node; |   340     return node; | 
|   338   } |   341   } | 
|   339  |   342  | 
|   340   bool allUsersAreBoolifies(HInstruction instruction) { |   343   bool allUsersAreBoolifies(HInstruction instruction) { | 
|   341     List<HInstruction> users = instruction.usedBy; |   344     List<HInstruction> users = instruction.usedBy; | 
|   342     int length = users.length; |   345     int length = users.length; | 
|   343     for (int i = 0; i < length; i++) { |   346     for (int i = 0; i < length; i++) { | 
|   344       if (users[i] is! HBoolify) return false; |   347       if (users[i] is! HBoolify) return false; | 
| (...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1306       // this type for the field is still a strong signal |  1309       // this type for the field is still a strong signal | 
|  1307       // indicating the expected type of the field. |  1310       // indicating the expected type of the field. | 
|  1308       field.propagatedType = type; |  1311       field.propagatedType = type; | 
|  1309     } else { |  1312     } else { | 
|  1310       // If there are no invoked setters we know the type of |  1313       // If there are no invoked setters we know the type of | 
|  1311       // this field for sure. |  1314       // this field for sure. | 
|  1312       field.guaranteedType = type; |  1315       field.guaranteedType = type; | 
|  1313     } |  1316     } | 
|  1314   } |  1317   } | 
|  1315 } |  1318 } | 
| OLD | NEW |