Chromium Code Reviews| 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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 104 | 104 |
| 105 HInstruction instruction = block.first; | 105 HInstruction instruction = block.first; |
| 106 while (instruction !== null) { | 106 while (instruction !== null) { |
| 107 // Note that visitInstruction (from the phis and here) might insert an | 107 // Note that visitInstruction (from the phis and here) might insert an |
| 108 // HTypeGuard instruction. We have to skip those. | 108 // HTypeGuard instruction. We have to skip those. |
| 109 if (instruction is !HTypeGuard) visitInstruction(instruction); | 109 if (instruction is !HTypeGuard) visitInstruction(instruction); |
| 110 instruction = instruction.next; | 110 instruction = instruction.next; |
| 111 } | 111 } |
| 112 } | 112 } |
| 113 | 113 |
| 114 bool typeGuardWouldBeValuable(HInstruction instruction, | |
| 115 HType speculativeType) { | |
| 116 bool isMoreNested(HBasicBlock loopHeader1, HBasicBlock loopHeader2) { | |
|
kasperl
2012/04/20 12:07:31
isNestedInside? You're checking if loop1 is inside
floitsch
2012/04/20 12:43:47
Done.
| |
| 117 if (loopHeader1 == loopHeader2) return false; | |
|
kasperl
2012/04/20 12:07:31
Is this a place where === makes sense?
floitsch
2012/04/20 12:43:47
Done.
| |
| 118 if (loopHeader2 == null) return true; | |
| 119 while (loopHeader1 != null) { | |
| 120 if (loopHeader1 == loopHeader2) return true; | |
| 121 loopHeader1 = loopHeader1.parentLoopHeader; | |
| 122 } | |
| 123 return false; | |
| 124 } | |
| 125 | |
| 126 // If the instruction is not in a loop then the header will be null. | |
| 127 HBasicBlock currentLoopHeader = instruction.block.getEnclosingLoopHeader(); | |
| 128 for (HInstruction user in instruction.usedBy) { | |
| 129 HBasicBlock userLoopHeader = user.block.getEnclosingLoopHeader(); | |
| 130 if (isMoreNested(userLoopHeader, currentLoopHeader)) return true; | |
| 131 } | |
| 132 return false; | |
| 133 } | |
| 134 | |
| 114 bool shouldInsertTypeGuard(HInstruction instruction) { | 135 bool shouldInsertTypeGuard(HInstruction instruction) { |
| 115 HType speculativeType = instruction.propagatedType; | 136 HType speculativeType = instruction.propagatedType; |
| 116 HType computedType = instruction.computeTypeFromInputTypes(); | 137 HType computedType = instruction.computeTypeFromInputTypes(); |
| 117 // Start by reverting the propagated type. If we add a type guard then the | 138 // Start by reverting the propagated type. If we add a type guard then the |
| 118 // guard will expose the speculative type. If we don't add a type guard | 139 // guard will expose the speculative type. If we don't add a type guard |
| 119 // then this avoids subsequent instructions to use the the wrong type. | 140 // then this avoids subsequent instructions to use the the wrong type. |
| 120 // | 141 // |
| 121 // Note that just setting the propagatedType of the instruction is not | 142 // Note that just setting the propagatedType of the instruction is not |
| 122 // complete since the type could lead to a phi node which in turn could | 143 // complete since the type could lead to a phi node which in turn could |
| 123 // change the computedType. In this case we might miss some guards we | 144 // change the computedType. In this case we might miss some guards we |
| 124 // would have liked to insert. Most of the time this should however be | 145 // would have liked to insert. Most of the time this should however be |
| 125 // fine, due to dominator-order visiting. | 146 // fine, due to dominator-order visiting. |
| 126 instruction.propagatedType = computedType; | 147 instruction.propagatedType = computedType; |
| 127 | 148 |
| 128 if (!speculativeType.isUseful()) return false; | 149 if (!speculativeType.isUseful()) return false; |
| 129 // If the types agree we don't need to check. | 150 // If the types agree we don't need to check. |
| 130 if (speculativeType == computedType) return false; | 151 if (speculativeType == computedType) return false; |
| 131 // TODO(floitsch): Make the creation of type guards more conditional. | 152 // If a bailout check is more expensive than doing the actual operation |
| 132 return true; | 153 // don't do it either. |
| 154 return typeGuardWouldBeValuable(instruction, speculativeType); | |
| 133 } | 155 } |
| 134 | 156 |
| 135 void visitInstruction(HInstruction instruction) { | 157 void visitInstruction(HInstruction instruction) { |
| 136 HType speculativeType = instruction.propagatedType; | 158 HType speculativeType = instruction.propagatedType; |
| 137 if (shouldInsertTypeGuard(instruction)) { | 159 if (shouldInsertTypeGuard(instruction)) { |
| 138 List<HInstruction> inputs = <HInstruction>[instruction]; | 160 List<HInstruction> inputs = <HInstruction>[instruction]; |
| 139 HTypeGuard guard = new HTypeGuard(speculativeType, stateId++, inputs); | 161 HTypeGuard guard = new HTypeGuard(speculativeType, stateId++, inputs); |
| 140 guard.propagatedType = speculativeType; | 162 guard.propagatedType = speculativeType; |
| 141 work.guards.add(guard); | 163 work.guards.add(guard); |
| 142 instruction.block.rewrite(instruction, guard); | 164 instruction.block.rewrite(instruction, guard); |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 426 compiler.internalError('Control flow instructions already dealt with.', | 448 compiler.internalError('Control flow instructions already dealt with.', |
| 427 instruction: instruction); | 449 instruction: instruction); |
| 428 } | 450 } |
| 429 | 451 |
| 430 visitTypeGuard(HTypeGuard guard) { | 452 visitTypeGuard(HTypeGuard guard) { |
| 431 blocks.forEach((HBasicBlock block) { | 453 blocks.forEach((HBasicBlock block) { |
| 432 block.guards.add(guard); | 454 block.guards.add(guard); |
| 433 }); | 455 }); |
| 434 } | 456 } |
| 435 } | 457 } |
| OLD | NEW |