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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart

Issue 91103003: Use the integer type to get rid of above 0 checks in bounds checks. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years 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 | « no previous file | tests/compiler/dart2js/value_range2_test.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 part of ssa; 5 part of ssa;
6 6
7 7
8 class ValueRangeInfo { 8 class ValueRangeInfo {
9 final ConstantSystem constantSystem; 9 final ConstantSystem constantSystem;
10 10
11 IntValue intZero; 11 IntValue intZero;
12 IntValue intOne; 12 IntValue intOne;
13 13
14 ValueRangeInfo(this.constantSystem) { 14 ValueRangeInfo(this.constantSystem) {
15 intZero = newIntValue(0); 15 intZero = newIntValue(0);
16 intOne = newIntValue(1); 16 intOne = newIntValue(1);
17 } 17 }
18 18
19 Value newIntValue(int value) { 19 Value newIntValue(int value) {
20 return new IntValue(value, this); 20 return new IntValue(value, this);
21 } 21 }
22 22
23 Value newInstructionValue(HInstruction instruction) { 23 Value newInstructionValue(HInstruction instruction) {
24 return new InstructionValue(instruction, this); 24 return new InstructionValue(instruction, this);
25 } 25 }
26 26
27 Value newLengthValue(HInstruction instruction) { 27 Value newPositiveValue(HInstruction instruction) {
28 return new LengthValue(instruction, this); 28 return new PositiveValue(instruction, this);
29 } 29 }
30 30
31 Value newAddValue(Value left, Value right) { 31 Value newAddValue(Value left, Value right) {
32 return new AddValue(left, right, this); 32 return new AddValue(left, right, this);
33 } 33 }
34 34
35 Value newSubtractValue(Value left, Value right) { 35 Value newSubtractValue(Value left, Value right) {
36 return new SubtractValue(left, right, this); 36 return new SubtractValue(left, right, this);
37 } 37 }
38 38
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 return info.newNegateValue(this); 284 return info.newNegateValue(this);
285 } 285 }
286 286
287 bool get isNegative => false; 287 bool get isNegative => false;
288 bool get isPositive => false; 288 bool get isPositive => false;
289 289
290 String toString() => 'Instruction: $instruction'; 290 String toString() => 'Instruction: $instruction';
291 } 291 }
292 292
293 /** 293 /**
294 * Special value for instructions that represent the length of an 294 * Special value for instructions whose type is a positive integer.
295 * array. The difference with an [InstructionValue] is that we know
296 * the value is positive.
297 */ 295 */
298 class LengthValue extends InstructionValue { 296 class PositiveValue extends InstructionValue {
sra1 2013/11/27 20:29:36 Zero is possible, but is not positive. Perhaps lea
299 LengthValue(HInstruction instruction, info) : super(instruction, info); 297 PositiveValue(HInstruction instruction, info) : super(instruction, info);
300 bool get isPositive => true; 298 bool get isPositive => true;
301 String toString() => 'Length: $instruction';
302 } 299 }
303 300
304 /** 301 /**
305 * Represents a binary operation on two [Value], where the operation 302 * Represents a binary operation on two [Value], where the operation
306 * did not yield a canonical value. 303 * did not yield a canonical value.
307 */ 304 */
308 class BinaryOperationValue extends Value { 305 class BinaryOperationValue extends Value {
309 final Value left; 306 final Value left;
310 final Value right; 307 final Value right;
311 BinaryOperationValue(this.left, this.right, info) : super(info); 308 BinaryOperationValue(this.left, this.right, info) : super(info);
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 assert(range != null); 627 assert(range != null);
631 ranges[instruction] = range; 628 ranges[instruction] = range;
632 } 629 }
633 } 630 }
634 631
635 block.forEachPhi(visit); 632 block.forEachPhi(visit);
636 block.forEachInstruction(visit); 633 block.forEachInstruction(visit);
637 } 634 }
638 635
639 Range visitInstruction(HInstruction instruction) { 636 Range visitInstruction(HInstruction instruction) {
640 return info.newUnboundRange(); 637 if (instruction.isUInt32(compiler)) {
641 } 638 return info.newNormalizedRange(
642 639 info.intZero, info.newPositiveValue(instruction));
643 Range visitParameterValue(HParameterValue parameter) { 640 } else if (instruction.isInteger(compiler)) {
644 if (!parameter.isInteger(compiler)) return info.newUnboundRange(); 641 InstructionValue value = info.newInstructionValue(instruction);
645 Value value = info.newInstructionValue(parameter); 642 return info.newNormalizedRange(value, value);
646 return info.newNormalizedRange(value, value); 643 } else {
644 return info.newUnboundRange();
645 }
647 } 646 }
648 647
649 Range visitPhi(HPhi phi) { 648 Range visitPhi(HPhi phi) {
650 if (!phi.isInteger(compiler)) return info.newUnboundRange(); 649 if (!phi.isInteger(compiler)) return info.newUnboundRange();
651 // Some phases may replace instructions that change the inputs of 650 // Some phases may replace instructions that change the inputs of
652 // this phi. Only the [SsaTypesPropagation] phase will update the 651 // this phi. Only the [SsaTypesPropagation] phase will update the
653 // phi type. Play it safe by assuming the [SsaTypesPropagation] 652 // phi type. Play it safe by assuming the [SsaTypesPropagation]
654 // phase is not necessarily run before the [ValueRangeAnalyzer]. 653 // phase is not necessarily run before the [ValueRangeAnalyzer].
655 if (phi.inputs.any((i) => !i.isInteger(compiler))) { 654 if (phi.inputs.any((i) => !i.isInteger(compiler))) {
656 return info.newUnboundRange(); 655 return info.newUnboundRange();
(...skipping 18 matching lines...) Expand all
675 return info.newNormalizedRange(value, value); 674 return info.newNormalizedRange(value, value);
676 } 675 }
677 676
678 Range visitFieldGet(HFieldGet fieldGet) { 677 Range visitFieldGet(HFieldGet fieldGet) {
679 if (!fieldGet.isInteger(compiler)) return info.newUnboundRange(); 678 if (!fieldGet.isInteger(compiler)) return info.newUnboundRange();
680 if (!fieldGet.receiver.isIndexablePrimitive(compiler)) { 679 if (!fieldGet.receiver.isIndexablePrimitive(compiler)) {
681 return visitInstruction(fieldGet); 680 return visitInstruction(fieldGet);
682 } 681 }
683 JavaScriptBackend backend = compiler.backend; 682 JavaScriptBackend backend = compiler.backend;
684 assert(fieldGet.element == backend.jsIndexableLength); 683 assert(fieldGet.element == backend.jsIndexableLength);
685 LengthValue value = info.newLengthValue(fieldGet); 684 PositiveValue value = info.newPositiveValue(fieldGet);
686 // We know this range is above zero. To simplify the analysis, we 685 // We know this range is above zero. To simplify the analysis, we
687 // put the zero value as the lower bound of this range. This 686 // put the zero value as the lower bound of this range. This
688 // allows to easily remove the second bound check in the following 687 // allows to easily remove the second bound check in the following
689 // expression: a[1] + a[0]. 688 // expression: a[1] + a[0].
690 return info.newNormalizedRange(info.intZero, value); 689 return info.newNormalizedRange(info.intZero, value);
691 } 690 }
692 691
693 Range visitBoundsCheck(HBoundsCheck check) { 692 Range visitBoundsCheck(HBoundsCheck check) {
694 // Save the next instruction, in case the check gets removed. 693 // Save the next instruction, in case the check gets removed.
695 HInstruction next = check.next; 694 HInstruction next = check.next;
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 } 1007 }
1009 1008
1010 Range handleBinaryOperation(HBinaryArithmetic instruction) { 1009 Range handleBinaryOperation(HBinaryArithmetic instruction) {
1011 Range leftRange = visit(instruction.left); 1010 Range leftRange = visit(instruction.left);
1012 Range rightRange = visit(instruction.right); 1011 Range rightRange = visit(instruction.right);
1013 if (leftRange == null || rightRange == null) return null; 1012 if (leftRange == null || rightRange == null) return null;
1014 BinaryOperation operation = instruction.operation(info.constantSystem); 1013 BinaryOperation operation = instruction.operation(info.constantSystem);
1015 return operation.apply(leftRange, rightRange); 1014 return operation.apply(leftRange, rightRange);
1016 } 1015 }
1017 } 1016 }
OLDNEW
« no previous file with comments | « no previous file | tests/compiler/dart2js/value_range2_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698