| 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 import '../common/codegen.dart' show CodegenWorkItem; | 5 import '../common/codegen.dart' show CodegenWorkItem; |
| 6 import '../common/tasks.dart' show CompilerTask; | 6 import '../common/tasks.dart' show CompilerTask; |
| 7 import '../compiler.dart' show Compiler; | 7 import '../compiler.dart' show Compiler; |
| 8 import '../constants/constant_system.dart'; | 8 import '../constants/constant_system.dart'; |
| 9 import '../constants/values.dart'; | 9 import '../constants/values.dart'; |
| 10 import '../core_types.dart' show CoreClasses; | 10 import '../core_types.dart' show CoreClasses; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 void optimize(CodegenWorkItem work, HGraph graph) { | 44 void optimize(CodegenWorkItem work, HGraph graph) { |
| 45 void runPhase(OptimizationPhase phase) { | 45 void runPhase(OptimizationPhase phase) { |
| 46 measureSubtask(phase.name, () => phase.visitGraph(graph)); | 46 measureSubtask(phase.name, () => phase.visitGraph(graph)); |
| 47 compiler.tracer.traceGraph(phase.name, graph); | 47 compiler.tracer.traceGraph(phase.name, graph); |
| 48 assert(graph.isValid()); | 48 assert(graph.isValid()); |
| 49 } | 49 } |
| 50 | 50 |
| 51 ConstantSystem constantSystem = compiler.backend.constantSystem; | 51 ConstantSystem constantSystem = compiler.backend.constantSystem; |
| 52 bool trustPrimitives = compiler.options.trustPrimitives; | 52 bool trustPrimitives = compiler.options.trustPrimitives; |
| 53 Set<HInstruction> boundsChecked = new Set<HInstruction>(); | 53 Set<HInstruction> boundsChecked = new Set<HInstruction>(); |
| 54 SsaCodeMotion codeMotion; |
| 54 measure(() { | 55 measure(() { |
| 55 List<OptimizationPhase> phases = <OptimizationPhase>[ | 56 List<OptimizationPhase> phases = <OptimizationPhase>[ |
| 56 // Run trivial instruction simplification first to optimize | 57 // Run trivial instruction simplification first to optimize |
| 57 // some patterns useful for type conversion. | 58 // some patterns useful for type conversion. |
| 58 new SsaInstructionSimplifier(constantSystem, backend, this), | 59 new SsaInstructionSimplifier(constantSystem, backend, this), |
| 59 new SsaTypeConversionInserter(compiler), | 60 new SsaTypeConversionInserter(compiler), |
| 60 new SsaRedundantPhiEliminator(), | 61 new SsaRedundantPhiEliminator(), |
| 61 new SsaDeadPhiEliminator(), | 62 new SsaDeadPhiEliminator(), |
| 62 new SsaTypePropagator(compiler), | 63 new SsaTypePropagator(compiler), |
| 63 // After type propagation, more instructions can be | 64 // After type propagation, more instructions can be |
| 64 // simplified. | 65 // simplified. |
| 65 new SsaInstructionSimplifier(constantSystem, backend, this), | 66 new SsaInstructionSimplifier(constantSystem, backend, this), |
| 66 new SsaCheckInserter(trustPrimitives, backend, boundsChecked), | 67 new SsaCheckInserter(trustPrimitives, backend, boundsChecked), |
| 67 new SsaInstructionSimplifier(constantSystem, backend, this), | 68 new SsaInstructionSimplifier(constantSystem, backend, this), |
| 68 new SsaCheckInserter(trustPrimitives, backend, boundsChecked), | 69 new SsaCheckInserter(trustPrimitives, backend, boundsChecked), |
| 69 new SsaTypePropagator(compiler), | 70 new SsaTypePropagator(compiler), |
| 70 // Run a dead code eliminator before LICM because dead | 71 // Run a dead code eliminator before LICM because dead |
| 71 // interceptors are often in the way of LICM'able instructions. | 72 // interceptors are often in the way of LICM'able instructions. |
| 72 new SsaDeadCodeEliminator(compiler, this), | 73 new SsaDeadCodeEliminator(compiler, this), |
| 73 new SsaGlobalValueNumberer(compiler), | 74 new SsaGlobalValueNumberer(compiler), |
| 74 // After GVN, some instructions might need their type to be | 75 // After GVN, some instructions might need their type to be |
| 75 // updated because they now have different inputs. | 76 // updated because they now have different inputs. |
| 76 new SsaTypePropagator(compiler), | 77 new SsaTypePropagator(compiler), |
| 77 new SsaCodeMotion(), | 78 codeMotion = new SsaCodeMotion(), |
| 78 new SsaLoadElimination(compiler), | 79 new SsaLoadElimination(compiler), |
| 79 new SsaRedundantPhiEliminator(), | 80 new SsaRedundantPhiEliminator(), |
| 80 new SsaDeadPhiEliminator(), | 81 new SsaDeadPhiEliminator(), |
| 81 new SsaTypePropagator(compiler), | 82 new SsaTypePropagator(compiler), |
| 82 new SsaValueRangeAnalyzer(compiler, constantSystem, this), | 83 new SsaValueRangeAnalyzer(compiler, constantSystem, this), |
| 83 // Previous optimizations may have generated new | 84 // Previous optimizations may have generated new |
| 84 // opportunities for instruction simplification. | 85 // opportunities for instruction simplification. |
| 85 new SsaInstructionSimplifier(constantSystem, backend, this), | 86 new SsaInstructionSimplifier(constantSystem, backend, this), |
| 86 new SsaCheckInserter(trustPrimitives, backend, boundsChecked), | 87 new SsaCheckInserter(trustPrimitives, backend, boundsChecked), |
| 87 ]; | 88 ]; |
| 88 phases.forEach(runPhase); | 89 phases.forEach(runPhase); |
| 89 | 90 |
| 90 // Simplifying interceptors is not strictly just an optimization, it is | 91 // Simplifying interceptors is not strictly just an optimization, it is |
| 91 // required for implementation correctness because the code generator | 92 // required for implementation correctness because the code generator |
| 92 // assumes it is always performed. | 93 // assumes it is always performed. |
| 93 runPhase( | 94 runPhase( |
| 94 new SsaSimplifyInterceptors(compiler, constantSystem, work.element)); | 95 new SsaSimplifyInterceptors(compiler, constantSystem, work.element)); |
| 95 | 96 |
| 96 SsaDeadCodeEliminator dce = new SsaDeadCodeEliminator(compiler, this); | 97 SsaDeadCodeEliminator dce = new SsaDeadCodeEliminator(compiler, this); |
| 97 runPhase(dce); | 98 runPhase(dce); |
| 98 if (dce.eliminatedSideEffects) { | 99 if (codeMotion.movedCode || dce.eliminatedSideEffects) { |
| 99 phases = <OptimizationPhase>[ | 100 phases = <OptimizationPhase>[ |
| 100 new SsaTypePropagator(compiler), | 101 new SsaTypePropagator(compiler), |
| 101 new SsaGlobalValueNumberer(compiler), | 102 new SsaGlobalValueNumberer(compiler), |
| 102 new SsaCodeMotion(), | 103 new SsaCodeMotion(), |
| 103 new SsaValueRangeAnalyzer(compiler, constantSystem, this), | 104 new SsaValueRangeAnalyzer(compiler, constantSystem, this), |
| 104 new SsaInstructionSimplifier(constantSystem, backend, this), | 105 new SsaInstructionSimplifier(constantSystem, backend, this), |
| 105 new SsaCheckInserter(trustPrimitives, backend, boundsChecked), | 106 new SsaCheckInserter(trustPrimitives, backend, boundsChecked), |
| 106 new SsaSimplifyInterceptors(compiler, constantSystem, work.element), | 107 new SsaSimplifyInterceptors(compiler, constantSystem, work.element), |
| 107 new SsaDeadCodeEliminator(compiler, this), | 108 new SsaDeadCodeEliminator(compiler, this), |
| 108 ]; | 109 ]; |
| (...skipping 1797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1906 // instructions are the ones that: | 1907 // instructions are the ones that: |
| 1907 // 1) can be used for GVN, and | 1908 // 1) can be used for GVN, and |
| 1908 // 2) do not use definitions of their own block. | 1909 // 2) do not use definitions of their own block. |
| 1909 // | 1910 // |
| 1910 // A basic block looks at its sucessors and finds the intersection of | 1911 // A basic block looks at its sucessors and finds the intersection of |
| 1911 // these computed ValueSet. It moves all instructions of the | 1912 // these computed ValueSet. It moves all instructions of the |
| 1912 // intersection into its own list of instructions. | 1913 // intersection into its own list of instructions. |
| 1913 class SsaCodeMotion extends HBaseVisitor implements OptimizationPhase { | 1914 class SsaCodeMotion extends HBaseVisitor implements OptimizationPhase { |
| 1914 final String name = "SsaCodeMotion"; | 1915 final String name = "SsaCodeMotion"; |
| 1915 | 1916 |
| 1917 bool movedCode = false; |
| 1916 List<ValueSet> values; | 1918 List<ValueSet> values; |
| 1917 | 1919 |
| 1918 void visitGraph(HGraph graph) { | 1920 void visitGraph(HGraph graph) { |
| 1919 values = new List<ValueSet>(graph.blocks.length); | 1921 values = new List<ValueSet>(graph.blocks.length); |
| 1920 for (int i = 0; i < graph.blocks.length; i++) { | 1922 for (int i = 0; i < graph.blocks.length; i++) { |
| 1921 values[graph.blocks[i].id] = new ValueSet(); | 1923 values[graph.blocks[i].id] = new ValueSet(); |
| 1922 } | 1924 } |
| 1923 visitPostDominatorTree(graph); | 1925 visitPostDominatorTree(graph); |
| 1924 } | 1926 } |
| 1925 | 1927 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1942 // Move the instruction to the current block. | 1944 // Move the instruction to the current block. |
| 1943 instruction.block.detach(instruction); | 1945 instruction.block.detach(instruction); |
| 1944 block.moveAtExit(instruction); | 1946 block.moveAtExit(instruction); |
| 1945 // Go through all successors and rewrite their instruction | 1947 // Go through all successors and rewrite their instruction |
| 1946 // to the shared one. | 1948 // to the shared one. |
| 1947 for (final successor in successors) { | 1949 for (final successor in successors) { |
| 1948 HInstruction toRewrite = values[successor.id].lookup(instruction); | 1950 HInstruction toRewrite = values[successor.id].lookup(instruction); |
| 1949 if (toRewrite != instruction) { | 1951 if (toRewrite != instruction) { |
| 1950 successor.rewriteWithBetterUser(toRewrite, instruction); | 1952 successor.rewriteWithBetterUser(toRewrite, instruction); |
| 1951 successor.remove(toRewrite); | 1953 successor.remove(toRewrite); |
| 1954 movedCode = true; |
| 1952 } | 1955 } |
| 1953 } | 1956 } |
| 1954 } | 1957 } |
| 1955 } | 1958 } |
| 1956 } | 1959 } |
| 1957 | 1960 |
| 1958 // Don't try to merge instructions to a dominator if we have | 1961 // Don't try to merge instructions to a dominator if we have |
| 1959 // multiple predecessors. | 1962 // multiple predecessors. |
| 1960 if (block.predecessors.length != 1) return; | 1963 if (block.predecessors.length != 1) return; |
| 1961 | 1964 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1985 } | 1988 } |
| 1986 } | 1989 } |
| 1987 if (!canBeMoved) continue; | 1990 if (!canBeMoved) continue; |
| 1988 | 1991 |
| 1989 HInstruction existing = set_.lookup(current); | 1992 HInstruction existing = set_.lookup(current); |
| 1990 if (existing == null) { | 1993 if (existing == null) { |
| 1991 set_.add(current); | 1994 set_.add(current); |
| 1992 } else { | 1995 } else { |
| 1993 block.rewriteWithBetterUser(current, existing); | 1996 block.rewriteWithBetterUser(current, existing); |
| 1994 block.remove(current); | 1997 block.remove(current); |
| 1998 movedCode = true; |
| 1995 } | 1999 } |
| 1996 } | 2000 } |
| 1997 } | 2001 } |
| 1998 } | 2002 } |
| 1999 | 2003 |
| 2000 class SsaTypeConversionInserter extends HBaseVisitor | 2004 class SsaTypeConversionInserter extends HBaseVisitor |
| 2001 implements OptimizationPhase { | 2005 implements OptimizationPhase { |
| 2002 final String name = "SsaTypeconversionInserter"; | 2006 final String name = "SsaTypeconversionInserter"; |
| 2003 final Compiler compiler; | 2007 final Compiler compiler; |
| 2004 | 2008 |
| (...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2580 | 2584 |
| 2581 keyedValues.forEach((receiver, values) { | 2585 keyedValues.forEach((receiver, values) { |
| 2582 result.keyedValues[receiver] = | 2586 result.keyedValues[receiver] = |
| 2583 new Map<HInstruction, HInstruction>.from(values); | 2587 new Map<HInstruction, HInstruction>.from(values); |
| 2584 }); | 2588 }); |
| 2585 | 2589 |
| 2586 result.nonEscapingReceivers.addAll(nonEscapingReceivers); | 2590 result.nonEscapingReceivers.addAll(nonEscapingReceivers); |
| 2587 return result; | 2591 return result; |
| 2588 } | 2592 } |
| 2589 } | 2593 } |
| OLD | NEW |