Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(170)

Side by Side Diff: lib/compiler/implementation/ssa/bailout.dart

Issue 10171007: Reapply "Only emit typeguards if we think they are valuable." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « frog/tests/leg/src/TypeInferenceTest.dart ('k') | lib/compiler/implementation/ssa/nodes.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 isNested(HBasicBlock inner, HBasicBlock outer) {
117 if (inner === outer) return false;
118 if (outer === null) return true;
119 while (inner !== null) {
120 if (inner === outer) return true;
121 inner = inner.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.enclosingLoopHeader;
128 for (HInstruction user in instruction.usedBy) {
129 HBasicBlock userLoopHeader = user.block.enclosingLoopHeader;
130 if (isNested(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
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 }
OLDNEW
« no previous file with comments | « frog/tests/leg/src/TypeInferenceTest.dart ('k') | lib/compiler/implementation/ssa/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698