| 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 BailoutInfo { | 5 class BailoutInfo { |
| 6 int instructionId; | 6 int instructionId; |
| 7 int bailoutId; | 7 int bailoutId; |
| 8 BailoutInfo(this.instructionId, this.bailoutId); | 8 BailoutInfo(this.instructionId, this.bailoutId); |
| 9 } | 9 } |
| 10 | 10 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 loopMarkers = new Set<HBasicBlock>.from(other.loopMarkers); | 22 loopMarkers = new Set<HBasicBlock>.from(other.loopMarkers); |
| 23 | 23 |
| 24 void remove(HInstruction instruction) { | 24 void remove(HInstruction instruction) { |
| 25 lives.remove(instruction); | 25 lives.remove(instruction); |
| 26 } | 26 } |
| 27 | 27 |
| 28 void add(HInstruction instruction) { | 28 void add(HInstruction instruction) { |
| 29 // If the instruction is a type guard, we add its checked input | 29 // If the instruction is a type guard, we add its checked input |
| 30 // instead. This allows sharing the same environment between | 30 // instead. This allows sharing the same environment between |
| 31 // different type guards. | 31 // different type guards. |
| 32 // | 32 // |
| 33 // Also, we don't need to add code motion invariant instructions | 33 // Also, we don't need to add code motion invariant instructions |
| 34 // in the live set (because we generate them at use-site), except | 34 // in the live set (because we generate them at use-site), except |
| 35 // for parameters that are not 'this', which is always passed as | 35 // for parameters that are not 'this', which is always passed as |
| 36 // the receiver. | 36 // the receiver. |
| 37 if (instruction is HTypeGuard) { | 37 if (instruction is HTypeGuard) { |
| 38 add(instruction.checkedInput); | 38 add(instruction.checkedInput); |
| 39 } else if (!instruction.isCodeMotionInvariant() | 39 } else if (!instruction.isCodeMotionInvariant() |
| 40 || (instruction is HParameterValue && instruction is !HThis)) { | 40 || (instruction is HParameterValue && instruction is !HThis)) { |
| 41 lives.add(instruction); | 41 lives.add(instruction); |
| 42 } else { | 42 } else { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 68 * we consider the guard to be of value. | 68 * we consider the guard to be of value. |
| 69 * | 69 * |
| 70 * Might modify the [:propagatedType:] fields of the instructions in an | 70 * Might modify the [:propagatedType:] fields of the instructions in an |
| 71 * inconsistent way. No further analysis should rely on them. | 71 * inconsistent way. No further analysis should rely on them. |
| 72 */ | 72 */ |
| 73 class SsaTypeGuardInserter extends HGraphVisitor implements OptimizationPhase { | 73 class SsaTypeGuardInserter extends HGraphVisitor implements OptimizationPhase { |
| 74 final Compiler compiler; | 74 final Compiler compiler; |
| 75 final String name = 'SsaTypeGuardInserter'; | 75 final String name = 'SsaTypeGuardInserter'; |
| 76 final WorkItem work; | 76 final WorkItem work; |
| 77 bool calledInLoop = false; | 77 bool calledInLoop = false; |
| 78 bool highTypeLikelyhood = false; |
| 78 bool isRecursiveMethod = false; | 79 bool isRecursiveMethod = false; |
| 79 int stateId = 1; | 80 int stateId = 1; |
| 80 | 81 |
| 81 SsaTypeGuardInserter(this.compiler, this.work); | 82 SsaTypeGuardInserter(this.compiler, this.work); |
| 82 | 83 |
| 83 void visitGraph(HGraph graph) { | 84 void visitGraph(HGraph graph) { |
| 84 isRecursiveMethod = graph.isRecursiveMethod; | 85 isRecursiveMethod = graph.isRecursiveMethod; |
| 85 calledInLoop = graph.calledInLoop; | 86 calledInLoop = graph.calledInLoop; |
| 87 highTypeLikelyhood = graph.highTypeLikelyhood; |
| 86 work.guards = <HTypeGuard>[]; | 88 work.guards = <HTypeGuard>[]; |
| 87 visitDominatorTree(graph); | 89 visitDominatorTree(graph); |
| 88 } | 90 } |
| 89 | 91 |
| 90 void visitBasicBlock(HBasicBlock block) { | 92 void visitBasicBlock(HBasicBlock block) { |
| 91 block.forEachPhi(visitInstruction); | 93 block.forEachPhi(visitInstruction); |
| 92 | 94 |
| 93 HInstruction instruction = block.first; | 95 HInstruction instruction = block.first; |
| 94 while (instruction !== null) { | 96 while (instruction !== null) { |
| 95 // Note that visitInstruction (from the phis and here) might insert an | 97 // Note that visitInstruction (from the phis and here) might insert an |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 | 140 |
| 139 // If the instruction is not in a loop then the header will be null. | 141 // If the instruction is not in a loop then the header will be null. |
| 140 HBasicBlock currentLoopHeader = instruction.block.enclosingLoopHeader; | 142 HBasicBlock currentLoopHeader = instruction.block.enclosingLoopHeader; |
| 141 for (HInstruction user in instruction.usedBy) { | 143 for (HInstruction user in instruction.usedBy) { |
| 142 HBasicBlock userLoopHeader = user.block.enclosingLoopHeader; | 144 HBasicBlock userLoopHeader = user.block.enclosingLoopHeader; |
| 143 if (isNested(userLoopHeader, currentLoopHeader)) return true; | 145 if (isNested(userLoopHeader, currentLoopHeader)) return true; |
| 144 } | 146 } |
| 145 | 147 |
| 146 // Insert type guards if the method is likely to be called in a | 148 // Insert type guards if the method is likely to be called in a |
| 147 // loop. | 149 // loop. |
| 148 return calledInLoop; | 150 return calledInLoop || highTypeLikelyhood; |
| 149 } | 151 } |
| 150 | 152 |
| 151 bool shouldInsertTypeGuard(HInstruction instruction) { | 153 bool shouldInsertTypeGuard(HInstruction instruction) { |
| 152 HType speculativeType = instruction.propagatedType; | 154 HType speculativeType = instruction.propagatedType; |
| 153 HType computedType = instruction.computeTypeFromInputTypes(); | 155 HType computedType = instruction.computeTypeFromInputTypes(); |
| 154 // Start by reverting the propagated type. If we add a type guard then the | 156 // Start by reverting the propagated type. If we add a type guard then the |
| 155 // guard will expose the speculative type. If we don't add a type guard | 157 // guard will expose the speculative type. If we don't add a type guard |
| 156 // then this avoids subsequent instructions to use the the wrong type. | 158 // then this avoids subsequent instructions to use the the wrong type. |
| 157 // | 159 // |
| 158 // Note that just setting the propagatedType of the instruction is not | 160 // Note that just setting the propagatedType of the instruction is not |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 hasComplexTypeGuards = true; | 522 hasComplexTypeGuards = true; |
| 521 } | 523 } |
| 522 } else { | 524 } else { |
| 523 hasComplexTypeGuards = true; | 525 hasComplexTypeGuards = true; |
| 524 blocks.forEach((HBasicBlock block) { | 526 blocks.forEach((HBasicBlock block) { |
| 525 block.guards.add(guard); | 527 block.guards.add(guard); |
| 526 }); | 528 }); |
| 527 } | 529 } |
| 528 } | 530 } |
| 529 } | 531 } |
| OLD | NEW |