OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_COMPILER_REPRESENTATION_CHANGE_H_ | 5 #ifndef V8_COMPILER_REPRESENTATION_CHANGE_H_ |
6 #define V8_COMPILER_REPRESENTATION_CHANGE_H_ | 6 #define V8_COMPILER_REPRESENTATION_CHANGE_H_ |
7 | 7 |
8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
9 #include "src/compiler/simplified-operator.h" | 9 #include "src/compiler/simplified-operator.h" |
10 | 10 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 | 66 |
67 explicit Truncation(TruncationKind kind) : kind_(kind) {} | 67 explicit Truncation(TruncationKind kind) : kind_(kind) {} |
68 TruncationKind kind() const { return kind_; } | 68 TruncationKind kind() const { return kind_; } |
69 | 69 |
70 TruncationKind kind_; | 70 TruncationKind kind_; |
71 | 71 |
72 static TruncationKind Generalize(TruncationKind rep1, TruncationKind rep2); | 72 static TruncationKind Generalize(TruncationKind rep1, TruncationKind rep2); |
73 static bool LessGeneral(TruncationKind rep1, TruncationKind rep2); | 73 static bool LessGeneral(TruncationKind rep1, TruncationKind rep2); |
74 }; | 74 }; |
75 | 75 |
| 76 enum class TypeCheckKind : uint8_t { |
| 77 kNone, |
| 78 kSigned32, |
| 79 kNumberOrUndefined, |
| 80 kNumber |
| 81 }; |
| 82 |
| 83 // The {UseInfo} class is used to describe a use of an input of a node. |
| 84 // |
| 85 // This information is used in two different ways, based on the phase: |
| 86 // |
| 87 // 1. During propagation, the use info is used to inform the input node |
| 88 // about what part of the input is used (we call this truncation) and what |
| 89 // is the preferred representation. |
| 90 // |
| 91 // 2. During lowering, the use info is used to properly convert the input |
| 92 // to the preferred representation. The preferred representation might be |
| 93 // insufficient to do the conversion (e.g. word32->float64 conv), so we also |
| 94 // need the signedness information to produce the correct value. |
| 95 class UseInfo { |
| 96 public: |
| 97 UseInfo(MachineRepresentation representation, Truncation truncation, |
| 98 TypeCheckKind type_check = TypeCheckKind::kNone) |
| 99 : representation_(representation), |
| 100 truncation_(truncation), |
| 101 type_check_(type_check) {} |
| 102 static UseInfo TruncatingWord32() { |
| 103 return UseInfo(MachineRepresentation::kWord32, Truncation::Word32()); |
| 104 } |
| 105 static UseInfo TruncatingWord64() { |
| 106 return UseInfo(MachineRepresentation::kWord64, Truncation::Word64()); |
| 107 } |
| 108 static UseInfo Bool() { |
| 109 return UseInfo(MachineRepresentation::kBit, Truncation::Bool()); |
| 110 } |
| 111 static UseInfo TruncatingFloat32() { |
| 112 return UseInfo(MachineRepresentation::kFloat32, Truncation::Float32()); |
| 113 } |
| 114 static UseInfo TruncatingFloat64() { |
| 115 return UseInfo(MachineRepresentation::kFloat64, Truncation::Float64()); |
| 116 } |
| 117 static UseInfo PointerInt() { |
| 118 return kPointerSize == 4 ? TruncatingWord32() : TruncatingWord64(); |
| 119 } |
| 120 static UseInfo AnyTagged() { |
| 121 return UseInfo(MachineRepresentation::kTagged, Truncation::Any()); |
| 122 } |
| 123 |
| 124 // Possibly deoptimizing conversions. |
| 125 static UseInfo CheckedSigned32AsWord32() { |
| 126 return UseInfo(MachineRepresentation::kWord32, Truncation::Any(), |
| 127 TypeCheckKind::kSigned32); |
| 128 } |
| 129 static UseInfo CheckedNumberOrUndefinedAsFloat64() { |
| 130 return UseInfo(MachineRepresentation::kFloat64, Truncation::Any(), |
| 131 TypeCheckKind::kNumberOrUndefined); |
| 132 } |
| 133 |
| 134 // Undetermined representation. |
| 135 static UseInfo Any() { |
| 136 return UseInfo(MachineRepresentation::kNone, Truncation::Any()); |
| 137 } |
| 138 static UseInfo AnyTruncatingToBool() { |
| 139 return UseInfo(MachineRepresentation::kNone, Truncation::Bool()); |
| 140 } |
| 141 |
| 142 // Value not used. |
| 143 static UseInfo None() { |
| 144 return UseInfo(MachineRepresentation::kNone, Truncation::None()); |
| 145 } |
| 146 |
| 147 MachineRepresentation representation() const { return representation_; } |
| 148 Truncation truncation() const { return truncation_; } |
| 149 TypeCheckKind type_check() const { return type_check_; } |
| 150 |
| 151 private: |
| 152 MachineRepresentation representation_; |
| 153 Truncation truncation_; |
| 154 TypeCheckKind type_check_; |
| 155 }; |
76 | 156 |
77 // Contains logic related to changing the representation of values for constants | 157 // Contains logic related to changing the representation of values for constants |
78 // and other nodes, as well as lowering Simplified->Machine operators. | 158 // and other nodes, as well as lowering Simplified->Machine operators. |
79 // Eagerly folds any representation changes for constants. | 159 // Eagerly folds any representation changes for constants. |
80 class RepresentationChanger final { | 160 class RepresentationChanger final { |
81 public: | 161 public: |
82 RepresentationChanger(JSGraph* jsgraph, Isolate* isolate) | 162 RepresentationChanger(JSGraph* jsgraph, Isolate* isolate) |
83 : jsgraph_(jsgraph), | 163 : jsgraph_(jsgraph), |
84 isolate_(isolate), | 164 isolate_(isolate), |
85 testing_type_errors_(false), | 165 testing_type_errors_(false), |
86 type_error_(false) {} | 166 type_error_(false) {} |
87 | 167 |
88 // Changes representation from {output_type} to {use_rep}. The {truncation} | 168 // Changes representation from {output_type} to {use_rep}. The {truncation} |
89 // parameter is only used for sanity checking - if the changer cannot figure | 169 // parameter is only used for sanity checking - if the changer cannot figure |
90 // out signedness for the word32->float64 conversion, then we check that the | 170 // out signedness for the word32->float64 conversion, then we check that the |
91 // uses truncate to word32 (so they do not care about signedness). | 171 // uses truncate to word32 (so they do not care about signedness). |
92 Node* GetRepresentationFor(Node* node, MachineRepresentation output_rep, | 172 Node* GetRepresentationFor(Node* node, MachineRepresentation output_rep, |
93 Type* output_type, MachineRepresentation use_rep, | 173 Type* output_type, Node* use_node, |
94 Truncation truncation = Truncation::None()); | 174 UseInfo use_info); |
95 const Operator* Int32OperatorFor(IrOpcode::Value opcode); | 175 const Operator* Int32OperatorFor(IrOpcode::Value opcode); |
| 176 const Operator* Int32OverflowOperatorFor(IrOpcode::Value opcode); |
96 const Operator* Uint32OperatorFor(IrOpcode::Value opcode); | 177 const Operator* Uint32OperatorFor(IrOpcode::Value opcode); |
97 const Operator* Float64OperatorFor(IrOpcode::Value opcode); | 178 const Operator* Float64OperatorFor(IrOpcode::Value opcode); |
98 | 179 |
99 MachineType TypeForBasePointer(const FieldAccess& access) { | 180 MachineType TypeForBasePointer(const FieldAccess& access) { |
100 return access.tag() != 0 ? MachineType::AnyTagged() | 181 return access.tag() != 0 ? MachineType::AnyTagged() |
101 : MachineType::Pointer(); | 182 : MachineType::Pointer(); |
102 } | 183 } |
103 | 184 |
104 MachineType TypeForBasePointer(const ElementAccess& access) { | 185 MachineType TypeForBasePointer(const ElementAccess& access) { |
105 return access.tag() != 0 ? MachineType::AnyTagged() | 186 return access.tag() != 0 ? MachineType::AnyTagged() |
106 : MachineType::Pointer(); | 187 : MachineType::Pointer(); |
107 } | 188 } |
108 | 189 |
109 private: | 190 private: |
110 JSGraph* jsgraph_; | 191 JSGraph* jsgraph_; |
111 Isolate* isolate_; | 192 Isolate* isolate_; |
112 | 193 |
113 friend class RepresentationChangerTester; // accesses the below fields. | 194 friend class RepresentationChangerTester; // accesses the below fields. |
114 | 195 |
115 bool testing_type_errors_; // If {true}, don't abort on a type error. | 196 bool testing_type_errors_; // If {true}, don't abort on a type error. |
116 bool type_error_; // Set when a type error is detected. | 197 bool type_error_; // Set when a type error is detected. |
117 | 198 |
118 Node* GetTaggedRepresentationFor(Node* node, MachineRepresentation output_rep, | 199 Node* GetTaggedRepresentationFor(Node* node, MachineRepresentation output_rep, |
119 Type* output_type); | 200 Type* output_type); |
120 Node* GetFloat32RepresentationFor(Node* node, | 201 Node* GetFloat32RepresentationFor(Node* node, |
121 MachineRepresentation output_rep, | 202 MachineRepresentation output_rep, |
122 Type* output_type, Truncation truncation); | 203 Type* output_type, Truncation truncation); |
123 Node* GetFloat64RepresentationFor(Node* node, | 204 Node* GetFloat64RepresentationFor(Node* node, |
124 MachineRepresentation output_rep, | 205 MachineRepresentation output_rep, |
125 Type* output_type, Truncation truncation); | 206 Type* output_type, Node* use_node, |
| 207 UseInfo use_info); |
126 Node* GetWord32RepresentationFor(Node* node, MachineRepresentation output_rep, | 208 Node* GetWord32RepresentationFor(Node* node, MachineRepresentation output_rep, |
127 Type* output_type, Truncation truncation); | 209 Type* output_type, Node* use_node, |
| 210 UseInfo use_info); |
128 Node* GetBitRepresentationFor(Node* node, MachineRepresentation output_rep, | 211 Node* GetBitRepresentationFor(Node* node, MachineRepresentation output_rep, |
129 Type* output_type); | 212 Type* output_type); |
130 Node* GetWord64RepresentationFor(Node* node, MachineRepresentation output_rep, | 213 Node* GetWord64RepresentationFor(Node* node, MachineRepresentation output_rep, |
131 Type* output_type); | 214 Type* output_type); |
| 215 Node* GetCheckedWord32RepresentationFor(Node* node, |
| 216 MachineRepresentation output_rep, |
| 217 Type* output_type, Node* use_node, |
| 218 Truncation truncation, |
| 219 TypeCheckKind check); |
132 Node* TypeError(Node* node, MachineRepresentation output_rep, | 220 Node* TypeError(Node* node, MachineRepresentation output_rep, |
133 Type* output_type, MachineRepresentation use); | 221 Type* output_type, MachineRepresentation use); |
134 Node* MakeTruncatedInt32Constant(double value); | 222 Node* MakeTruncatedInt32Constant(double value); |
135 Node* InsertChangeFloat32ToFloat64(Node* node); | 223 Node* InsertChangeFloat32ToFloat64(Node* node); |
136 Node* InsertChangeFloat64ToInt32(Node* node); | 224 Node* InsertChangeFloat64ToInt32(Node* node); |
137 Node* InsertChangeFloat64ToUint32(Node* node); | 225 Node* InsertChangeFloat64ToUint32(Node* node); |
138 Node* InsertChangeTaggedSignedToInt32(Node* node); | 226 Node* InsertChangeTaggedSignedToInt32(Node* node); |
139 Node* InsertChangeTaggedToFloat64(Node* node); | 227 Node* InsertChangeTaggedToFloat64(Node* node); |
140 | 228 |
| 229 Node* InsertConversion(Node* node, const Operator* op, Node* use_node); |
| 230 |
141 JSGraph* jsgraph() const { return jsgraph_; } | 231 JSGraph* jsgraph() const { return jsgraph_; } |
142 Isolate* isolate() const { return isolate_; } | 232 Isolate* isolate() const { return isolate_; } |
143 Factory* factory() const { return isolate()->factory(); } | 233 Factory* factory() const { return isolate()->factory(); } |
144 SimplifiedOperatorBuilder* simplified() { return jsgraph()->simplified(); } | 234 SimplifiedOperatorBuilder* simplified() { return jsgraph()->simplified(); } |
145 MachineOperatorBuilder* machine() { return jsgraph()->machine(); } | 235 MachineOperatorBuilder* machine() { return jsgraph()->machine(); } |
146 }; | 236 }; |
147 | 237 |
148 } // namespace compiler | 238 } // namespace compiler |
149 } // namespace internal | 239 } // namespace internal |
150 } // namespace v8 | 240 } // namespace v8 |
151 | 241 |
152 #endif // V8_COMPILER_REPRESENTATION_CHANGE_H_ | 242 #endif // V8_COMPILER_REPRESENTATION_CHANGE_H_ |
OLD | NEW |