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

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

Issue 10968060: Add a value range analysis phase to remove bounds checks. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 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 | « lib/compiler/implementation/ssa/nodes.dart ('k') | lib/compiler/implementation/ssa/ssa.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 abstract class OptimizationPhase { 5 abstract class 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 {
(...skipping 23 matching lines...) Expand all
34 List<OptimizationPhase> phases = <OptimizationPhase>[ 34 List<OptimizationPhase> phases = <OptimizationPhase>[
35 // Run trivial constant folding first to optimize 35 // Run trivial constant folding first to optimize
36 // some patterns useful for type conversion. 36 // some patterns useful for type conversion.
37 new SsaConstantFolder(constantSystem, backend, work, types), 37 new SsaConstantFolder(constantSystem, backend, work, types),
38 new SsaTypeConversionInserter(compiler), 38 new SsaTypeConversionInserter(compiler),
39 new SsaTypePropagator(compiler, types), 39 new SsaTypePropagator(compiler, types),
40 new SsaCheckInserter(backend, types, context.boundsChecked), 40 new SsaCheckInserter(backend, types, context.boundsChecked),
41 new SsaConstantFolder(constantSystem, backend, work, types), 41 new SsaConstantFolder(constantSystem, backend, work, types),
42 new SsaRedundantPhiEliminator(), 42 new SsaRedundantPhiEliminator(),
43 new SsaDeadPhiEliminator(), 43 new SsaDeadPhiEliminator(),
44 new SsaConstantFolder(constantSystem, backend, work, types),
44 new SsaGlobalValueNumberer(compiler, types), 45 new SsaGlobalValueNumberer(compiler, types),
45 new SsaCodeMotion(), 46 new SsaCodeMotion(),
47 new SsaValueRangeAnalyzer(constantSystem, types, work),
46 // Previous optimizations may have generated new 48 // Previous optimizations may have generated new
47 // opportunities for constant folding. 49 // opportunities for constant folding.
48 new SsaConstantFolder(constantSystem, backend, work, types), 50 new SsaConstantFolder(constantSystem, backend, work, types),
49 new SsaDeadCodeEliminator(types), 51 new SsaDeadCodeEliminator(types),
50 new SsaRegisterRecompilationCandidates(backend, work, types)]; 52 new SsaRegisterRecompilationCandidates(backend, work, types)];
51 runPhases(graph, phases); 53 runPhases(graph, phases);
52 }); 54 });
53 } 55 }
54 56
55 bool trySpeculativeOptimizations(WorkItem work, HGraph graph) { 57 bool trySpeculativeOptimizations(WorkItem work, HGraph graph) {
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 if (operand is HConstant) { 192 if (operand is HConstant) {
191 UnaryOperation operation = node.operation(constantSystem); 193 UnaryOperation operation = node.operation(constantSystem);
192 HConstant receiver = operand; 194 HConstant receiver = operand;
193 Constant folded = operation.fold(receiver.constant); 195 Constant folded = operation.fold(receiver.constant);
194 if (folded !== null) return graph.addConstant(folded); 196 if (folded !== null) return graph.addConstant(folded);
195 } 197 }
196 return node; 198 return node;
197 } 199 }
198 200
199 HInstruction visitInvokeInterceptor(HInvokeInterceptor node) { 201 HInstruction visitInvokeInterceptor(HInvokeInterceptor node) {
202 // Try to recognize the length interceptor with input [:new List(int):].
203 if (node.isLengthGetter() && node.inputs[1] is HInvokeStatic) {
204 HInvokeStatic call = node.inputs[1];
205 Element element = call.inputs[0].element;
206 if (element.isConstructor() &&
207 element.enclosingElement == compiler.listClass.defaultClass.element) {
208 if (call.inputs.length == 2 && call.inputs[1].isInteger(types)) {
209 return call.inputs[1];
210 }
211 }
212 }
200 HInstruction input = node.inputs[1]; 213 HInstruction input = node.inputs[1];
201 if (node.isLengthGetter()) { 214 if (node.isLengthGetter()) {
202 if (input.isConstantString()) { 215 if (input.isConstantString()) {
203 HConstant constantInput = input; 216 HConstant constantInput = input;
204 StringConstant constant = constantInput.constant; 217 StringConstant constant = constantInput.constant;
205 return graph.addConstantInt(constant.length, constantSystem); 218 return graph.addConstantInt(constant.length, constantSystem);
206 } else if (input.isConstantList()) { 219 } else if (input.isConstantList()) {
207 HConstant constantInput = input; 220 HConstant constantInput = input;
208 ListConstant constant = constantInput.constant; 221 ListConstant constant = constantInput.constant;
209 return graph.addConstantInt(constant.length, constantSystem); 222 return graph.addConstantInt(constant.length, constantSystem);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 HInvokeDynamicMethod result = new HInvokeDynamicMethod( 276 HInvokeDynamicMethod result = new HInvokeDynamicMethod(
264 selector, 277 selector,
265 node.inputs.getRange(1, node.inputs.length - 1)); 278 node.inputs.getRange(1, node.inputs.length - 1));
266 if (type.isExact()) { 279 if (type.isExact()) {
267 HBoundedType concrete = type; 280 HBoundedType concrete = type;
268 result.element = concrete.lookupMember(selector.name); 281 result.element = concrete.lookupMember(selector.name);
269 } 282 }
270 return result; 283 return result;
271 } 284 }
272 285
273 HInstruction visitBoundsCheck(HBoundsCheck node) {
274 int tryGetIntConstantValue(HInstruction instruction, String errorMessage) {
275 // Tests whether an [HInstruction] is a constant.
276 // If it is a constant, and not an int constant, it fails.
277 // If it's an int constant it returns the value.
278 // Otherwise it's not a constant, and this function returns null.
279 if (!instruction.isConstant()) return null;
280 HConstant constantInstruction = instruction;
281 Constant constant = constantInstruction.constant;
282 if (!constant.isInt()) {
283 compiler.internalError(errorMessage, instruction: instruction);
284 }
285 IntConstant intConstant = constant;
286 return intConstant.value;
287 }
288 int index = tryGetIntConstantValue(node.index,
289 'String or List index not a number');
290 if (index !== null) {
291 if (index < 0) {
292 node.staticChecks = HBoundsCheck.ALWAYS_FALSE;
293 return node;
294 }
295 int length = tryGetIntConstantValue(node.length,
296 'String or List length not a number');
297 if (length !== null) {
298 if (index >= length) {
299 node.staticChecks = HBoundsCheck.ALWAYS_FALSE;
300 } else {
301 // Could have set the staticChecks to ALWAYS_TRUE instead.
302 return node.index;
303 }
304 return node;
305 }
306 node.staticChecks = HBoundsCheck.ALWAYS_ABOVE_ZERO;
307 }
308 return node;
309 }
310
311 HInstruction visitIntegerCheck(HIntegerCheck node) { 286 HInstruction visitIntegerCheck(HIntegerCheck node) {
312 HInstruction value = node.value; 287 HInstruction value = node.value;
313 if (value.isInteger(types)) return value; 288 if (value.isInteger(types)) return value;
314 if (value.isConstant()) { 289 if (value.isConstant()) {
315 HConstant constantInstruction = value; 290 HConstant constantInstruction = value;
316 assert(!constantInstruction.constant.isInt()); 291 assert(!constantInstruction.constant.isInt());
317 if (!constantSystem.isInt(constantInstruction.constant)) { 292 if (!constantSystem.isInt(constantInstruction.constant)) {
318 // -0.0 is a double but will pass the runtime integer check. 293 // -0.0 is a double but will pass the runtime integer check.
319 node.alwaysFalse = true; 294 node.alwaysFalse = true;
320 } 295 }
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 696
722 void visitIndex(HIndex node) { 697 void visitIndex(HIndex node) {
723 if (!node.receiver.isIndexablePrimitive(types)) return; 698 if (!node.receiver.isIndexablePrimitive(types)) return;
724 if (boundsChecked.contains(node)) return; 699 if (boundsChecked.contains(node)) return;
725 HInstruction index = node.index; 700 HInstruction index = node.index;
726 if (!node.index.isInteger(types)) { 701 if (!node.index.isInteger(types)) {
727 index = insertIntegerCheck(node, index); 702 index = insertIntegerCheck(node, index);
728 } 703 }
729 index = insertBoundsCheck(node, node.receiver, index); 704 index = insertBoundsCheck(node, node.receiver, index);
730 node.changeUse(node.index, index); 705 node.changeUse(node.index, index);
706 assert(node.isBuiltin(types));
731 } 707 }
732 708
733 void visitIndexAssign(HIndexAssign node) { 709 void visitIndexAssign(HIndexAssign node) {
734 if (!node.receiver.isMutableArray(types)) return; 710 if (!node.receiver.isMutableArray(types)) return;
735 if (boundsChecked.contains(node)) return; 711 if (boundsChecked.contains(node)) return;
736 HInstruction index = node.index; 712 HInstruction index = node.index;
737 if (!node.index.isInteger(types)) { 713 if (!node.index.isInteger(types)) {
738 index = insertIntegerCheck(node, index); 714 index = insertIntegerCheck(node, index);
739 } 715 }
740 index = insertBoundsCheck(node, node.receiver, index); 716 index = insertBoundsCheck(node, node.receiver, index);
741 node.changeUse(node.index, index); 717 node.changeUse(node.index, index);
718 assert(node.isBuiltin(types));
742 } 719 }
743 720
744 void visitInvokeInterceptor(HInvokeInterceptor node) { 721 void visitInvokeInterceptor(HInvokeInterceptor node) {
745 if (!node.isPopCall(types)) return; 722 if (!node.isPopCall(types)) return;
746 if (boundsChecked.contains(node)) return; 723 if (boundsChecked.contains(node)) return;
747 HInstruction receiver = node.inputs[1]; 724 HInstruction receiver = node.inputs[1];
748 insertBoundsCheck(node, receiver, graph.addConstantInt(0, constantSystem)); 725 insertBoundsCheck(node, receiver, graph.addConstantInt(0, constantSystem));
749 } 726 }
750 } 727 }
751 728
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after
1369 // this type for the field is still a strong signal 1346 // this type for the field is still a strong signal
1370 // indicating the expected type of the field. 1347 // indicating the expected type of the field.
1371 types[field] = type; 1348 types[field] = type;
1372 } else { 1349 } else {
1373 // If there are no invoked setters we know the type of 1350 // If there are no invoked setters we know the type of
1374 // this field for sure. 1351 // this field for sure.
1375 field.guaranteedType = type; 1352 field.guaranteedType = type;
1376 } 1353 }
1377 } 1354 }
1378 } 1355 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/ssa/nodes.dart ('k') | lib/compiler/implementation/ssa/ssa.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698