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 part of ssa; | 5 part of ssa; |
6 | 6 |
7 abstract class HVisitor<R> { | 7 abstract class HVisitor<R> { |
8 R visitAdd(HAdd node); | 8 R visitAdd(HAdd node); |
9 R visitBitAnd(HBitAnd node); | 9 R visitBitAnd(HBitAnd node); |
10 R visitBitNot(HBitNot node); | 10 R visitBitNot(HBitNot node); |
(...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 : id = idCounter++, usedBy = <HInstruction>[] { | 809 : id = idCounter++, usedBy = <HInstruction>[] { |
810 assert(inputs.every((e) => e != null)); | 810 assert(inputs.every((e) => e != null)); |
811 } | 811 } |
812 | 812 |
813 int get hashCode => id; | 813 int get hashCode => id; |
814 | 814 |
815 bool useGvn() => _useGvn; | 815 bool useGvn() => _useGvn; |
816 void setUseGvn() { _useGvn = true; } | 816 void setUseGvn() { _useGvn = true; } |
817 void clearUseGvn() { _useGvn = false; } | 817 void clearUseGvn() { _useGvn = false; } |
818 | 818 |
| 819 bool get isMovable => useGvn(); |
| 820 |
819 /** | 821 /** |
820 * A pure instruction is an instruction that does not have any side | 822 * A pure instruction is an instruction that does not have any side |
821 * effect, nor any dependency. They can be moved anywhere in the | 823 * effect, nor any dependency. They can be moved anywhere in the |
822 * graph. | 824 * graph. |
823 */ | 825 */ |
824 bool isPure() { | 826 bool isPure() { |
825 return !sideEffects.hasSideEffects() | 827 return !sideEffects.hasSideEffects() |
826 && !sideEffects.dependsOnSomething() | 828 && !sideEffects.dependsOnSomething() |
827 && !canThrow(); | 829 && !canThrow(); |
828 } | 830 } |
(...skipping 1628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2457 bool isJsStatement() => isControlFlow(); | 2459 bool isJsStatement() => isControlFlow(); |
2458 bool isControlFlow() => isArgumentTypeCheck || isReceiverTypeCheck; | 2460 bool isControlFlow() => isArgumentTypeCheck || isReceiverTypeCheck; |
2459 | 2461 |
2460 int typeCode() => HInstruction.TYPE_CONVERSION_TYPECODE; | 2462 int typeCode() => HInstruction.TYPE_CONVERSION_TYPECODE; |
2461 bool typeEquals(HInstruction other) => other is HTypeConversion; | 2463 bool typeEquals(HInstruction other) => other is HTypeConversion; |
2462 bool isCodeMotionInvariant() => false; | 2464 bool isCodeMotionInvariant() => false; |
2463 | 2465 |
2464 bool dataEquals(HTypeConversion other) { | 2466 bool dataEquals(HTypeConversion other) { |
2465 return kind == other.kind | 2467 return kind == other.kind |
2466 && typeExpression == other.typeExpression | 2468 && typeExpression == other.typeExpression |
2467 && checkedType == other.checkedType; | 2469 && checkedType == other.checkedType |
| 2470 && receiverTypeCheckSelector == other.receiverTypeCheckSelector; |
2468 } | 2471 } |
2469 } | 2472 } |
2470 | 2473 |
2471 /// The [HTypeKnown] instruction marks a value with a refined type. | 2474 /// The [HTypeKnown] instruction marks a value with a refined type. |
2472 class HTypeKnown extends HCheck { | 2475 class HTypeKnown extends HCheck { |
2473 TypeMask knownType; | 2476 TypeMask knownType; |
2474 HTypeKnown(TypeMask knownType, HInstruction input) | 2477 bool _isMovable; |
| 2478 |
| 2479 HTypeKnown.pinned(TypeMask knownType, HInstruction input) |
2475 : this.knownType = knownType, | 2480 : this.knownType = knownType, |
| 2481 this._isMovable = false, |
2476 super(<HInstruction>[input], knownType); | 2482 super(<HInstruction>[input], knownType); |
| 2483 |
| 2484 HTypeKnown.witnessed(TypeMask knownType, HInstruction input, |
| 2485 HInstruction witness) |
| 2486 : this.knownType = knownType, |
| 2487 this._isMovable = true, |
| 2488 super(<HInstruction>[input, witness], knownType); |
| 2489 |
2477 toString() => 'TypeKnown $knownType'; | 2490 toString() => 'TypeKnown $knownType'; |
2478 accept(HVisitor visitor) => visitor.visitTypeKnown(this); | 2491 accept(HVisitor visitor) => visitor.visitTypeKnown(this); |
2479 | 2492 |
2480 bool isJsStatement() => false; | 2493 bool isJsStatement() => false; |
2481 bool isControlFlow() => false; | 2494 bool isControlFlow() => false; |
2482 bool canThrow() => false; | 2495 bool canThrow() => false; |
2483 | 2496 |
2484 int typeCode() => HInstruction.TYPE_KNOWN_TYPECODE; | 2497 int typeCode() => HInstruction.TYPE_KNOWN_TYPECODE; |
2485 bool typeEquals(HInstruction other) => other is HTypeKnown; | 2498 bool typeEquals(HInstruction other) => other is HTypeKnown; |
2486 bool isCodeMotionInvariant() => true; | 2499 bool isCodeMotionInvariant() => true; |
| 2500 bool get isMovable => _isMovable && useGvn(); |
2487 | 2501 |
2488 bool dataEquals(HTypeKnown other) { | 2502 bool dataEquals(HTypeKnown other) { |
2489 return knownType == other.knownType | 2503 return knownType == other.knownType |
2490 && instructionType == other.instructionType; | 2504 && instructionType == other.instructionType; |
2491 } | 2505 } |
2492 } | 2506 } |
2493 | 2507 |
2494 class HRangeConversion extends HCheck { | 2508 class HRangeConversion extends HCheck { |
2495 HRangeConversion(HInstruction input, type) | 2509 HRangeConversion(HInstruction input, type) |
2496 : super(<HInstruction>[input], type) { | 2510 : super(<HInstruction>[input], type) { |
2497 sourceElement = input.sourceElement; | 2511 sourceElement = input.sourceElement; |
2498 } | 2512 } |
| 2513 |
| 2514 bool get isMovable => false; |
| 2515 |
2499 accept(HVisitor visitor) => visitor.visitRangeConversion(this); | 2516 accept(HVisitor visitor) => visitor.visitRangeConversion(this); |
2500 } | 2517 } |
2501 | 2518 |
2502 class HStringConcat extends HInstruction { | 2519 class HStringConcat extends HInstruction { |
2503 final ast.Node node; | 2520 final ast.Node node; |
2504 HStringConcat(HInstruction left, HInstruction right, this.node, TypeMask type) | 2521 HStringConcat(HInstruction left, HInstruction right, this.node, TypeMask type) |
2505 : super(<HInstruction>[left, right], type) { | 2522 : super(<HInstruction>[left, right], type) { |
2506 // TODO(sra): Until Issue 9293 is fixed, this false dependency keeps the | 2523 // TODO(sra): Until Issue 9293 is fixed, this false dependency keeps the |
2507 // concats bunched with stringified inputs for much better looking code with | 2524 // concats bunched with stringified inputs for much better looking code with |
2508 // fewer temps. | 2525 // fewer temps. |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2949 class HDynamicType extends HRuntimeType { | 2966 class HDynamicType extends HRuntimeType { |
2950 HDynamicType(DynamicType dartType, TypeMask instructionType) | 2967 HDynamicType(DynamicType dartType, TypeMask instructionType) |
2951 : super(const <HInstruction>[], dartType, instructionType); | 2968 : super(const <HInstruction>[], dartType, instructionType); |
2952 | 2969 |
2953 accept(HVisitor visitor) => visitor.visitDynamicType(this); | 2970 accept(HVisitor visitor) => visitor.visitDynamicType(this); |
2954 | 2971 |
2955 int typeCode() => HInstruction.DYNAMIC_TYPE_TYPECODE; | 2972 int typeCode() => HInstruction.DYNAMIC_TYPE_TYPECODE; |
2956 | 2973 |
2957 bool typeEquals(HInstruction other) => other is HDynamicType; | 2974 bool typeEquals(HInstruction other) => other is HDynamicType; |
2958 } | 2975 } |
OLD | NEW |