| 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 |