OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 import 'optimizers.dart' show Pass, ParentVisitor; | 5 import 'optimizers.dart' show Pass, ParentVisitor; |
6 | 6 |
7 import '../constants/constant_system.dart'; | 7 import '../constants/constant_system.dart'; |
8 import '../constants/expressions.dart'; | 8 import '../constants/expressions.dart'; |
9 import '../resolution/operators.dart'; | 9 import '../resolution/operators.dart'; |
10 import '../constants/values.dart'; | 10 import '../constants/values.dart'; |
(...skipping 15 matching lines...) Expand all Loading... |
26 T get boolType; | 26 T get boolType; |
27 T get intType; | 27 T get intType; |
28 T get stringType; | 28 T get stringType; |
29 T get listType; | 29 T get listType; |
30 T get mapType; | 30 T get mapType; |
31 | 31 |
32 T getReturnType(FunctionElement element); | 32 T getReturnType(FunctionElement element); |
33 T getSelectorReturnType(Selector selector); | 33 T getSelectorReturnType(Selector selector); |
34 T getParameterType(ParameterElement element); | 34 T getParameterType(ParameterElement element); |
35 T join(T a, T b); | 35 T join(T a, T b); |
36 T typeOf(ConstantValue constant); | 36 T getTypeOf(ConstantValue constant); |
37 | 37 |
38 /// True if all values satisfying [type] are booleans (null is not a boolean). | 38 /// True if all values satisfying [type] are booleans (null is not a boolean). |
39 bool isDefinitelyBool(T type); | 39 bool isDefinitelyBool(T type); |
| 40 |
| 41 bool areDisjoint(T left, T right); |
40 } | 42 } |
41 | 43 |
42 class UnitTypeSystem implements TypeSystem<String> { | 44 class UnitTypeSystem implements TypeSystem<String> { |
43 static const String UNIT = 'unit'; | 45 static const String UNIT = 'unit'; |
44 | 46 |
45 get boolType => UNIT; | 47 get boolType => UNIT; |
46 get dynamicType => UNIT; | 48 get dynamicType => UNIT; |
47 get functionType => UNIT; | 49 get functionType => UNIT; |
48 get intType => UNIT; | 50 get intType => UNIT; |
49 get listType => UNIT; | 51 get listType => UNIT; |
50 get mapType => UNIT; | 52 get mapType => UNIT; |
51 get stringType => UNIT; | 53 get stringType => UNIT; |
52 get typeType => UNIT; | 54 get typeType => UNIT; |
53 | 55 |
54 getParameterType(_) => UNIT; | 56 getParameterType(_) => UNIT; |
55 getReturnType(_) => UNIT; | 57 getReturnType(_) => UNIT; |
56 getSelectorReturnType(_) => UNIT; | 58 getSelectorReturnType(_) => UNIT; |
57 join(a, b) => UNIT; | 59 join(a, b) => UNIT; |
58 typeOf(_) => UNIT; | 60 getTypeOf(_) => UNIT; |
59 | 61 |
60 bool isDefinitelyBool(_) => false; | 62 bool isDefinitelyBool(_) => false; |
| 63 |
| 64 @override |
| 65 bool areDisjoint(a, b) => false; |
61 } | 66 } |
62 | 67 |
63 class TypeMaskSystem implements TypeSystem<TypeMask> { | 68 class TypeMaskSystem implements TypeSystem<TypeMask> { |
64 final TypesTask inferrer; | 69 final TypesTask inferrer; |
65 final ClassWorld classWorld; | 70 final ClassWorld classWorld; |
66 | 71 |
67 TypeMask get dynamicType => inferrer.dynamicType; | 72 TypeMask get dynamicType => inferrer.dynamicType; |
68 TypeMask get typeType => inferrer.typeType; | 73 TypeMask get typeType => inferrer.typeType; |
69 TypeMask get functionType => inferrer.functionType; | 74 TypeMask get functionType => inferrer.functionType; |
70 TypeMask get boolType => inferrer.boolType; | 75 TypeMask get boolType => inferrer.boolType; |
(...skipping 18 matching lines...) Expand all Loading... |
89 TypeMask getSelectorReturnType(Selector selector) { | 94 TypeMask getSelectorReturnType(Selector selector) { |
90 return inferrer.getGuaranteedTypeOfSelector(selector); | 95 return inferrer.getGuaranteedTypeOfSelector(selector); |
91 } | 96 } |
92 | 97 |
93 @override | 98 @override |
94 TypeMask join(TypeMask a, TypeMask b) { | 99 TypeMask join(TypeMask a, TypeMask b) { |
95 return a.union(b, classWorld); | 100 return a.union(b, classWorld); |
96 } | 101 } |
97 | 102 |
98 @override | 103 @override |
99 TypeMask typeOf(ConstantValue constant) { | 104 TypeMask getTypeOf(ConstantValue constant) { |
100 return computeTypeMask(inferrer.compiler, constant); | 105 return computeTypeMask(inferrer.compiler, constant); |
101 } | 106 } |
102 | 107 |
103 bool isDefinitelyBool(TypeMask t) { | 108 bool isDefinitelyBool(TypeMask t) { |
104 return t.containsOnlyBool(classWorld) && !t.isNullable; | 109 return t.containsOnlyBool(classWorld) && !t.isNullable; |
105 } | 110 } |
| 111 |
| 112 bool areDisjoint(TypeMask left, TypeMask right) { |
| 113 TypeMask intersection = left.intersection(right, classWorld); |
| 114 return intersection.isEmpty && !intersection.isNullable; |
| 115 } |
106 } | 116 } |
107 | 117 |
108 /** | 118 /** |
109 * Propagates types (including value types for constants) throughout the IR, and | 119 * Propagates types (including value types for constants) throughout the IR, and |
110 * replaces branches with fixed jumps as well as side-effect free expressions | 120 * replaces branches with fixed jumps as well as side-effect free expressions |
111 * with known constant results. | 121 * with known constant results. |
112 * | 122 * |
113 * Should be followed by the [ShrinkingReducer] pass. | 123 * Should be followed by the [ShrinkingReducer] pass. |
114 * | 124 * |
115 * Implemented according to 'Constant Propagation with Conditional Branches' | 125 * Implemented according to 'Constant Propagation with Conditional Branches' |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
568 if (operation != null) { | 578 if (operation != null) { |
569 result = operation.fold(lhs.constant, rhs.constant); | 579 result = operation.fold(lhs.constant, rhs.constant); |
570 } | 580 } |
571 } | 581 } |
572 | 582 |
573 // Update value of the continuation parameter. Again, this is effectively | 583 // Update value of the continuation parameter. Again, this is effectively |
574 // a phi. | 584 // a phi. |
575 if (result == null) { | 585 if (result == null) { |
576 setValues(nonConstant()); | 586 setValues(nonConstant()); |
577 } else { | 587 } else { |
578 T type = typeSystem.typeOf(result); | 588 T type = typeSystem.getTypeOf(result); |
579 setValues(constantValue(result, type)); | 589 setValues(constantValue(result, type)); |
580 } | 590 } |
581 } | 591 } |
582 | 592 |
583 void visitInvokeMethodDirectly(InvokeMethodDirectly node) { | 593 void visitInvokeMethodDirectly(InvokeMethodDirectly node) { |
584 Continuation cont = node.continuation.definition; | 594 Continuation cont = node.continuation.definition; |
585 setReachable(cont); | 595 setReachable(cont); |
586 | 596 |
587 assert(cont.parameters.length == 1); | 597 assert(cont.parameters.length == 1); |
588 Parameter returnValue = cont.parameters[0]; | 598 Parameter returnValue = cont.parameters[0]; |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 } | 738 } |
729 | 739 |
730 void visitLiteralMap(LiteralMap node) { | 740 void visitLiteralMap(LiteralMap node) { |
731 // Constant maps are translated into (Constant MapConstant(...)) IR nodes, | 741 // Constant maps are translated into (Constant MapConstant(...)) IR nodes, |
732 // and thus LiteralMap nodes are NonConst. | 742 // and thus LiteralMap nodes are NonConst. |
733 setValue(node, nonConstant(typeSystem.mapType)); | 743 setValue(node, nonConstant(typeSystem.mapType)); |
734 } | 744 } |
735 | 745 |
736 void visitConstant(Constant node) { | 746 void visitConstant(Constant node) { |
737 ConstantValue value = node.value; | 747 ConstantValue value = node.value; |
738 setValue(node, constantValue(value, typeSystem.typeOf(value))); | 748 setValue(node, constantValue(value, typeSystem.getTypeOf(value))); |
739 } | 749 } |
740 | 750 |
741 void visitCreateFunction(CreateFunction node) { | 751 void visitCreateFunction(CreateFunction node) { |
742 setReachable(node.definition); | 752 setReachable(node.definition); |
743 ConstantValue constant = | 753 ConstantValue constant = |
744 new FunctionConstantValue(node.definition.element); | 754 new FunctionConstantValue(node.definition.element); |
745 setValue(node, constantValue(constant, typeSystem.functionType)); | 755 setValue(node, constantValue(constant, typeSystem.functionType)); |
746 } | 756 } |
747 | 757 |
748 void visitGetMutableVariable(GetMutableVariable node) { | 758 void visitGetMutableVariable(GetMutableVariable node) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
819 _AbstractValue<T> leftConst = getValue(node.left.definition); | 829 _AbstractValue<T> leftConst = getValue(node.left.definition); |
820 _AbstractValue<T> rightConst = getValue(node.right.definition); | 830 _AbstractValue<T> rightConst = getValue(node.right.definition); |
821 ConstantValue leftValue = leftConst.constant; | 831 ConstantValue leftValue = leftConst.constant; |
822 ConstantValue rightValue = rightConst.constant; | 832 ConstantValue rightValue = rightConst.constant; |
823 if (leftConst.isNothing || rightConst.isNothing) { | 833 if (leftConst.isNothing || rightConst.isNothing) { |
824 // Come back later. | 834 // Come back later. |
825 return; | 835 return; |
826 } else if (!leftConst.isConstant || !rightConst.isConstant) { | 836 } else if (!leftConst.isConstant || !rightConst.isConstant) { |
827 T leftType = leftConst.type; | 837 T leftType = leftConst.type; |
828 T rightType = rightConst.type; | 838 T rightType = rightConst.type; |
829 setValue(node, nonConstant(typeSystem.boolType)); | 839 if (typeSystem.areDisjoint(leftType, rightType)) { |
| 840 setValue(node, |
| 841 constantValue(new FalseConstantValue(), typeSystem.boolType)); |
| 842 } else { |
| 843 setValue(node, nonConstant(typeSystem.boolType)); |
| 844 } |
830 } else if (leftValue.isPrimitive && rightValue.isPrimitive) { | 845 } else if (leftValue.isPrimitive && rightValue.isPrimitive) { |
831 assert(leftConst.isConstant && rightConst.isConstant); | 846 assert(leftConst.isConstant && rightConst.isConstant); |
832 PrimitiveConstantValue left = leftValue; | 847 PrimitiveConstantValue left = leftValue; |
833 PrimitiveConstantValue right = rightValue; | 848 PrimitiveConstantValue right = rightValue; |
834 ConstantValue result = | 849 ConstantValue result = |
835 new BoolConstantValue(left.primitiveValue == right.primitiveValue); | 850 new BoolConstantValue(left.primitiveValue == right.primitiveValue); |
836 setValue(node, constantValue(result, typeSystem.boolType)); | 851 setValue(node, constantValue(result, typeSystem.boolType)); |
837 } | 852 } |
838 } | 853 } |
839 | 854 |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 ConstantExpression visitString(StringConstantValue constant, arg) { | 1043 ConstantExpression visitString(StringConstantValue constant, arg) { |
1029 return new StringConstantExpression( | 1044 return new StringConstantExpression( |
1030 constant.primitiveValue.slowToString(), constant); | 1045 constant.primitiveValue.slowToString(), constant); |
1031 } | 1046 } |
1032 | 1047 |
1033 @override | 1048 @override |
1034 ConstantExpression visitType(TypeConstantValue constant, arg) { | 1049 ConstantExpression visitType(TypeConstantValue constant, arg) { |
1035 throw new UnsupportedError("ConstantExpressionCreator.visitType"); | 1050 throw new UnsupportedError("ConstantExpressionCreator.visitType"); |
1036 } | 1051 } |
1037 } | 1052 } |
OLD | NEW |