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 #include "src/compiler/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 // 1. During propagation, the use info is used to inform the input node | 66 // 1. During propagation, the use info is used to inform the input node |
67 // about what part of the input is used (we call this truncation) and what | 67 // about what part of the input is used (we call this truncation) and what |
68 // is the preferred representation. | 68 // is the preferred representation. |
69 // | 69 // |
70 // 2. During lowering, the use info is used to properly convert the input | 70 // 2. During lowering, the use info is used to properly convert the input |
71 // to the preferred representation. The preferred representation might be | 71 // to the preferred representation. The preferred representation might be |
72 // insufficient to do the conversion (e.g. word32->float64 conv), so we also | 72 // insufficient to do the conversion (e.g. word32->float64 conv), so we also |
73 // need the signedness information to produce the correct value. | 73 // need the signedness information to produce the correct value. |
74 class UseInfo { | 74 class UseInfo { |
75 public: | 75 public: |
76 UseInfo(MachineType preferred, Truncation truncation) | 76 UseInfo(MachineRepresentation preferred, Truncation truncation) |
77 : preferred_(preferred), truncation_(truncation) { | 77 : preferred_(preferred), truncation_(truncation) {} |
78 DCHECK(preferred == (preferred & kRepMask)); | |
79 } | |
80 static UseInfo TruncatingWord32() { | 78 static UseInfo TruncatingWord32() { |
81 return UseInfo(kRepWord32, Truncation::Word32()); | 79 return UseInfo(MachineRepresentation::kWord32, Truncation::Word32()); |
82 } | 80 } |
83 static UseInfo TruncatingWord64() { | 81 static UseInfo TruncatingWord64() { |
84 return UseInfo(kRepWord64, Truncation::Word64()); | 82 return UseInfo(MachineRepresentation::kWord64, Truncation::Word64()); |
85 } | 83 } |
86 static UseInfo Bool() { return UseInfo(kRepBit, Truncation::Bool()); } | 84 static UseInfo Bool() { |
| 85 return UseInfo(MachineRepresentation::kBit, Truncation::Bool()); |
| 86 } |
87 static UseInfo Float32() { | 87 static UseInfo Float32() { |
88 return UseInfo(kRepFloat32, Truncation::Float32()); | 88 return UseInfo(MachineRepresentation::kFloat32, Truncation::Float32()); |
89 } | 89 } |
90 static UseInfo Float64() { | 90 static UseInfo Float64() { |
91 return UseInfo(kRepFloat64, Truncation::Float64()); | 91 return UseInfo(MachineRepresentation::kFloat64, Truncation::Float64()); |
92 } | 92 } |
93 static UseInfo PointerInt() { | 93 static UseInfo PointerInt() { |
94 return kPointerSize == 4 ? TruncatingWord32() : TruncatingWord64(); | 94 return kPointerSize == 4 ? TruncatingWord32() : TruncatingWord64(); |
95 } | 95 } |
96 static UseInfo AnyTagged() { return UseInfo(kRepTagged, Truncation::Any()); } | 96 static UseInfo AnyTagged() { |
| 97 return UseInfo(MachineRepresentation::kTagged, Truncation::Any()); |
| 98 } |
97 | 99 |
98 // Undetermined representation. | 100 // Undetermined representation. |
99 static UseInfo Any() { return UseInfo(kMachNone, Truncation::Any()); } | 101 static UseInfo Any() { |
100 static UseInfo None() { return UseInfo(kMachNone, Truncation::None()); } | 102 return UseInfo(MachineRepresentation::kNone, Truncation::Any()); |
| 103 } |
| 104 static UseInfo None() { |
| 105 return UseInfo(MachineRepresentation::kNone, Truncation::None()); |
| 106 } |
101 | 107 |
102 // Truncation to a representation that is smaller than the preferred | 108 // Truncation to a representation that is smaller than the preferred |
103 // one. | 109 // one. |
104 static UseInfo Float64TruncatingToWord32() { | 110 static UseInfo Float64TruncatingToWord32() { |
105 return UseInfo(kRepFloat64, Truncation::Word32()); | 111 return UseInfo(MachineRepresentation::kFloat64, Truncation::Word32()); |
106 } | 112 } |
107 static UseInfo Word64TruncatingToWord32() { | 113 static UseInfo Word64TruncatingToWord32() { |
108 return UseInfo(kRepWord64, Truncation::Word32()); | 114 return UseInfo(MachineRepresentation::kWord64, Truncation::Word32()); |
109 } | 115 } |
110 static UseInfo AnyTruncatingToBool() { | 116 static UseInfo AnyTruncatingToBool() { |
111 return UseInfo(kMachNone, Truncation::Bool()); | 117 return UseInfo(MachineRepresentation::kNone, Truncation::Bool()); |
112 } | 118 } |
113 | 119 |
114 MachineType preferred() const { return preferred_; } | 120 MachineRepresentation preferred() const { return preferred_; } |
115 Truncation truncation() const { return truncation_; } | 121 Truncation truncation() const { return truncation_; } |
116 | 122 |
117 private: | 123 private: |
118 MachineType preferred_; | 124 MachineRepresentation preferred_; |
119 Truncation truncation_; | 125 Truncation truncation_; |
120 }; | 126 }; |
121 | 127 |
122 | 128 |
123 UseInfo UseInfoFromMachineType(MachineType type) { | 129 UseInfo TruncatingUseInfoFromRepresentation(MachineRepresentation rep) { |
124 MachineTypeUnion rep = RepresentationOf(type); | 130 switch (rep) { |
125 DCHECK((rep & kTypeMask) == 0); | 131 case MachineRepresentation::kTagged: |
126 | 132 return UseInfo::AnyTagged(); |
127 if (rep & kRepTagged) return UseInfo::AnyTagged(); | 133 case MachineRepresentation::kFloat64: |
128 if (rep & kRepFloat64) { | |
129 DCHECK((rep & kRepWord64) == 0); | |
130 return UseInfo::Float64(); | 134 return UseInfo::Float64(); |
| 135 case MachineRepresentation::kFloat32: |
| 136 return UseInfo::Float32(); |
| 137 case MachineRepresentation::kWord64: |
| 138 return UseInfo::TruncatingWord64(); |
| 139 case MachineRepresentation::kWord8: |
| 140 case MachineRepresentation::kWord16: |
| 141 case MachineRepresentation::kWord32: |
| 142 return UseInfo::TruncatingWord32(); |
| 143 case MachineRepresentation::kBit: |
| 144 return UseInfo::Bool(); |
| 145 case MachineRepresentation::kNone: |
| 146 break; |
131 } | 147 } |
132 if (rep & kRepFloat32) { | 148 UNREACHABLE(); |
133 if (rep == kRepFloat32) return UseInfo::Float32(); | 149 return UseInfo::None(); |
134 return UseInfo::AnyTagged(); | |
135 } | |
136 if (rep & kRepWord64) { | |
137 return UseInfo::TruncatingWord64(); | |
138 } | |
139 if (rep & (kRepWord32 | kRepWord16 | kRepWord8)) { | |
140 CHECK(!(rep & kRepBit)); | |
141 return UseInfo::TruncatingWord32(); | |
142 } | |
143 DCHECK(rep & kRepBit); | |
144 return UseInfo::Bool(); | |
145 } | 150 } |
146 | 151 |
147 | 152 |
148 UseInfo UseInfoForBasePointer(const FieldAccess& access) { | 153 UseInfo UseInfoForBasePointer(const FieldAccess& access) { |
149 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); | 154 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); |
150 } | 155 } |
151 | 156 |
152 | 157 |
153 UseInfo UseInfoForBasePointer(const ElementAccess& access) { | 158 UseInfo UseInfoForBasePointer(const ElementAccess& access) { |
154 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); | 159 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); |
155 } | 160 } |
156 | 161 |
157 | 162 |
158 #ifdef DEBUG | 163 #ifdef DEBUG |
159 // Helpers for monotonicity checking. | 164 // Helpers for monotonicity checking. |
160 | 165 |
161 bool MachineTypeIsSubtype(MachineType t1, MachineType t2) { | 166 bool MachineTypeIsSubtype(MachineSemantic t1, MachineSemantic t2) { |
162 switch (t1) { | 167 switch (t1) { |
163 case kMachNone: | 168 case MachineSemantic::kNone: |
164 return true; | 169 return true; |
165 case kTypeBool: | 170 case MachineSemantic::kBool: |
166 return t2 == kTypeBool || t2 == kTypeNumber || t2 == kTypeAny; | 171 return t2 == MachineSemantic::kBool || t2 == MachineSemantic::kNumber || |
167 case kTypeInt32: | 172 t2 == MachineSemantic::kAny; |
168 return t2 == kTypeInt32 || t2 == kTypeNumber || t2 == kTypeAny; | 173 case MachineSemantic::kInt32: |
169 case kTypeUint32: | 174 return t2 == MachineSemantic::kInt32 || t2 == MachineSemantic::kNumber || |
170 return t2 == kTypeUint32 || t2 == kTypeNumber || t2 == kTypeAny; | 175 t2 == MachineSemantic::kAny; |
171 case kTypeInt64: | 176 case MachineSemantic::kUint32: |
172 return t2 == kTypeInt64; | 177 return t2 == MachineSemantic::kUint32 || t2 == MachineSemantic::kNumber || |
173 case kTypeUint64: | 178 t2 == MachineSemantic::kAny; |
174 return t2 == kTypeUint64; | 179 case MachineSemantic::kInt64: |
175 case kTypeNumber: | 180 return t2 == MachineSemantic::kInt64; |
176 return t2 == kTypeNumber || t2 == kTypeAny; | 181 case MachineSemantic::kUint64: |
177 case kTypeAny: | 182 return t2 == MachineSemantic::kUint64; |
178 return t2 == kTypeAny; | 183 case MachineSemantic::kNumber: |
| 184 return t2 == MachineSemantic::kNumber || t2 == MachineSemantic::kAny; |
| 185 case MachineSemantic::kAny: |
| 186 return t2 == MachineSemantic::kAny; |
179 default: | 187 default: |
180 break; | 188 break; |
181 } | 189 } |
182 UNREACHABLE(); | 190 UNREACHABLE(); |
183 return false; | 191 return false; |
184 } | 192 } |
185 | 193 |
186 | 194 |
187 bool MachineRepresentationIsSubtype(MachineType r1, MachineType r2) { | 195 bool MachineRepresentationIsSubtype(MachineRepresentation r1, |
| 196 MachineRepresentation r2) { |
188 switch (r1) { | 197 switch (r1) { |
189 case kMachNone: | 198 case MachineRepresentation::kNone: |
190 return true; | 199 return true; |
191 case kRepBit: | 200 case MachineRepresentation::kBit: |
192 return r2 == kRepBit || r2 == kRepTagged; | 201 return r2 == MachineRepresentation::kBit || |
193 case kRepWord8: | 202 r2 == MachineRepresentation::kTagged; |
194 return r2 == kRepWord8 || r2 == kRepWord16 || r2 == kRepWord32 || | 203 case MachineRepresentation::kWord8: |
195 r2 == kRepWord64 || r2 == kRepFloat32 || r2 == kRepFloat64 || | 204 return r2 == MachineRepresentation::kWord8 || |
196 r2 == kRepTagged; | 205 r2 == MachineRepresentation::kWord16 || |
197 case kRepWord16: | 206 r2 == MachineRepresentation::kWord32 || |
198 return r2 == kRepWord16 || r2 == kRepWord32 || r2 == kRepWord64 || | 207 r2 == MachineRepresentation::kWord64 || |
199 r2 == kRepFloat32 || r2 == kRepFloat64 || r2 == kRepTagged; | 208 r2 == MachineRepresentation::kFloat32 || |
200 case kRepWord32: | 209 r2 == MachineRepresentation::kFloat64 || |
201 return r2 == kRepWord32 || r2 == kRepWord64 || r2 == kRepFloat64 || | 210 r2 == MachineRepresentation::kTagged; |
202 r2 == kRepTagged; | 211 case MachineRepresentation::kWord16: |
203 case kRepWord64: | 212 return r2 == MachineRepresentation::kWord16 || |
204 return r2 == kRepWord64; | 213 r2 == MachineRepresentation::kWord32 || |
205 case kRepFloat32: | 214 r2 == MachineRepresentation::kWord64 || |
206 return r2 == kRepFloat32 || r2 == kRepFloat64 || r2 == kRepTagged; | 215 r2 == MachineRepresentation::kFloat32 || |
207 case kRepFloat64: | 216 r2 == MachineRepresentation::kFloat64 || |
208 return r2 == kRepFloat64 || r2 == kRepTagged; | 217 r2 == MachineRepresentation::kTagged; |
209 case kRepTagged: | 218 case MachineRepresentation::kWord32: |
210 return r2 == kRepTagged; | 219 return r2 == MachineRepresentation::kWord32 || |
| 220 r2 == MachineRepresentation::kWord64 || |
| 221 r2 == MachineRepresentation::kFloat64 || |
| 222 r2 == MachineRepresentation::kTagged; |
| 223 case MachineRepresentation::kWord64: |
| 224 return r2 == MachineRepresentation::kWord64; |
| 225 case MachineRepresentation::kFloat32: |
| 226 return r2 == MachineRepresentation::kFloat32 || |
| 227 r2 == MachineRepresentation::kFloat64 || |
| 228 r2 == MachineRepresentation::kTagged; |
| 229 case MachineRepresentation::kFloat64: |
| 230 return r2 == MachineRepresentation::kFloat64 || |
| 231 r2 == MachineRepresentation::kTagged; |
| 232 case MachineRepresentation::kTagged: |
| 233 return r2 == MachineRepresentation::kTagged; |
211 default: | 234 default: |
212 break; | 235 break; |
213 } | 236 } |
214 UNREACHABLE(); | 237 UNREACHABLE(); |
215 return false; | 238 return false; |
216 } | 239 } |
217 | 240 |
218 | 241 |
219 bool MachineTypeRepIsSubtype(MachineTypeUnion m1, MachineTypeUnion m2) { | 242 bool MachineTypeRepIsSubtype(MachineType m1, MachineType m2) { |
220 return MachineTypeIsSubtype(static_cast<MachineType>(m1 & kTypeMask), | 243 return MachineTypeIsSubtype(m1.semantic(), m2.semantic()) && |
221 static_cast<MachineType>(m2 & kTypeMask)) && | 244 MachineRepresentationIsSubtype(m1.representation(), |
222 MachineRepresentationIsSubtype( | 245 m2.representation()); |
223 static_cast<MachineType>(m1 & kRepMask), | |
224 static_cast<MachineType>(m2 & kRepMask)); | |
225 } | 246 } |
226 | 247 |
227 | 248 |
228 class InputUseInfos { | 249 class InputUseInfos { |
229 public: | 250 public: |
230 explicit InputUseInfos(Zone* zone) : input_use_infos_(zone) {} | 251 explicit InputUseInfos(Zone* zone) : input_use_infos_(zone) {} |
231 | 252 |
232 void SetAndCheckInput(Node* node, int index, UseInfo use_info) { | 253 void SetAndCheckInput(Node* node, int index, UseInfo use_info) { |
233 if (input_use_infos_.empty()) { | 254 if (input_use_infos_.empty()) { |
234 input_use_infos_.resize(node->InputCount(), UseInfo::None()); | 255 input_use_infos_.resize(node->InputCount(), UseInfo::None()); |
(...skipping 29 matching lines...) Expand all Loading... |
264 Truncation old_truncation = truncation_; | 285 Truncation old_truncation = truncation_; |
265 truncation_ = Truncation::Generalize(truncation_, info.truncation()); | 286 truncation_ = Truncation::Generalize(truncation_, info.truncation()); |
266 return truncation_ != old_truncation; | 287 return truncation_ != old_truncation; |
267 } | 288 } |
268 | 289 |
269 void set_queued(bool value) { queued_ = value; } | 290 void set_queued(bool value) { queued_ = value; } |
270 bool queued() const { return queued_; } | 291 bool queued() const { return queued_; } |
271 void set_visited() { visited_ = true; } | 292 void set_visited() { visited_ = true; } |
272 bool visited() const { return visited_; } | 293 bool visited() const { return visited_; } |
273 Truncation truncation() const { return truncation_; } | 294 Truncation truncation() const { return truncation_; } |
274 void set_output_type(MachineTypeUnion type) { output_ = type; } | 295 void set_output_type(MachineType type) { output_ = type; } |
275 MachineTypeUnion output_type() const { return output_; } | 296 MachineType output_type() const { return output_; } |
276 | 297 |
277 private: | 298 private: |
278 bool queued_ = false; // Bookkeeping for the traversal. | 299 bool queued_ = false; // Bookkeeping for the traversal. |
279 bool visited_ = false; // Bookkeeping for the traversal. | 300 bool visited_ = false; // Bookkeeping for the traversal. |
280 MachineTypeUnion output_ = kMachNone; // Output type of the node. | 301 MachineType output_ = MachineType::None(); // Output type of the node. |
281 Truncation truncation_ = Truncation::None(); // Information about uses. | 302 Truncation truncation_ = Truncation::None(); // Information about uses. |
282 }; | 303 }; |
283 | 304 |
284 RepresentationSelector(JSGraph* jsgraph, Zone* zone, | 305 RepresentationSelector(JSGraph* jsgraph, Zone* zone, |
285 RepresentationChanger* changer, | 306 RepresentationChanger* changer, |
286 SourcePositionTable* source_positions) | 307 SourcePositionTable* source_positions) |
287 : jsgraph_(jsgraph), | 308 : jsgraph_(jsgraph), |
288 count_(jsgraph->graph()->NodeCount()), | 309 count_(jsgraph->graph()->NodeCount()), |
289 info_(count_, zone), | 310 info_(count_, zone), |
290 #ifdef DEBUG | 311 #ifdef DEBUG |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 TRACE(" added: "); | 408 TRACE(" added: "); |
388 } else { | 409 } else { |
389 TRACE(" inqueue: "); | 410 TRACE(" inqueue: "); |
390 } | 411 } |
391 PrintTruncation(info->truncation()); | 412 PrintTruncation(info->truncation()); |
392 } | 413 } |
393 } | 414 } |
394 | 415 |
395 bool lower() { return phase_ == LOWER; } | 416 bool lower() { return phase_ == LOWER; } |
396 | 417 |
397 void SetOutput(Node* node, MachineTypeUnion output) { | 418 void SetOutput(Node* node, MachineType output) { |
398 // Every node should have at most one output representation. Note that | 419 // Every node should have at most one output representation. Note that |
399 // phis can have 0, if they have not been used in a representation-inducing | 420 // phis can have 0, if they have not been used in a representation-inducing |
400 // instruction. | 421 // instruction. |
401 DCHECK((output & kRepMask) == 0 || | |
402 base::bits::IsPowerOfTwo32(output & kRepMask)); | |
403 NodeInfo* info = GetInfo(node); | 422 NodeInfo* info = GetInfo(node); |
404 DCHECK(MachineTypeRepIsSubtype(info->output_type(), output)); | 423 DCHECK(MachineTypeRepIsSubtype(info->output_type(), output)); |
405 info->set_output_type(output); | 424 info->set_output_type(output); |
406 } | 425 } |
407 | 426 |
408 bool BothInputsAre(Node* node, Type* type) { | 427 bool BothInputsAre(Node* node, Type* type) { |
409 DCHECK_EQ(2, node->InputCount()); | 428 DCHECK_EQ(2, node->InputCount()); |
410 return NodeProperties::GetType(node->InputAt(0))->Is(type) && | 429 return NodeProperties::GetType(node->InputAt(0))->Is(type) && |
411 NodeProperties::GetType(node->InputAt(1))->Is(type); | 430 NodeProperties::GetType(node->InputAt(1))->Is(type); |
412 } | 431 } |
413 | 432 |
414 void ConvertInput(Node* node, int index, UseInfo use) { | 433 void ConvertInput(Node* node, int index, UseInfo use) { |
415 Node* input = node->InputAt(index); | 434 Node* input = node->InputAt(index); |
416 // In the change phase, insert a change before the use if necessary. | 435 // In the change phase, insert a change before the use if necessary. |
417 if (use.preferred() == kMachNone) | 436 if (use.preferred() == MachineRepresentation::kNone) |
418 return; // No input requirement on the use. | 437 return; // No input requirement on the use. |
419 MachineTypeUnion output = GetInfo(input)->output_type(); | 438 MachineType output = GetInfo(input)->output_type(); |
420 if ((output & kRepMask) != use.preferred()) { | 439 if (output.representation() != use.preferred()) { |
421 // Output representation doesn't match usage. | 440 // Output representation doesn't match usage. |
422 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(), | 441 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(), |
423 index, input->id(), input->op()->mnemonic()); | 442 index, input->id(), input->op()->mnemonic()); |
424 TRACE(" from "); | 443 TRACE(" from "); |
425 PrintInfo(output); | 444 PrintInfo(output); |
426 TRACE(" to "); | 445 TRACE(" to "); |
427 PrintUseInfo(use); | 446 PrintUseInfo(use); |
428 TRACE("\n"); | 447 TRACE("\n"); |
429 Node* n = changer_->GetRepresentationFor(input, output, use.preferred(), | 448 Node* n = changer_->GetRepresentationFor(input, output, use.preferred(), |
430 use.truncation()); | 449 use.truncation()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 ProcessInput(node, i, UseInfo::AnyTagged()); | 484 ProcessInput(node, i, UseInfo::AnyTagged()); |
466 } | 485 } |
467 // Only enqueue other inputs (framestates, effects, control). | 486 // Only enqueue other inputs (framestates, effects, control). |
468 for (int i = tagged_count; i < node->InputCount(); i++) { | 487 for (int i = tagged_count; i < node->InputCount(); i++) { |
469 EnqueueInput(node, i); | 488 EnqueueInput(node, i); |
470 } | 489 } |
471 } | 490 } |
472 | 491 |
473 // Helper for binops of the R x L -> O variety. | 492 // Helper for binops of the R x L -> O variety. |
474 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, | 493 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, |
475 MachineTypeUnion output) { | 494 MachineType output) { |
476 DCHECK_EQ(2, node->op()->ValueInputCount()); | 495 DCHECK_EQ(2, node->op()->ValueInputCount()); |
477 ProcessInput(node, 0, left_use); | 496 ProcessInput(node, 0, left_use); |
478 ProcessInput(node, 1, right_use); | 497 ProcessInput(node, 1, right_use); |
479 for (int i = 2; i < node->InputCount(); i++) { | 498 for (int i = 2; i < node->InputCount(); i++) { |
480 EnqueueInput(node, i); | 499 EnqueueInput(node, i); |
481 } | 500 } |
482 SetOutput(node, output); | 501 SetOutput(node, output); |
483 } | 502 } |
484 | 503 |
485 // Helper for binops of the I x I -> O variety. | 504 // Helper for binops of the I x I -> O variety. |
486 void VisitBinop(Node* node, UseInfo input_use, MachineTypeUnion output) { | 505 void VisitBinop(Node* node, UseInfo input_use, MachineType output) { |
487 VisitBinop(node, input_use, input_use, output); | 506 VisitBinop(node, input_use, input_use, output); |
488 } | 507 } |
489 | 508 |
490 // Helper for unops of the I -> O variety. | 509 // Helper for unops of the I -> O variety. |
491 void VisitUnop(Node* node, UseInfo input_use, MachineTypeUnion output) { | 510 void VisitUnop(Node* node, UseInfo input_use, MachineType output) { |
492 DCHECK_EQ(1, node->InputCount()); | 511 DCHECK_EQ(1, node->InputCount()); |
493 ProcessInput(node, 0, input_use); | 512 ProcessInput(node, 0, input_use); |
494 SetOutput(node, output); | 513 SetOutput(node, output); |
495 } | 514 } |
496 | 515 |
497 // Helper for leaf nodes. | 516 // Helper for leaf nodes. |
498 void VisitLeaf(Node* node, MachineTypeUnion output) { | 517 void VisitLeaf(Node* node, MachineType output) { |
499 DCHECK_EQ(0, node->InputCount()); | 518 DCHECK_EQ(0, node->InputCount()); |
500 SetOutput(node, output); | 519 SetOutput(node, output); |
501 } | 520 } |
502 | 521 |
503 // Helpers for specific types of binops. | 522 // Helpers for specific types of binops. |
504 void VisitFloat64Binop(Node* node) { | 523 void VisitFloat64Binop(Node* node) { |
505 VisitBinop(node, UseInfo::Float64(), kMachFloat64); | 524 VisitBinop(node, UseInfo::Float64(), MachineType::Float64()); |
506 } | 525 } |
507 void VisitInt32Binop(Node* node) { | 526 void VisitInt32Binop(Node* node) { |
508 VisitBinop(node, UseInfo::TruncatingWord32(), kMachInt32); | 527 VisitBinop(node, UseInfo::TruncatingWord32(), MachineType::Int32()); |
509 } | 528 } |
510 void VisitUint32Binop(Node* node) { | 529 void VisitUint32Binop(Node* node) { |
511 VisitBinop(node, UseInfo::TruncatingWord32(), kMachUint32); | 530 VisitBinop(node, UseInfo::TruncatingWord32(), MachineType::Uint32()); |
512 } | 531 } |
513 void VisitInt64Binop(Node* node) { | 532 void VisitInt64Binop(Node* node) { |
514 VisitBinop(node, UseInfo::TruncatingWord64(), kMachInt64); | 533 VisitBinop(node, UseInfo::TruncatingWord64(), MachineType::Int64()); |
515 } | 534 } |
516 void VisitUint64Binop(Node* node) { | 535 void VisitUint64Binop(Node* node) { |
517 VisitBinop(node, UseInfo::TruncatingWord64(), kMachUint64); | 536 VisitBinop(node, UseInfo::TruncatingWord64(), MachineType::Uint64()); |
518 } | 537 } |
519 void VisitFloat64Cmp(Node* node) { | 538 void VisitFloat64Cmp(Node* node) { |
520 VisitBinop(node, UseInfo::Float64(), kMachBool); | 539 VisitBinop(node, UseInfo::Float64(), MachineType::Bool()); |
521 } | 540 } |
522 void VisitInt32Cmp(Node* node) { | 541 void VisitInt32Cmp(Node* node) { |
523 VisitBinop(node, UseInfo::TruncatingWord32(), kMachBool); | 542 VisitBinop(node, UseInfo::TruncatingWord32(), MachineType::Bool()); |
524 } | 543 } |
525 void VisitUint32Cmp(Node* node) { | 544 void VisitUint32Cmp(Node* node) { |
526 VisitBinop(node, UseInfo::TruncatingWord32(), kMachBool); | 545 VisitBinop(node, UseInfo::TruncatingWord32(), MachineType::Bool()); |
527 } | 546 } |
528 void VisitInt64Cmp(Node* node) { | 547 void VisitInt64Cmp(Node* node) { |
529 VisitBinop(node, UseInfo::TruncatingWord64(), kMachBool); | 548 VisitBinop(node, UseInfo::TruncatingWord64(), MachineType::Bool()); |
530 } | 549 } |
531 void VisitUint64Cmp(Node* node) { | 550 void VisitUint64Cmp(Node* node) { |
532 VisitBinop(node, UseInfo::TruncatingWord64(), kMachBool); | 551 VisitBinop(node, UseInfo::TruncatingWord64(), MachineType::Bool()); |
533 } | 552 } |
534 | 553 |
535 // Infer representation for phi-like nodes. | 554 // Infer representation for phi-like nodes. |
536 static MachineType GetRepresentationForPhi(Node* node, Truncation use) { | 555 static MachineRepresentation GetRepresentationForPhi(Node* node, |
| 556 Truncation use) { |
537 // Phis adapt to the output representation their uses demand. | 557 // Phis adapt to the output representation their uses demand. |
538 Type* upper = NodeProperties::GetType(node); | 558 Type* upper = NodeProperties::GetType(node); |
539 if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) { | 559 if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) { |
540 // We are within 32 bits range => pick kRepWord32. | 560 // We are within 32 bits range => pick kRepWord32. |
541 return kRepWord32; | 561 return MachineRepresentation::kWord32; |
542 } else if (use.TruncatesToWord32()) { | 562 } else if (use.TruncatesToWord32()) { |
543 // We only use 32 bits. | 563 // We only use 32 bits. |
544 return kRepWord32; | 564 return MachineRepresentation::kWord32; |
545 } else if (upper->Is(Type::Boolean())) { | 565 } else if (upper->Is(Type::Boolean())) { |
546 // multiple uses => pick kRepBit. | 566 // multiple uses => pick kRepBit. |
547 return kRepBit; | 567 return MachineRepresentation::kBit; |
548 } else if (upper->Is(Type::Number())) { | 568 } else if (upper->Is(Type::Number())) { |
549 // multiple uses => pick kRepFloat64. | 569 // multiple uses => pick kRepFloat64. |
550 return kRepFloat64; | 570 return MachineRepresentation::kFloat64; |
551 } else if (upper->Is(Type::Internal())) { | 571 } else if (upper->Is(Type::Internal())) { |
552 return kMachPtr; | 572 return MachineType::PointerRepresentation(); |
553 } | 573 } |
554 return kRepTagged; | 574 return MachineRepresentation::kTagged; |
555 } | 575 } |
556 | 576 |
557 // Helper for handling selects. | 577 // Helper for handling selects. |
558 void VisitSelect(Node* node, Truncation truncation, | 578 void VisitSelect(Node* node, Truncation truncation, |
559 SimplifiedLowering* lowering) { | 579 SimplifiedLowering* lowering) { |
560 ProcessInput(node, 0, UseInfo::Bool()); | 580 ProcessInput(node, 0, UseInfo::Bool()); |
561 MachineType output = GetRepresentationForPhi(node, truncation); | 581 MachineRepresentation output = GetRepresentationForPhi(node, truncation); |
562 | 582 |
563 Type* upper = NodeProperties::GetType(node); | 583 Type* upper = NodeProperties::GetType(node); |
564 MachineType output_type = | 584 MachineType output_type = |
565 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); | 585 MachineType(output, changer_->TypeFromUpperBound(upper)); |
566 SetOutput(node, output_type); | 586 SetOutput(node, output_type); |
567 | 587 |
568 if (lower()) { | 588 if (lower()) { |
569 // Update the select operator. | 589 // Update the select operator. |
570 SelectParameters p = SelectParametersOf(node->op()); | 590 SelectParameters p = SelectParametersOf(node->op()); |
571 MachineType type = static_cast<MachineType>(output_type); | 591 if (output != p.representation()) { |
572 if (type != p.type()) { | |
573 NodeProperties::ChangeOp(node, | 592 NodeProperties::ChangeOp(node, |
574 lowering->common()->Select(type, p.hint())); | 593 lowering->common()->Select(output, p.hint())); |
575 } | 594 } |
576 } | 595 } |
577 // Convert inputs to the output representation of this phi, pass the | 596 // Convert inputs to the output representation of this phi, pass the |
578 // truncation truncation along. | 597 // truncation truncation along. |
579 UseInfo input_use(output, truncation); | 598 UseInfo input_use(output, truncation); |
580 ProcessInput(node, 1, input_use); | 599 ProcessInput(node, 1, input_use); |
581 ProcessInput(node, 2, input_use); | 600 ProcessInput(node, 2, input_use); |
582 } | 601 } |
583 | 602 |
584 // Helper for handling phis. | 603 // Helper for handling phis. |
585 void VisitPhi(Node* node, Truncation truncation, | 604 void VisitPhi(Node* node, Truncation truncation, |
586 SimplifiedLowering* lowering) { | 605 SimplifiedLowering* lowering) { |
587 MachineType output = GetRepresentationForPhi(node, truncation); | 606 MachineRepresentation output = GetRepresentationForPhi(node, truncation); |
588 | 607 |
589 Type* upper = NodeProperties::GetType(node); | 608 Type* upper = NodeProperties::GetType(node); |
590 MachineType output_type = | 609 MachineType output_type = |
591 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); | 610 MachineType(output, changer_->TypeFromUpperBound(upper)); |
592 SetOutput(node, output_type); | 611 SetOutput(node, output_type); |
593 | 612 |
594 int values = node->op()->ValueInputCount(); | 613 int values = node->op()->ValueInputCount(); |
595 | 614 |
596 if (lower()) { | 615 if (lower()) { |
597 // Update the phi operator. | 616 // Update the phi operator. |
598 MachineType type = static_cast<MachineType>(output_type); | 617 if (output != PhiRepresentationOf(node->op())) { |
599 if (type != OpParameter<MachineType>(node)) { | 618 NodeProperties::ChangeOp(node, lowering->common()->Phi(output, values)); |
600 NodeProperties::ChangeOp(node, lowering->common()->Phi(type, values)); | |
601 } | 619 } |
602 } | 620 } |
603 | 621 |
604 // Convert inputs to the output representation of this phi, pass the | 622 // Convert inputs to the output representation of this phi, pass the |
605 // truncation truncation along. | 623 // truncation truncation along. |
606 UseInfo input_use(output, truncation); | 624 UseInfo input_use(output, truncation); |
607 for (int i = 0; i < node->InputCount(); i++) { | 625 for (int i = 0; i < node->InputCount(); i++) { |
608 ProcessInput(node, i, i < values ? input_use : UseInfo::None()); | 626 ProcessInput(node, i, i < values ? input_use : UseInfo::None()); |
609 } | 627 } |
610 } | 628 } |
611 | 629 |
612 void VisitCall(Node* node, SimplifiedLowering* lowering) { | 630 void VisitCall(Node* node, SimplifiedLowering* lowering) { |
613 const CallDescriptor* desc = OpParameter<const CallDescriptor*>(node->op()); | 631 const CallDescriptor* desc = OpParameter<const CallDescriptor*>(node->op()); |
614 const MachineSignature* sig = desc->GetMachineSignature(); | 632 const MachineSignature* sig = desc->GetMachineSignature(); |
615 int params = static_cast<int>(sig->parameter_count()); | 633 int params = static_cast<int>(sig->parameter_count()); |
616 // Propagate representation information from call descriptor. | 634 // Propagate representation information from call descriptor. |
617 for (int i = 0; i < node->InputCount(); i++) { | 635 for (int i = 0; i < node->InputCount(); i++) { |
618 if (i == 0) { | 636 if (i == 0) { |
619 // The target of the call. | 637 // The target of the call. |
620 ProcessInput(node, i, UseInfo::None()); | 638 ProcessInput(node, i, UseInfo::None()); |
621 } else if ((i - 1) < params) { | 639 } else if ((i - 1) < params) { |
622 ProcessInput(node, i, UseInfoFromMachineType(sig->GetParam(i - 1))); | 640 ProcessInput(node, i, TruncatingUseInfoFromRepresentation( |
| 641 sig->GetParam(i - 1).representation())); |
623 } else { | 642 } else { |
624 ProcessInput(node, i, UseInfo::None()); | 643 ProcessInput(node, i, UseInfo::None()); |
625 } | 644 } |
626 } | 645 } |
627 | 646 |
628 if (sig->return_count() > 0) { | 647 if (sig->return_count() > 0) { |
629 SetOutput(node, desc->GetMachineSignature()->GetReturn()); | 648 SetOutput(node, desc->GetMachineSignature()->GetReturn()); |
630 } else { | 649 } else { |
631 SetOutput(node, kMachAnyTagged); | 650 SetOutput(node, MachineType::AnyTagged()); |
632 } | 651 } |
633 } | 652 } |
634 | 653 |
635 void VisitStateValues(Node* node) { | 654 void VisitStateValues(Node* node) { |
636 if (phase_ == PROPAGATE) { | 655 if (phase_ == PROPAGATE) { |
637 for (int i = 0; i < node->InputCount(); i++) { | 656 for (int i = 0; i < node->InputCount(); i++) { |
638 EnqueueInput(node, i, UseInfo::Any()); | 657 EnqueueInput(node, i, UseInfo::Any()); |
639 } | 658 } |
640 } else { | 659 } else { |
641 Zone* zone = jsgraph_->zone(); | 660 Zone* zone = jsgraph_->zone(); |
642 ZoneVector<MachineType>* types = | 661 ZoneVector<MachineType>* types = |
643 new (zone->New(sizeof(ZoneVector<MachineType>))) | 662 new (zone->New(sizeof(ZoneVector<MachineType>))) |
644 ZoneVector<MachineType>(node->InputCount(), zone); | 663 ZoneVector<MachineType>(node->InputCount(), zone); |
645 for (int i = 0; i < node->InputCount(); i++) { | 664 for (int i = 0; i < node->InputCount(); i++) { |
646 MachineTypeUnion input_type = GetInfo(node->InputAt(i))->output_type(); | 665 MachineType input_type = GetInfo(node->InputAt(i))->output_type(); |
647 (*types)[i] = static_cast<MachineType>(input_type); | 666 (*types)[i] = input_type; |
648 } | 667 } |
649 NodeProperties::ChangeOp(node, | 668 NodeProperties::ChangeOp(node, |
650 jsgraph_->common()->TypedStateValues(types)); | 669 jsgraph_->common()->TypedStateValues(types)); |
651 } | 670 } |
652 SetOutput(node, kMachAnyTagged); | 671 SetOutput(node, MachineType::AnyTagged()); |
653 } | 672 } |
654 | 673 |
655 const Operator* Int32Op(Node* node) { | 674 const Operator* Int32Op(Node* node) { |
656 return changer_->Int32OperatorFor(node->opcode()); | 675 return changer_->Int32OperatorFor(node->opcode()); |
657 } | 676 } |
658 | 677 |
659 const Operator* Uint32Op(Node* node) { | 678 const Operator* Uint32Op(Node* node) { |
660 return changer_->Uint32OperatorFor(node->opcode()); | 679 return changer_->Uint32OperatorFor(node->opcode()); |
661 } | 680 } |
662 | 681 |
(...skipping 30 matching lines...) Expand all Loading... |
693 // Dispatching routine for visiting the node {node} with the usage {use}. | 712 // Dispatching routine for visiting the node {node} with the usage {use}. |
694 // Depending on the operator, propagate new usage info to the inputs. | 713 // Depending on the operator, propagate new usage info to the inputs. |
695 void VisitNode(Node* node, Truncation truncation, | 714 void VisitNode(Node* node, Truncation truncation, |
696 SimplifiedLowering* lowering) { | 715 SimplifiedLowering* lowering) { |
697 switch (node->opcode()) { | 716 switch (node->opcode()) { |
698 //------------------------------------------------------------------ | 717 //------------------------------------------------------------------ |
699 // Common operators. | 718 // Common operators. |
700 //------------------------------------------------------------------ | 719 //------------------------------------------------------------------ |
701 case IrOpcode::kStart: | 720 case IrOpcode::kStart: |
702 case IrOpcode::kDead: | 721 case IrOpcode::kDead: |
703 return VisitLeaf(node, 0); | 722 return VisitLeaf(node, MachineType::None()); |
704 case IrOpcode::kParameter: { | 723 case IrOpcode::kParameter: { |
705 // TODO(titzer): use representation from linkage. | 724 // TODO(titzer): use representation from linkage. |
706 Type* upper = NodeProperties::GetType(node); | 725 Type* upper = NodeProperties::GetType(node); |
707 ProcessInput(node, 0, UseInfo::None()); | 726 ProcessInput(node, 0, UseInfo::None()); |
708 SetOutput(node, kRepTagged | changer_->TypeFromUpperBound(upper)); | 727 SetOutput(node, MachineType(MachineRepresentation::kTagged, |
| 728 changer_->TypeFromUpperBound(upper))); |
709 return; | 729 return; |
710 } | 730 } |
711 case IrOpcode::kInt32Constant: | 731 case IrOpcode::kInt32Constant: |
712 return VisitLeaf(node, kRepWord32); | 732 return VisitLeaf(node, MachineType::RepWord32()); |
713 case IrOpcode::kInt64Constant: | 733 case IrOpcode::kInt64Constant: |
714 return VisitLeaf(node, kRepWord64); | 734 return VisitLeaf(node, MachineType::RepWord64()); |
715 case IrOpcode::kFloat32Constant: | 735 case IrOpcode::kFloat32Constant: |
716 return VisitLeaf(node, kRepFloat32); | 736 return VisitLeaf(node, MachineType::RepFloat32()); |
717 case IrOpcode::kFloat64Constant: | 737 case IrOpcode::kFloat64Constant: |
718 return VisitLeaf(node, kRepFloat64); | 738 return VisitLeaf(node, MachineType::RepFloat64()); |
719 case IrOpcode::kExternalConstant: | 739 case IrOpcode::kExternalConstant: |
720 return VisitLeaf(node, kMachPtr); | 740 return VisitLeaf(node, MachineType::Pointer()); |
721 case IrOpcode::kNumberConstant: | 741 case IrOpcode::kNumberConstant: |
722 return VisitLeaf(node, kRepTagged); | 742 return VisitLeaf(node, MachineType::RepTagged()); |
723 case IrOpcode::kHeapConstant: | 743 case IrOpcode::kHeapConstant: |
724 return VisitLeaf(node, kRepTagged); | 744 return VisitLeaf(node, MachineType::RepTagged()); |
725 | 745 |
726 case IrOpcode::kBranch: | 746 case IrOpcode::kBranch: |
727 ProcessInput(node, 0, UseInfo::Bool()); | 747 ProcessInput(node, 0, UseInfo::Bool()); |
728 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); | 748 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); |
729 break; | 749 break; |
730 case IrOpcode::kSwitch: | 750 case IrOpcode::kSwitch: |
731 ProcessInput(node, 0, UseInfo::TruncatingWord32()); | 751 ProcessInput(node, 0, UseInfo::TruncatingWord32()); |
732 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); | 752 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); |
733 break; | 753 break; |
734 case IrOpcode::kSelect: | 754 case IrOpcode::kSelect: |
735 return VisitSelect(node, truncation, lowering); | 755 return VisitSelect(node, truncation, lowering); |
736 case IrOpcode::kPhi: | 756 case IrOpcode::kPhi: |
737 return VisitPhi(node, truncation, lowering); | 757 return VisitPhi(node, truncation, lowering); |
738 case IrOpcode::kCall: | 758 case IrOpcode::kCall: |
739 return VisitCall(node, lowering); | 759 return VisitCall(node, lowering); |
740 | 760 |
741 //------------------------------------------------------------------ | 761 //------------------------------------------------------------------ |
742 // JavaScript operators. | 762 // JavaScript operators. |
743 //------------------------------------------------------------------ | 763 //------------------------------------------------------------------ |
744 // For now, we assume that all JS operators were too complex to lower | 764 // For now, we assume that all JS operators were too complex to lower |
745 // to Simplified and that they will always require tagged value inputs | 765 // to Simplified and that they will always require tagged value inputs |
746 // and produce tagged value outputs. | 766 // and produce tagged value outputs. |
747 // TODO(turbofan): it might be possible to lower some JSOperators here, | 767 // TODO(turbofan): it might be possible to lower some JSOperators here, |
748 // but that responsibility really lies in the typed lowering phase. | 768 // but that responsibility really lies in the typed lowering phase. |
749 #define DEFINE_JS_CASE(x) case IrOpcode::k##x: | 769 #define DEFINE_JS_CASE(x) case IrOpcode::k##x: |
750 JS_OP_LIST(DEFINE_JS_CASE) | 770 JS_OP_LIST(DEFINE_JS_CASE) |
751 #undef DEFINE_JS_CASE | 771 #undef DEFINE_JS_CASE |
752 VisitInputs(node); | 772 VisitInputs(node); |
753 return SetOutput(node, kRepTagged); | 773 return SetOutput(node, MachineType::RepTagged()); |
754 | 774 |
755 //------------------------------------------------------------------ | 775 //------------------------------------------------------------------ |
756 // Simplified operators. | 776 // Simplified operators. |
757 //------------------------------------------------------------------ | 777 //------------------------------------------------------------------ |
758 case IrOpcode::kBooleanNot: { | 778 case IrOpcode::kBooleanNot: { |
759 if (lower()) { | 779 if (lower()) { |
760 MachineTypeUnion input = GetInfo(node->InputAt(0))->output_type(); | 780 MachineType input = GetInfo(node->InputAt(0))->output_type(); |
761 if (input & kRepBit) { | 781 if (input.representation() == MachineRepresentation::kBit) { |
762 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) | 782 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) |
763 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); | 783 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); |
764 NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal()); | 784 NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal()); |
765 } else { | 785 } else { |
766 // BooleanNot(x: kRepTagged) => WordEqual(x, #false) | 786 // BooleanNot(x: kRepTagged) => WordEqual(x, #false) |
767 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant()); | 787 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant()); |
768 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); | 788 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
769 } | 789 } |
770 } else { | 790 } else { |
771 // No input representation requirement; adapt during lowering. | 791 // No input representation requirement; adapt during lowering. |
772 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); | 792 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); |
773 SetOutput(node, kRepBit); | 793 SetOutput(node, MachineType::RepBit()); |
774 } | 794 } |
775 break; | 795 break; |
776 } | 796 } |
777 case IrOpcode::kBooleanToNumber: { | 797 case IrOpcode::kBooleanToNumber: { |
778 if (lower()) { | 798 if (lower()) { |
779 MachineTypeUnion input = GetInfo(node->InputAt(0))->output_type(); | 799 MachineType input = GetInfo(node->InputAt(0))->output_type(); |
780 if (input & kRepBit) { | 800 if (input.representation() == MachineRepresentation::kBit) { |
781 // BooleanToNumber(x: kRepBit) => x | 801 // BooleanToNumber(x: kRepBit) => x |
782 DeferReplacement(node, node->InputAt(0)); | 802 DeferReplacement(node, node->InputAt(0)); |
783 } else { | 803 } else { |
784 // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true) | 804 // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true) |
785 node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant()); | 805 node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant()); |
786 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); | 806 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
787 } | 807 } |
788 } else { | 808 } else { |
789 // No input representation requirement; adapt during lowering. | 809 // No input representation requirement; adapt during lowering. |
790 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); | 810 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); |
791 SetOutput(node, kMachInt32); | 811 SetOutput(node, MachineType::Int32()); |
792 } | 812 } |
793 break; | 813 break; |
794 } | 814 } |
795 case IrOpcode::kNumberEqual: | 815 case IrOpcode::kNumberEqual: |
796 case IrOpcode::kNumberLessThan: | 816 case IrOpcode::kNumberLessThan: |
797 case IrOpcode::kNumberLessThanOrEqual: { | 817 case IrOpcode::kNumberLessThanOrEqual: { |
798 // Number comparisons reduce to integer comparisons for integer inputs. | 818 // Number comparisons reduce to integer comparisons for integer inputs. |
799 if (BothInputsAre(node, Type::Signed32())) { | 819 if (BothInputsAre(node, Type::Signed32())) { |
800 // => signed Int32Cmp | 820 // => signed Int32Cmp |
801 VisitInt32Cmp(node); | 821 VisitInt32Cmp(node); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
880 } | 900 } |
881 case IrOpcode::kNumberBitwiseOr: | 901 case IrOpcode::kNumberBitwiseOr: |
882 case IrOpcode::kNumberBitwiseXor: | 902 case IrOpcode::kNumberBitwiseXor: |
883 case IrOpcode::kNumberBitwiseAnd: { | 903 case IrOpcode::kNumberBitwiseAnd: { |
884 VisitInt32Binop(node); | 904 VisitInt32Binop(node); |
885 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); | 905 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
886 break; | 906 break; |
887 } | 907 } |
888 case IrOpcode::kNumberShiftLeft: { | 908 case IrOpcode::kNumberShiftLeft: { |
889 VisitBinop(node, UseInfo::TruncatingWord32(), | 909 VisitBinop(node, UseInfo::TruncatingWord32(), |
890 UseInfo::TruncatingWord32(), kMachInt32); | 910 UseInfo::TruncatingWord32(), MachineType::Int32()); |
891 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shl()); | 911 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shl()); |
892 break; | 912 break; |
893 } | 913 } |
894 case IrOpcode::kNumberShiftRight: { | 914 case IrOpcode::kNumberShiftRight: { |
895 VisitBinop(node, UseInfo::TruncatingWord32(), | 915 VisitBinop(node, UseInfo::TruncatingWord32(), |
896 UseInfo::TruncatingWord32(), kMachInt32); | 916 UseInfo::TruncatingWord32(), MachineType::Int32()); |
897 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Sar()); | 917 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Sar()); |
898 break; | 918 break; |
899 } | 919 } |
900 case IrOpcode::kNumberShiftRightLogical: { | 920 case IrOpcode::kNumberShiftRightLogical: { |
901 VisitBinop(node, UseInfo::TruncatingWord32(), | 921 VisitBinop(node, UseInfo::TruncatingWord32(), |
902 UseInfo::TruncatingWord32(), kMachUint32); | 922 UseInfo::TruncatingWord32(), MachineType::Uint32()); |
903 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shr()); | 923 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shr()); |
904 break; | 924 break; |
905 } | 925 } |
906 case IrOpcode::kNumberToInt32: { | 926 case IrOpcode::kNumberToInt32: { |
907 // Just change representation if necessary. | 927 // Just change representation if necessary. |
908 VisitUnop(node, UseInfo::TruncatingWord32(), kMachInt32); | 928 VisitUnop(node, UseInfo::TruncatingWord32(), MachineType::Int32()); |
909 if (lower()) DeferReplacement(node, node->InputAt(0)); | 929 if (lower()) DeferReplacement(node, node->InputAt(0)); |
910 break; | 930 break; |
911 } | 931 } |
912 case IrOpcode::kNumberToUint32: { | 932 case IrOpcode::kNumberToUint32: { |
913 // Just change representation if necessary. | 933 // Just change representation if necessary. |
914 VisitUnop(node, UseInfo::TruncatingWord32(), kMachUint32); | 934 VisitUnop(node, UseInfo::TruncatingWord32(), MachineType::Uint32()); |
915 if (lower()) DeferReplacement(node, node->InputAt(0)); | 935 if (lower()) DeferReplacement(node, node->InputAt(0)); |
916 break; | 936 break; |
917 } | 937 } |
918 case IrOpcode::kNumberIsHoleNaN: { | 938 case IrOpcode::kNumberIsHoleNaN: { |
919 VisitUnop(node, UseInfo::Float64(), kMachBool); | 939 VisitUnop(node, UseInfo::Float64(), MachineType::Bool()); |
920 if (lower()) { | 940 if (lower()) { |
921 // NumberIsHoleNaN(x) => Word32Equal(Float64ExtractLowWord32(x), | 941 // NumberIsHoleNaN(x) => Word32Equal(Float64ExtractLowWord32(x), |
922 // #HoleNaNLower32) | 942 // #HoleNaNLower32) |
923 node->ReplaceInput(0, | 943 node->ReplaceInput(0, |
924 jsgraph_->graph()->NewNode( | 944 jsgraph_->graph()->NewNode( |
925 lowering->machine()->Float64ExtractLowWord32(), | 945 lowering->machine()->Float64ExtractLowWord32(), |
926 node->InputAt(0))); | 946 node->InputAt(0))); |
927 node->AppendInput(jsgraph_->zone(), | 947 node->AppendInput(jsgraph_->zone(), |
928 jsgraph_->Int32Constant(kHoleNanLower32)); | 948 jsgraph_->Int32Constant(kHoleNanLower32)); |
929 NodeProperties::ChangeOp(node, jsgraph_->machine()->Word32Equal()); | 949 NodeProperties::ChangeOp(node, jsgraph_->machine()->Word32Equal()); |
930 } | 950 } |
931 break; | 951 break; |
932 } | 952 } |
933 case IrOpcode::kPlainPrimitiveToNumber: { | 953 case IrOpcode::kPlainPrimitiveToNumber: { |
934 VisitUnop(node, UseInfo::AnyTagged(), kTypeNumber | kRepTagged); | 954 VisitUnop(node, UseInfo::AnyTagged(), |
| 955 MachineType(MachineRepresentation::kTagged, |
| 956 MachineSemantic::kNumber)); |
935 if (lower()) { | 957 if (lower()) { |
936 // PlainPrimitiveToNumber(x) => Call(ToNumberStub, x, no-context) | 958 // PlainPrimitiveToNumber(x) => Call(ToNumberStub, x, no-context) |
937 Operator::Properties properties = node->op()->properties(); | 959 Operator::Properties properties = node->op()->properties(); |
938 Callable callable = CodeFactory::ToNumber(jsgraph_->isolate()); | 960 Callable callable = CodeFactory::ToNumber(jsgraph_->isolate()); |
939 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | 961 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
940 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 962 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
941 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, | 963 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, |
942 flags, properties); | 964 flags, properties); |
943 node->InsertInput(jsgraph_->zone(), 0, | 965 node->InsertInput(jsgraph_->zone(), 0, |
944 jsgraph_->HeapConstant(callable.code())); | 966 jsgraph_->HeapConstant(callable.code())); |
945 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); | 967 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); |
946 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); | 968 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); |
947 } | 969 } |
948 break; | 970 break; |
949 } | 971 } |
950 case IrOpcode::kReferenceEqual: { | 972 case IrOpcode::kReferenceEqual: { |
951 VisitBinop(node, UseInfo::AnyTagged(), kMachBool); | 973 VisitBinop(node, UseInfo::AnyTagged(), MachineType::Bool()); |
952 if (lower()) { | 974 if (lower()) { |
953 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); | 975 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
954 } | 976 } |
955 break; | 977 break; |
956 } | 978 } |
957 case IrOpcode::kStringEqual: { | 979 case IrOpcode::kStringEqual: { |
958 VisitBinop(node, UseInfo::AnyTagged(), kMachBool); | 980 VisitBinop(node, UseInfo::AnyTagged(), MachineType::Bool()); |
959 if (lower()) lowering->DoStringEqual(node); | 981 if (lower()) lowering->DoStringEqual(node); |
960 break; | 982 break; |
961 } | 983 } |
962 case IrOpcode::kStringLessThan: { | 984 case IrOpcode::kStringLessThan: { |
963 VisitBinop(node, UseInfo::AnyTagged(), kMachBool); | 985 VisitBinop(node, UseInfo::AnyTagged(), MachineType::Bool()); |
964 if (lower()) lowering->DoStringLessThan(node); | 986 if (lower()) lowering->DoStringLessThan(node); |
965 break; | 987 break; |
966 } | 988 } |
967 case IrOpcode::kStringLessThanOrEqual: { | 989 case IrOpcode::kStringLessThanOrEqual: { |
968 VisitBinop(node, UseInfo::AnyTagged(), kMachBool); | 990 VisitBinop(node, UseInfo::AnyTagged(), MachineType::Bool()); |
969 if (lower()) lowering->DoStringLessThanOrEqual(node); | 991 if (lower()) lowering->DoStringLessThanOrEqual(node); |
970 break; | 992 break; |
971 } | 993 } |
972 case IrOpcode::kAllocate: { | 994 case IrOpcode::kAllocate: { |
973 ProcessInput(node, 0, UseInfo::AnyTagged()); | 995 ProcessInput(node, 0, UseInfo::AnyTagged()); |
974 ProcessRemainingInputs(node, 1); | 996 ProcessRemainingInputs(node, 1); |
975 SetOutput(node, kMachAnyTagged); | 997 SetOutput(node, MachineType::AnyTagged()); |
976 break; | 998 break; |
977 } | 999 } |
978 case IrOpcode::kLoadField: { | 1000 case IrOpcode::kLoadField: { |
979 FieldAccess access = FieldAccessOf(node->op()); | 1001 FieldAccess access = FieldAccessOf(node->op()); |
980 ProcessInput(node, 0, UseInfoForBasePointer(access)); | 1002 ProcessInput(node, 0, UseInfoForBasePointer(access)); |
981 ProcessRemainingInputs(node, 1); | 1003 ProcessRemainingInputs(node, 1); |
982 SetOutput(node, access.machine_type); | 1004 SetOutput(node, access.machine_type); |
983 break; | 1005 break; |
984 } | 1006 } |
985 case IrOpcode::kStoreField: { | 1007 case IrOpcode::kStoreField: { |
986 FieldAccess access = FieldAccessOf(node->op()); | 1008 FieldAccess access = FieldAccessOf(node->op()); |
987 ProcessInput(node, 0, UseInfoForBasePointer(access)); | 1009 ProcessInput(node, 0, UseInfoForBasePointer(access)); |
988 ProcessInput(node, 1, UseInfoFromMachineType(access.machine_type)); | 1010 ProcessInput(node, 1, TruncatingUseInfoFromRepresentation( |
| 1011 access.machine_type.representation())); |
989 ProcessRemainingInputs(node, 2); | 1012 ProcessRemainingInputs(node, 2); |
990 SetOutput(node, 0); | 1013 SetOutput(node, MachineType::None()); |
991 break; | 1014 break; |
992 } | 1015 } |
993 case IrOpcode::kLoadBuffer: { | 1016 case IrOpcode::kLoadBuffer: { |
994 BufferAccess access = BufferAccessOf(node->op()); | 1017 BufferAccess access = BufferAccessOf(node->op()); |
995 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer | 1018 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer |
996 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset | 1019 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset |
997 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length | 1020 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length |
998 ProcessRemainingInputs(node, 3); | 1021 ProcessRemainingInputs(node, 3); |
999 | 1022 |
1000 MachineType output_type; | 1023 MachineType output_type; |
1001 if (truncation.TruncatesUndefinedToZeroOrNaN()) { | 1024 if (truncation.TruncatesUndefinedToZeroOrNaN()) { |
1002 if (truncation.TruncatesNaNToZero()) { | 1025 if (truncation.TruncatesNaNToZero()) { |
1003 // If undefined is truncated to a non-NaN number, we can use | 1026 // If undefined is truncated to a non-NaN number, we can use |
1004 // the load's representation. | 1027 // the load's representation. |
1005 output_type = access.machine_type(); | 1028 output_type = access.machine_type(); |
1006 } else { | 1029 } else { |
1007 // If undefined is truncated to a number, but the use can | 1030 // If undefined is truncated to a number, but the use can |
1008 // observe NaN, we need to output at least the float32 | 1031 // observe NaN, we need to output at least the float32 |
1009 // representation. | 1032 // representation. |
1010 if (access.machine_type() & kRepFloat32) { | 1033 if (access.machine_type().representation() == |
| 1034 MachineRepresentation::kFloat32) { |
1011 output_type = access.machine_type(); | 1035 output_type = access.machine_type(); |
1012 } else { | 1036 } else { |
1013 output_type = kMachFloat64; | 1037 output_type = MachineType::Float64(); |
1014 } | 1038 } |
1015 } | 1039 } |
1016 } else { | 1040 } else { |
1017 // If undefined is not truncated away, we need to have the tagged | 1041 // If undefined is not truncated away, we need to have the tagged |
1018 // representation. | 1042 // representation. |
1019 output_type = kMachAnyTagged; | 1043 output_type = MachineType::AnyTagged(); |
1020 } | 1044 } |
1021 SetOutput(node, output_type); | 1045 SetOutput(node, output_type); |
1022 if (lower()) lowering->DoLoadBuffer(node, output_type, changer_); | 1046 if (lower()) lowering->DoLoadBuffer(node, output_type, changer_); |
1023 break; | 1047 break; |
1024 } | 1048 } |
1025 case IrOpcode::kStoreBuffer: { | 1049 case IrOpcode::kStoreBuffer: { |
1026 BufferAccess access = BufferAccessOf(node->op()); | 1050 BufferAccess access = BufferAccessOf(node->op()); |
1027 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer | 1051 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer |
1028 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset | 1052 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset |
1029 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length | 1053 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length |
1030 ProcessInput(node, 3, | 1054 ProcessInput(node, 3, |
1031 UseInfoFromMachineType(access.machine_type())); // value | 1055 TruncatingUseInfoFromRepresentation( |
| 1056 access.machine_type().representation())); // value |
1032 ProcessRemainingInputs(node, 4); | 1057 ProcessRemainingInputs(node, 4); |
1033 SetOutput(node, 0); | 1058 SetOutput(node, MachineType::None()); |
1034 if (lower()) lowering->DoStoreBuffer(node); | 1059 if (lower()) lowering->DoStoreBuffer(node); |
1035 break; | 1060 break; |
1036 } | 1061 } |
1037 case IrOpcode::kLoadElement: { | 1062 case IrOpcode::kLoadElement: { |
1038 ElementAccess access = ElementAccessOf(node->op()); | 1063 ElementAccess access = ElementAccessOf(node->op()); |
1039 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base | 1064 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base |
1040 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index | 1065 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index |
1041 ProcessRemainingInputs(node, 2); | 1066 ProcessRemainingInputs(node, 2); |
1042 SetOutput(node, access.machine_type); | 1067 SetOutput(node, access.machine_type); |
1043 break; | 1068 break; |
1044 } | 1069 } |
1045 case IrOpcode::kStoreElement: { | 1070 case IrOpcode::kStoreElement: { |
1046 ElementAccess access = ElementAccessOf(node->op()); | 1071 ElementAccess access = ElementAccessOf(node->op()); |
1047 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base | 1072 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base |
1048 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index | 1073 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index |
1049 ProcessInput(node, 2, | 1074 ProcessInput(node, 2, |
1050 UseInfoFromMachineType(access.machine_type)); // value | 1075 TruncatingUseInfoFromRepresentation( |
| 1076 access.machine_type.representation())); // value |
1051 ProcessRemainingInputs(node, 3); | 1077 ProcessRemainingInputs(node, 3); |
1052 SetOutput(node, 0); | 1078 SetOutput(node, MachineType::None()); |
1053 break; | 1079 break; |
1054 } | 1080 } |
1055 case IrOpcode::kObjectIsNumber: { | 1081 case IrOpcode::kObjectIsNumber: { |
1056 ProcessInput(node, 0, UseInfo::AnyTagged()); | 1082 ProcessInput(node, 0, UseInfo::AnyTagged()); |
1057 SetOutput(node, kMachBool); | 1083 SetOutput(node, MachineType::Bool()); |
1058 if (lower()) lowering->DoObjectIsNumber(node); | 1084 if (lower()) lowering->DoObjectIsNumber(node); |
1059 break; | 1085 break; |
1060 } | 1086 } |
1061 case IrOpcode::kObjectIsSmi: { | 1087 case IrOpcode::kObjectIsSmi: { |
1062 ProcessInput(node, 0, UseInfo::AnyTagged()); | 1088 ProcessInput(node, 0, UseInfo::AnyTagged()); |
1063 SetOutput(node, kMachBool); | 1089 SetOutput(node, MachineType::Bool()); |
1064 if (lower()) lowering->DoObjectIsSmi(node); | 1090 if (lower()) lowering->DoObjectIsSmi(node); |
1065 break; | 1091 break; |
1066 } | 1092 } |
1067 | 1093 |
1068 //------------------------------------------------------------------ | 1094 //------------------------------------------------------------------ |
1069 // Machine-level operators. | 1095 // Machine-level operators. |
1070 //------------------------------------------------------------------ | 1096 //------------------------------------------------------------------ |
1071 case IrOpcode::kLoad: { | 1097 case IrOpcode::kLoad: { |
1072 // TODO(jarin) Eventually, we should get rid of all machine stores | 1098 // TODO(jarin) Eventually, we should get rid of all machine stores |
1073 // from the high-level phases, then this becomes UNREACHABLE. | 1099 // from the high-level phases, then this becomes UNREACHABLE. |
1074 LoadRepresentation rep = OpParameter<LoadRepresentation>(node); | 1100 LoadRepresentation rep = LoadRepresentationOf(node->op()); |
1075 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer | 1101 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer |
1076 ProcessInput(node, 1, UseInfo::PointerInt()); // index | 1102 ProcessInput(node, 1, UseInfo::PointerInt()); // index |
1077 ProcessRemainingInputs(node, 2); | 1103 ProcessRemainingInputs(node, 2); |
1078 SetOutput(node, rep); | 1104 SetOutput(node, rep); |
1079 break; | 1105 break; |
1080 } | 1106 } |
1081 case IrOpcode::kStore: { | 1107 case IrOpcode::kStore: { |
1082 // TODO(jarin) Eventually, we should get rid of all machine stores | 1108 // TODO(jarin) Eventually, we should get rid of all machine stores |
1083 // from the high-level phases, then this becomes UNREACHABLE. | 1109 // from the high-level phases, then this becomes UNREACHABLE. |
1084 StoreRepresentation rep = OpParameter<StoreRepresentation>(node); | 1110 StoreRepresentation rep = StoreRepresentationOf(node->op()); |
1085 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer | 1111 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer |
1086 ProcessInput(node, 1, UseInfo::PointerInt()); // index | 1112 ProcessInput(node, 1, UseInfo::PointerInt()); // index |
1087 ProcessInput(node, 2, UseInfoFromMachineType(rep.machine_type())); | 1113 ProcessInput(node, 2, TruncatingUseInfoFromRepresentation( |
| 1114 rep.machine_type().representation())); |
1088 ProcessRemainingInputs(node, 3); | 1115 ProcessRemainingInputs(node, 3); |
1089 SetOutput(node, 0); | 1116 SetOutput(node, MachineType::None()); |
1090 break; | 1117 break; |
1091 } | 1118 } |
1092 case IrOpcode::kWord32Shr: | 1119 case IrOpcode::kWord32Shr: |
1093 // We output unsigned int32 for shift right because JavaScript. | 1120 // We output unsigned int32 for shift right because JavaScript. |
1094 return VisitBinop(node, UseInfo::TruncatingWord32(), kMachUint32); | 1121 return VisitBinop(node, UseInfo::TruncatingWord32(), |
| 1122 MachineType::Uint32()); |
1095 case IrOpcode::kWord32And: | 1123 case IrOpcode::kWord32And: |
1096 case IrOpcode::kWord32Or: | 1124 case IrOpcode::kWord32Or: |
1097 case IrOpcode::kWord32Xor: | 1125 case IrOpcode::kWord32Xor: |
1098 case IrOpcode::kWord32Shl: | 1126 case IrOpcode::kWord32Shl: |
1099 case IrOpcode::kWord32Sar: | 1127 case IrOpcode::kWord32Sar: |
1100 // We use signed int32 as the output type for these word32 operations, | 1128 // We use signed int32 as the output type for these word32 operations, |
1101 // though the machine bits are the same for either signed or unsigned, | 1129 // though the machine bits are the same for either signed or unsigned, |
1102 // because JavaScript considers the result from these operations signed. | 1130 // because JavaScript considers the result from these operations signed. |
1103 return VisitBinop(node, UseInfo::TruncatingWord32(), | 1131 return VisitBinop(node, UseInfo::TruncatingWord32(), |
1104 kRepWord32 | kTypeInt32); | 1132 MachineType::Int32()); |
1105 case IrOpcode::kWord32Equal: | 1133 case IrOpcode::kWord32Equal: |
1106 return VisitBinop(node, UseInfo::TruncatingWord32(), kMachBool); | 1134 return VisitBinop(node, UseInfo::TruncatingWord32(), |
| 1135 MachineType::Bool()); |
1107 | 1136 |
1108 case IrOpcode::kWord32Clz: | 1137 case IrOpcode::kWord32Clz: |
1109 return VisitUnop(node, UseInfo::TruncatingWord32(), kMachUint32); | 1138 return VisitUnop(node, UseInfo::TruncatingWord32(), |
| 1139 MachineType::Uint32()); |
1110 | 1140 |
1111 case IrOpcode::kInt32Add: | 1141 case IrOpcode::kInt32Add: |
1112 case IrOpcode::kInt32Sub: | 1142 case IrOpcode::kInt32Sub: |
1113 case IrOpcode::kInt32Mul: | 1143 case IrOpcode::kInt32Mul: |
1114 case IrOpcode::kInt32MulHigh: | 1144 case IrOpcode::kInt32MulHigh: |
1115 case IrOpcode::kInt32Div: | 1145 case IrOpcode::kInt32Div: |
1116 case IrOpcode::kInt32Mod: | 1146 case IrOpcode::kInt32Mod: |
1117 return VisitInt32Binop(node); | 1147 return VisitInt32Binop(node); |
1118 case IrOpcode::kUint32Div: | 1148 case IrOpcode::kUint32Div: |
1119 case IrOpcode::kUint32Mod: | 1149 case IrOpcode::kUint32Mod: |
(...skipping 23 matching lines...) Expand all Loading... |
1143 case IrOpcode::kUint64Div: | 1173 case IrOpcode::kUint64Div: |
1144 case IrOpcode::kUint64Mod: | 1174 case IrOpcode::kUint64Mod: |
1145 return VisitUint64Binop(node); | 1175 return VisitUint64Binop(node); |
1146 | 1176 |
1147 case IrOpcode::kWord64And: | 1177 case IrOpcode::kWord64And: |
1148 case IrOpcode::kWord64Or: | 1178 case IrOpcode::kWord64Or: |
1149 case IrOpcode::kWord64Xor: | 1179 case IrOpcode::kWord64Xor: |
1150 case IrOpcode::kWord64Shl: | 1180 case IrOpcode::kWord64Shl: |
1151 case IrOpcode::kWord64Shr: | 1181 case IrOpcode::kWord64Shr: |
1152 case IrOpcode::kWord64Sar: | 1182 case IrOpcode::kWord64Sar: |
1153 return VisitBinop(node, UseInfo::TruncatingWord64(), kRepWord64); | 1183 return VisitBinop(node, UseInfo::TruncatingWord64(), |
| 1184 MachineType(MachineRepresentation::kWord64, |
| 1185 MachineSemantic::kNone)); |
1154 case IrOpcode::kWord64Equal: | 1186 case IrOpcode::kWord64Equal: |
1155 return VisitBinop(node, UseInfo::TruncatingWord64(), kMachBool); | 1187 return VisitBinop(node, UseInfo::TruncatingWord64(), |
| 1188 MachineType::Bool()); |
1156 | 1189 |
1157 case IrOpcode::kChangeInt32ToInt64: | 1190 case IrOpcode::kChangeInt32ToInt64: |
1158 return VisitUnop(node, UseInfo::TruncatingWord32(), | 1191 return VisitUnop(node, UseInfo::TruncatingWord32(), |
1159 kTypeInt32 | kRepWord64); | 1192 MachineType(MachineRepresentation::kWord64, |
| 1193 MachineSemantic::kInt32)); |
1160 case IrOpcode::kChangeUint32ToUint64: | 1194 case IrOpcode::kChangeUint32ToUint64: |
1161 return VisitUnop(node, UseInfo::TruncatingWord32(), | 1195 return VisitUnop(node, UseInfo::TruncatingWord32(), |
1162 kTypeUint32 | kRepWord64); | 1196 MachineType(MachineRepresentation::kWord64, |
| 1197 MachineSemantic::kUint32)); |
1163 case IrOpcode::kTruncateFloat64ToFloat32: | 1198 case IrOpcode::kTruncateFloat64ToFloat32: |
1164 return VisitUnop(node, UseInfo::Float64(), kTypeNumber | kRepFloat32); | 1199 return VisitUnop(node, UseInfo::Float64(), MachineType::Float32()); |
1165 case IrOpcode::kTruncateFloat64ToInt32: | 1200 case IrOpcode::kTruncateFloat64ToInt32: |
1166 return VisitUnop(node, UseInfo::Float64(), kTypeInt32 | kRepWord32); | 1201 return VisitUnop(node, UseInfo::Float64(), MachineType::Int32()); |
1167 case IrOpcode::kTruncateInt64ToInt32: | 1202 case IrOpcode::kTruncateInt64ToInt32: |
1168 // TODO(titzer): Is kTypeInt32 correct here? | 1203 // TODO(titzer): Is kTypeInt32 correct here? |
1169 return VisitUnop(node, UseInfo::Word64TruncatingToWord32(), | 1204 return VisitUnop(node, UseInfo::Word64TruncatingToWord32(), |
1170 kTypeInt32 | kRepWord32); | 1205 MachineType::Int32()); |
1171 | 1206 |
1172 case IrOpcode::kChangeFloat32ToFloat64: | 1207 case IrOpcode::kChangeFloat32ToFloat64: |
1173 return VisitUnop(node, UseInfo::Float32(), kTypeNumber | kRepFloat64); | 1208 return VisitUnop(node, UseInfo::Float32(), MachineType::Float64()); |
1174 case IrOpcode::kChangeInt32ToFloat64: | 1209 case IrOpcode::kChangeInt32ToFloat64: |
1175 return VisitUnop(node, UseInfo::TruncatingWord32(), | 1210 return VisitUnop(node, UseInfo::TruncatingWord32(), |
1176 kTypeInt32 | kRepFloat64); | 1211 MachineType(MachineRepresentation::kFloat64, |
| 1212 MachineSemantic::kInt32)); |
1177 case IrOpcode::kChangeUint32ToFloat64: | 1213 case IrOpcode::kChangeUint32ToFloat64: |
1178 return VisitUnop(node, UseInfo::TruncatingWord32(), | 1214 return VisitUnop(node, UseInfo::TruncatingWord32(), |
1179 kTypeUint32 | kRepFloat64); | 1215 MachineType(MachineRepresentation::kFloat64, |
| 1216 MachineSemantic::kUint32)); |
1180 case IrOpcode::kChangeFloat64ToInt32: | 1217 case IrOpcode::kChangeFloat64ToInt32: |
1181 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(), | 1218 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(), |
1182 kTypeInt32 | kRepWord32); | 1219 MachineType::Int32()); |
1183 case IrOpcode::kChangeFloat64ToUint32: | 1220 case IrOpcode::kChangeFloat64ToUint32: |
1184 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(), | 1221 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(), |
1185 kTypeUint32 | kRepWord32); | 1222 MachineType::Uint32()); |
1186 | 1223 |
1187 case IrOpcode::kFloat64Add: | 1224 case IrOpcode::kFloat64Add: |
1188 case IrOpcode::kFloat64Sub: | 1225 case IrOpcode::kFloat64Sub: |
1189 case IrOpcode::kFloat64Mul: | 1226 case IrOpcode::kFloat64Mul: |
1190 case IrOpcode::kFloat64Div: | 1227 case IrOpcode::kFloat64Div: |
1191 case IrOpcode::kFloat64Mod: | 1228 case IrOpcode::kFloat64Mod: |
1192 case IrOpcode::kFloat64Min: | 1229 case IrOpcode::kFloat64Min: |
1193 return VisitFloat64Binop(node); | 1230 return VisitFloat64Binop(node); |
1194 case IrOpcode::kFloat64Abs: | 1231 case IrOpcode::kFloat64Abs: |
1195 case IrOpcode::kFloat64Sqrt: | 1232 case IrOpcode::kFloat64Sqrt: |
1196 case IrOpcode::kFloat64RoundDown: | 1233 case IrOpcode::kFloat64RoundDown: |
1197 case IrOpcode::kFloat64RoundTruncate: | 1234 case IrOpcode::kFloat64RoundTruncate: |
1198 case IrOpcode::kFloat64RoundTiesAway: | 1235 case IrOpcode::kFloat64RoundTiesAway: |
1199 return VisitUnop(node, UseInfo::Float64(), kMachFloat64); | 1236 return VisitUnop(node, UseInfo::Float64(), MachineType::Float64()); |
1200 case IrOpcode::kFloat64Equal: | 1237 case IrOpcode::kFloat64Equal: |
1201 case IrOpcode::kFloat64LessThan: | 1238 case IrOpcode::kFloat64LessThan: |
1202 case IrOpcode::kFloat64LessThanOrEqual: | 1239 case IrOpcode::kFloat64LessThanOrEqual: |
1203 return VisitFloat64Cmp(node); | 1240 return VisitFloat64Cmp(node); |
1204 case IrOpcode::kFloat64ExtractLowWord32: | 1241 case IrOpcode::kFloat64ExtractLowWord32: |
1205 case IrOpcode::kFloat64ExtractHighWord32: | 1242 case IrOpcode::kFloat64ExtractHighWord32: |
1206 return VisitUnop(node, UseInfo::Float64(), kMachInt32); | 1243 return VisitUnop(node, UseInfo::Float64(), MachineType::Int32()); |
1207 case IrOpcode::kFloat64InsertLowWord32: | 1244 case IrOpcode::kFloat64InsertLowWord32: |
1208 case IrOpcode::kFloat64InsertHighWord32: | 1245 case IrOpcode::kFloat64InsertHighWord32: |
1209 return VisitBinop(node, UseInfo::Float64(), UseInfo::TruncatingWord32(), | 1246 return VisitBinop(node, UseInfo::Float64(), UseInfo::TruncatingWord32(), |
1210 kMachFloat64); | 1247 MachineType::Float64()); |
1211 case IrOpcode::kLoadStackPointer: | 1248 case IrOpcode::kLoadStackPointer: |
1212 case IrOpcode::kLoadFramePointer: | 1249 case IrOpcode::kLoadFramePointer: |
1213 return VisitLeaf(node, kMachPtr); | 1250 return VisitLeaf(node, MachineType::Pointer()); |
1214 case IrOpcode::kStateValues: | 1251 case IrOpcode::kStateValues: |
1215 VisitStateValues(node); | 1252 VisitStateValues(node); |
1216 break; | 1253 break; |
1217 default: | 1254 default: |
1218 VisitInputs(node); | 1255 VisitInputs(node); |
1219 // Assume the output is tagged. | 1256 // Assume the output is tagged. |
1220 SetOutput(node, kMachAnyTagged); | 1257 SetOutput(node, MachineType::AnyTagged()); |
1221 break; | 1258 break; |
1222 } | 1259 } |
1223 } | 1260 } |
1224 | 1261 |
1225 void DeferReplacement(Node* node, Node* replacement) { | 1262 void DeferReplacement(Node* node, Node* replacement) { |
1226 TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(), | 1263 TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(), |
1227 node->op()->mnemonic(), replacement->id(), | 1264 node->op()->mnemonic(), replacement->id(), |
1228 replacement->op()->mnemonic()); | 1265 replacement->op()->mnemonic()); |
1229 | 1266 |
1230 if (replacement->id() < count_ && | 1267 if (replacement->id() < count_ && |
1231 GetInfo(replacement)->output_type() == GetInfo(node)->output_type()) { | 1268 GetInfo(replacement)->output_type() == GetInfo(node)->output_type()) { |
1232 // Replace with a previously existing node eagerly only if the type is the | 1269 // Replace with a previously existing node eagerly only if the type is the |
1233 // same. | 1270 // same. |
1234 node->ReplaceUses(replacement); | 1271 node->ReplaceUses(replacement); |
1235 } else { | 1272 } else { |
1236 // Otherwise, we are replacing a node with a representation change. | 1273 // Otherwise, we are replacing a node with a representation change. |
1237 // Such a substitution must be done after all lowering is done, because | 1274 // Such a substitution must be done after all lowering is done, because |
1238 // changing the type could confuse the representation change | 1275 // changing the type could confuse the representation change |
1239 // insertion for uses of the node. | 1276 // insertion for uses of the node. |
1240 replacements_.push_back(node); | 1277 replacements_.push_back(node); |
1241 replacements_.push_back(replacement); | 1278 replacements_.push_back(replacement); |
1242 } | 1279 } |
1243 node->NullAllInputs(); // Node is now dead. | 1280 node->NullAllInputs(); // Node is now dead. |
1244 } | 1281 } |
1245 | 1282 |
1246 void PrintInfo(MachineTypeUnion info) { | 1283 void PrintInfo(MachineType info) { |
1247 if (FLAG_trace_representation) { | 1284 if (FLAG_trace_representation) { |
1248 OFStream os(stdout); | 1285 OFStream os(stdout); |
1249 os << static_cast<MachineType>(info); | 1286 os << info; |
1250 } | 1287 } |
1251 } | 1288 } |
1252 | 1289 |
1253 void PrintTruncation(Truncation truncation) { | 1290 void PrintTruncation(Truncation truncation) { |
1254 if (FLAG_trace_representation) { | 1291 if (FLAG_trace_representation) { |
1255 OFStream os(stdout); | 1292 OFStream os(stdout); |
1256 os << truncation.description(); | 1293 os << truncation.description(); |
1257 } | 1294 } |
1258 } | 1295 } |
1259 | 1296 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1305 RepresentationChanger changer(jsgraph(), jsgraph()->isolate()); | 1342 RepresentationChanger changer(jsgraph(), jsgraph()->isolate()); |
1306 RepresentationSelector selector(jsgraph(), zone_, &changer, | 1343 RepresentationSelector selector(jsgraph(), zone_, &changer, |
1307 source_positions_); | 1344 source_positions_); |
1308 selector.Run(this); | 1345 selector.Run(this); |
1309 } | 1346 } |
1310 | 1347 |
1311 | 1348 |
1312 void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type, | 1349 void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type, |
1313 RepresentationChanger* changer) { | 1350 RepresentationChanger* changer) { |
1314 DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode()); | 1351 DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode()); |
1315 DCHECK_NE(kMachNone, RepresentationOf(output_type)); | 1352 DCHECK_NE(MachineRepresentation::kNone, output_type.representation()); |
1316 MachineType const type = BufferAccessOf(node->op()).machine_type(); | 1353 MachineType const type = BufferAccessOf(node->op()).machine_type(); |
1317 if (output_type != type) { | 1354 if (output_type != type) { |
1318 Node* const buffer = node->InputAt(0); | 1355 Node* const buffer = node->InputAt(0); |
1319 Node* const offset = node->InputAt(1); | 1356 Node* const offset = node->InputAt(1); |
1320 Node* const length = node->InputAt(2); | 1357 Node* const length = node->InputAt(2); |
1321 Node* const effect = node->InputAt(3); | 1358 Node* const effect = node->InputAt(3); |
1322 Node* const control = node->InputAt(4); | 1359 Node* const control = node->InputAt(4); |
1323 Node* const index = | 1360 Node* const index = |
1324 machine()->Is64() | 1361 machine()->Is64() |
1325 ? graph()->NewNode(machine()->ChangeUint32ToUint64(), offset) | 1362 ? graph()->NewNode(machine()->ChangeUint32ToUint64(), offset) |
1326 : offset; | 1363 : offset; |
1327 | 1364 |
1328 Node* check = graph()->NewNode(machine()->Uint32LessThan(), offset, length); | 1365 Node* check = graph()->NewNode(machine()->Uint32LessThan(), offset, length); |
1329 Node* branch = | 1366 Node* branch = |
1330 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | 1367 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
1331 | 1368 |
1332 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 1369 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
1333 Node* etrue = | 1370 Node* etrue = |
1334 graph()->NewNode(machine()->Load(type), buffer, index, effect, if_true); | 1371 graph()->NewNode(machine()->Load(type), buffer, index, effect, if_true); |
1335 Node* vtrue = changer->GetRepresentationFor( | 1372 Node* vtrue = changer->GetRepresentationFor( |
1336 etrue, type, RepresentationOf(output_type), Truncation::None()); | 1373 etrue, type, output_type.representation(), Truncation::None()); |
1337 | 1374 |
1338 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | 1375 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
1339 Node* efalse = effect; | 1376 Node* efalse = effect; |
1340 Node* vfalse; | 1377 Node* vfalse; |
1341 if (output_type & kRepTagged) { | 1378 if (output_type.representation() == MachineRepresentation::kTagged) { |
1342 vfalse = jsgraph()->UndefinedConstant(); | 1379 vfalse = jsgraph()->UndefinedConstant(); |
1343 } else if (output_type & kRepFloat64) { | 1380 } else if (output_type.representation() == |
| 1381 MachineRepresentation::kFloat64) { |
1344 vfalse = | 1382 vfalse = |
1345 jsgraph()->Float64Constant(std::numeric_limits<double>::quiet_NaN()); | 1383 jsgraph()->Float64Constant(std::numeric_limits<double>::quiet_NaN()); |
1346 } else if (output_type & kRepFloat32) { | 1384 } else if (output_type.representation() == |
| 1385 MachineRepresentation::kFloat32) { |
1347 vfalse = | 1386 vfalse = |
1348 jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN()); | 1387 jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN()); |
1349 } else { | 1388 } else { |
1350 vfalse = jsgraph()->Int32Constant(0); | 1389 vfalse = jsgraph()->Int32Constant(0); |
1351 } | 1390 } |
1352 | 1391 |
1353 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); | 1392 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); |
1354 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge); | 1393 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge); |
1355 | 1394 |
1356 // Replace effect uses of {node} with the {ephi}. | 1395 // Replace effect uses of {node} with the {ephi}. |
1357 NodeProperties::ReplaceUses(node, node, ephi); | 1396 NodeProperties::ReplaceUses(node, node, ephi); |
1358 | 1397 |
1359 // Turn the {node} into a Phi. | 1398 // Turn the {node} into a Phi. |
1360 node->ReplaceInput(0, vtrue); | 1399 node->ReplaceInput(0, vtrue); |
1361 node->ReplaceInput(1, vfalse); | 1400 node->ReplaceInput(1, vfalse); |
1362 node->ReplaceInput(2, merge); | 1401 node->ReplaceInput(2, merge); |
1363 node->TrimInputCount(3); | 1402 node->TrimInputCount(3); |
1364 NodeProperties::ChangeOp(node, common()->Phi(output_type, 2)); | 1403 NodeProperties::ChangeOp(node, |
| 1404 common()->Phi(output_type.representation(), 2)); |
1365 } else { | 1405 } else { |
1366 NodeProperties::ChangeOp(node, machine()->CheckedLoad(type)); | 1406 NodeProperties::ChangeOp(node, machine()->CheckedLoad(type)); |
1367 } | 1407 } |
1368 } | 1408 } |
1369 | 1409 |
1370 | 1410 |
1371 void SimplifiedLowering::DoStoreBuffer(Node* node) { | 1411 void SimplifiedLowering::DoStoreBuffer(Node* node) { |
1372 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode()); | 1412 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode()); |
1373 MachineType const type = BufferAccessOf(node->op()).machine_type(); | 1413 MachineType const type = BufferAccessOf(node->op()).machine_type(); |
1374 NodeProperties::ChangeOp(node, machine()->CheckedStore(type)); | 1414 NodeProperties::ChangeOp(node, machine()->CheckedStore(type)); |
1375 } | 1415 } |
1376 | 1416 |
1377 | 1417 |
1378 void SimplifiedLowering::DoObjectIsNumber(Node* node) { | 1418 void SimplifiedLowering::DoObjectIsNumber(Node* node) { |
1379 Node* input = NodeProperties::GetValueInput(node, 0); | 1419 Node* input = NodeProperties::GetValueInput(node, 0); |
1380 // TODO(bmeurer): Optimize somewhat based on input type. | 1420 // TODO(bmeurer): Optimize somewhat based on input type. |
1381 Node* check = | 1421 Node* check = |
1382 graph()->NewNode(machine()->WordEqual(), | 1422 graph()->NewNode(machine()->WordEqual(), |
1383 graph()->NewNode(machine()->WordAnd(), input, | 1423 graph()->NewNode(machine()->WordAnd(), input, |
1384 jsgraph()->IntPtrConstant(kSmiTagMask)), | 1424 jsgraph()->IntPtrConstant(kSmiTagMask)), |
1385 jsgraph()->IntPtrConstant(kSmiTag)); | 1425 jsgraph()->IntPtrConstant(kSmiTag)); |
1386 Node* branch = graph()->NewNode(common()->Branch(), check, graph()->start()); | 1426 Node* branch = graph()->NewNode(common()->Branch(), check, graph()->start()); |
1387 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 1427 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
1388 Node* vtrue = jsgraph()->Int32Constant(1); | 1428 Node* vtrue = jsgraph()->Int32Constant(1); |
1389 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | 1429 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
1390 Node* vfalse = graph()->NewNode( | 1430 Node* vfalse = graph()->NewNode( |
1391 machine()->WordEqual(), | 1431 machine()->WordEqual(), |
1392 graph()->NewNode( | 1432 graph()->NewNode( |
1393 machine()->Load(kMachAnyTagged), input, | 1433 machine()->Load(MachineType::AnyTagged()), input, |
1394 jsgraph()->IntPtrConstant(HeapObject::kMapOffset - kHeapObjectTag), | 1434 jsgraph()->IntPtrConstant(HeapObject::kMapOffset - kHeapObjectTag), |
1395 graph()->start(), if_false), | 1435 graph()->start(), if_false), |
1396 jsgraph()->HeapConstant(isolate()->factory()->heap_number_map())); | 1436 jsgraph()->HeapConstant(isolate()->factory()->heap_number_map())); |
1397 Node* control = graph()->NewNode(common()->Merge(2), if_true, if_false); | 1437 Node* control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
1398 node->ReplaceInput(0, vtrue); | 1438 node->ReplaceInput(0, vtrue); |
1399 node->AppendInput(graph()->zone(), vfalse); | 1439 node->AppendInput(graph()->zone(), vfalse); |
1400 node->AppendInput(graph()->zone(), control); | 1440 node->AppendInput(graph()->zone(), control); |
1401 NodeProperties::ChangeOp(node, common()->Phi(kMachBool, 2)); | 1441 NodeProperties::ChangeOp(node, common()->Phi(MachineRepresentation::kBit, 2)); |
1402 } | 1442 } |
1403 | 1443 |
1404 | 1444 |
1405 void SimplifiedLowering::DoObjectIsSmi(Node* node) { | 1445 void SimplifiedLowering::DoObjectIsSmi(Node* node) { |
1406 node->ReplaceInput(0, | 1446 node->ReplaceInput(0, |
1407 graph()->NewNode(machine()->WordAnd(), node->InputAt(0), | 1447 graph()->NewNode(machine()->WordAnd(), node->InputAt(0), |
1408 jsgraph()->IntPtrConstant(kSmiTagMask))); | 1448 jsgraph()->IntPtrConstant(kSmiTagMask))); |
1409 node->AppendInput(graph()->zone(), jsgraph()->IntPtrConstant(kSmiTag)); | 1449 node->AppendInput(graph()->zone(), jsgraph()->IntPtrConstant(kSmiTag)); |
1410 NodeProperties::ChangeOp(node, machine()->WordEqual()); | 1450 NodeProperties::ChangeOp(node, machine()->WordEqual()); |
1411 } | 1451 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1449 // if rhs < -1 then | 1489 // if rhs < -1 then |
1450 // lhs / rhs | 1490 // lhs / rhs |
1451 // else if rhs == 0 then | 1491 // else if rhs == 0 then |
1452 // 0 | 1492 // 0 |
1453 // else | 1493 // else |
1454 // 0 - lhs | 1494 // 0 - lhs |
1455 // | 1495 // |
1456 // Note: We do not use the Diamond helper class here, because it really hurts | 1496 // Note: We do not use the Diamond helper class here, because it really hurts |
1457 // readability with nested diamonds. | 1497 // readability with nested diamonds. |
1458 const Operator* const merge_op = common()->Merge(2); | 1498 const Operator* const merge_op = common()->Merge(2); |
1459 const Operator* const phi_op = common()->Phi(kMachInt32, 2); | 1499 const Operator* const phi_op = |
| 1500 common()->Phi(MachineRepresentation::kWord32, 2); |
1460 | 1501 |
1461 Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs); | 1502 Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs); |
1462 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, | 1503 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, |
1463 graph()->start()); | 1504 graph()->start()); |
1464 | 1505 |
1465 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); | 1506 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
1466 Node* true0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true0); | 1507 Node* true0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true0); |
1467 | 1508 |
1468 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); | 1509 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
1469 Node* false0; | 1510 Node* false0; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1526 // lhs & msk | 1567 // lhs & msk |
1527 // else | 1568 // else |
1528 // if rhs < -1 then | 1569 // if rhs < -1 then |
1529 // lhs % rhs | 1570 // lhs % rhs |
1530 // else | 1571 // else |
1531 // zero | 1572 // zero |
1532 // | 1573 // |
1533 // Note: We do not use the Diamond helper class here, because it really hurts | 1574 // Note: We do not use the Diamond helper class here, because it really hurts |
1534 // readability with nested diamonds. | 1575 // readability with nested diamonds. |
1535 const Operator* const merge_op = common()->Merge(2); | 1576 const Operator* const merge_op = common()->Merge(2); |
1536 const Operator* const phi_op = common()->Phi(kMachInt32, 2); | 1577 const Operator* const phi_op = |
| 1578 common()->Phi(MachineRepresentation::kWord32, 2); |
1537 | 1579 |
1538 Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs); | 1580 Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs); |
1539 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, | 1581 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, |
1540 graph()->start()); | 1582 graph()->start()); |
1541 | 1583 |
1542 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); | 1584 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
1543 Node* true0; | 1585 Node* true0; |
1544 { | 1586 { |
1545 Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one); | 1587 Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one); |
1546 | 1588 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1605 | 1647 |
1606 if (m.right().Is(0)) { | 1648 if (m.right().Is(0)) { |
1607 return zero; | 1649 return zero; |
1608 } else if (machine()->Uint32DivIsSafe() || m.right().HasValue()) { | 1650 } else if (machine()->Uint32DivIsSafe() || m.right().HasValue()) { |
1609 return graph()->NewNode(machine()->Uint32Div(), lhs, rhs, graph()->start()); | 1651 return graph()->NewNode(machine()->Uint32Div(), lhs, rhs, graph()->start()); |
1610 } | 1652 } |
1611 | 1653 |
1612 Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); | 1654 Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); |
1613 Diamond d(graph(), common(), check, BranchHint::kFalse); | 1655 Diamond d(graph(), common(), check, BranchHint::kFalse); |
1614 Node* div = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, d.if_false); | 1656 Node* div = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, d.if_false); |
1615 return d.Phi(kMachUint32, zero, div); | 1657 return d.Phi(MachineRepresentation::kWord32, zero, div); |
1616 } | 1658 } |
1617 | 1659 |
1618 | 1660 |
1619 Node* SimplifiedLowering::Uint32Mod(Node* const node) { | 1661 Node* SimplifiedLowering::Uint32Mod(Node* const node) { |
1620 Uint32BinopMatcher m(node); | 1662 Uint32BinopMatcher m(node); |
1621 Node* const minus_one = jsgraph()->Int32Constant(-1); | 1663 Node* const minus_one = jsgraph()->Int32Constant(-1); |
1622 Node* const zero = jsgraph()->Uint32Constant(0); | 1664 Node* const zero = jsgraph()->Uint32Constant(0); |
1623 Node* const lhs = m.left().node(); | 1665 Node* const lhs = m.left().node(); |
1624 Node* const rhs = m.right().node(); | 1666 Node* const rhs = m.right().node(); |
1625 | 1667 |
(...skipping 11 matching lines...) Expand all Loading... |
1637 // if rhs & msk != 0 then | 1679 // if rhs & msk != 0 then |
1638 // lhs % rhs | 1680 // lhs % rhs |
1639 // else | 1681 // else |
1640 // lhs & msk | 1682 // lhs & msk |
1641 // else | 1683 // else |
1642 // zero | 1684 // zero |
1643 // | 1685 // |
1644 // Note: We do not use the Diamond helper class here, because it really hurts | 1686 // Note: We do not use the Diamond helper class here, because it really hurts |
1645 // readability with nested diamonds. | 1687 // readability with nested diamonds. |
1646 const Operator* const merge_op = common()->Merge(2); | 1688 const Operator* const merge_op = common()->Merge(2); |
1647 const Operator* const phi_op = common()->Phi(kMachInt32, 2); | 1689 const Operator* const phi_op = |
| 1690 common()->Phi(MachineRepresentation::kWord32, 2); |
1648 | 1691 |
1649 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), rhs, | 1692 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), rhs, |
1650 graph()->start()); | 1693 graph()->start()); |
1651 | 1694 |
1652 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); | 1695 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
1653 Node* true0; | 1696 Node* true0; |
1654 { | 1697 { |
1655 Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one); | 1698 Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one); |
1656 | 1699 |
1657 Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk); | 1700 Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1728 ReplaceEffectUses(node, comparison); | 1771 ReplaceEffectUses(node, comparison); |
1729 node->ReplaceInput(0, comparison); | 1772 node->ReplaceInput(0, comparison); |
1730 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1773 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
1731 node->TrimInputCount(2); | 1774 node->TrimInputCount(2); |
1732 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); | 1775 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); |
1733 } | 1776 } |
1734 | 1777 |
1735 } // namespace compiler | 1778 } // namespace compiler |
1736 } // namespace internal | 1779 } // namespace internal |
1737 } // namespace v8 | 1780 } // namespace v8 |
OLD | NEW |