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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 } | 155 } |
156 | 156 |
157 | 157 |
158 UseInfo UseInfoForBasePointer(const ElementAccess& access) { | 158 UseInfo UseInfoForBasePointer(const ElementAccess& access) { |
159 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); | 159 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); |
160 } | 160 } |
161 | 161 |
162 | 162 |
163 #ifdef DEBUG | 163 #ifdef DEBUG |
164 // Helpers for monotonicity checking. | 164 // Helpers for monotonicity checking. |
165 | |
166 bool MachineTypeIsSubtype(MachineSemantic t1, MachineSemantic t2) { | |
167 switch (t1) { | |
168 case MachineSemantic::kNone: | |
169 return true; | |
170 case MachineSemantic::kBool: | |
171 return t2 == MachineSemantic::kBool || t2 == MachineSemantic::kNumber || | |
172 t2 == MachineSemantic::kAny; | |
173 case MachineSemantic::kInt32: | |
174 return t2 == MachineSemantic::kInt32 || t2 == MachineSemantic::kNumber || | |
175 t2 == MachineSemantic::kAny; | |
176 case MachineSemantic::kUint32: | |
177 return t2 == MachineSemantic::kUint32 || t2 == MachineSemantic::kNumber || | |
178 t2 == MachineSemantic::kAny; | |
179 case MachineSemantic::kInt64: | |
180 return t2 == MachineSemantic::kInt64; | |
181 case MachineSemantic::kUint64: | |
182 return t2 == MachineSemantic::kUint64; | |
183 case MachineSemantic::kNumber: | |
184 return t2 == MachineSemantic::kNumber || t2 == MachineSemantic::kAny; | |
185 case MachineSemantic::kAny: | |
186 return t2 == MachineSemantic::kAny; | |
187 } | |
188 UNREACHABLE(); | |
189 return false; | |
190 } | |
191 | |
192 | |
193 bool MachineRepresentationIsSubtype(MachineRepresentation r1, | 165 bool MachineRepresentationIsSubtype(MachineRepresentation r1, |
194 MachineRepresentation r2) { | 166 MachineRepresentation r2) { |
195 switch (r1) { | 167 switch (r1) { |
196 case MachineRepresentation::kNone: | 168 case MachineRepresentation::kNone: |
197 return true; | 169 return true; |
198 case MachineRepresentation::kBit: | 170 case MachineRepresentation::kBit: |
199 return r2 == MachineRepresentation::kBit || | 171 return r2 == MachineRepresentation::kBit || |
200 r2 == MachineRepresentation::kTagged; | 172 r2 == MachineRepresentation::kTagged; |
201 case MachineRepresentation::kWord8: | 173 case MachineRepresentation::kWord8: |
202 return r2 == MachineRepresentation::kWord8 || | 174 return r2 == MachineRepresentation::kWord8 || |
(...skipping 25 matching lines...) Expand all Loading... |
228 return r2 == MachineRepresentation::kFloat64 || | 200 return r2 == MachineRepresentation::kFloat64 || |
229 r2 == MachineRepresentation::kTagged; | 201 r2 == MachineRepresentation::kTagged; |
230 case MachineRepresentation::kTagged: | 202 case MachineRepresentation::kTagged: |
231 return r2 == MachineRepresentation::kTagged; | 203 return r2 == MachineRepresentation::kTagged; |
232 } | 204 } |
233 UNREACHABLE(); | 205 UNREACHABLE(); |
234 return false; | 206 return false; |
235 } | 207 } |
236 | 208 |
237 | 209 |
238 bool MachineTypeRepIsSubtype(MachineType m1, MachineType m2) { | |
239 return MachineTypeIsSubtype(m1.semantic(), m2.semantic()) && | |
240 MachineRepresentationIsSubtype(m1.representation(), | |
241 m2.representation()); | |
242 } | |
243 | |
244 | |
245 class InputUseInfos { | 210 class InputUseInfos { |
246 public: | 211 public: |
247 explicit InputUseInfos(Zone* zone) : input_use_infos_(zone) {} | 212 explicit InputUseInfos(Zone* zone) : input_use_infos_(zone) {} |
248 | 213 |
249 void SetAndCheckInput(Node* node, int index, UseInfo use_info) { | 214 void SetAndCheckInput(Node* node, int index, UseInfo use_info) { |
250 if (input_use_infos_.empty()) { | 215 if (input_use_infos_.empty()) { |
251 input_use_infos_.resize(node->InputCount(), UseInfo::None()); | 216 input_use_infos_.resize(node->InputCount(), UseInfo::None()); |
252 } | 217 } |
253 // Check that the new use informatin is a super-type of the old | 218 // Check that the new use informatin is a super-type of the old |
254 // one. | 219 // one. |
(...skipping 11 matching lines...) Expand all Loading... |
266 }; | 231 }; |
267 | 232 |
268 #endif // DEBUG | 233 #endif // DEBUG |
269 | 234 |
270 } // namespace | 235 } // namespace |
271 | 236 |
272 | 237 |
273 class RepresentationSelector { | 238 class RepresentationSelector { |
274 public: | 239 public: |
275 // Information for each node tracked during the fixpoint. | 240 // Information for each node tracked during the fixpoint. |
| 241 class NodeOutputInfo { |
| 242 public: |
| 243 NodeOutputInfo(MachineRepresentation representation, Type* type) |
| 244 : type_(type), representation_(representation) {} |
| 245 NodeOutputInfo() |
| 246 : type_(Type::None()), representation_(MachineRepresentation::kNone) {} |
| 247 |
| 248 MachineRepresentation representation() const { return representation_; } |
| 249 Type* type() const { return type_; } |
| 250 |
| 251 static NodeOutputInfo None() { |
| 252 return NodeOutputInfo(MachineRepresentation::kNone, Type::None()); |
| 253 } |
| 254 |
| 255 static NodeOutputInfo Float32() { |
| 256 return NodeOutputInfo(MachineRepresentation::kFloat32, Type::Number()); |
| 257 } |
| 258 |
| 259 static NodeOutputInfo Float64() { |
| 260 return NodeOutputInfo(MachineRepresentation::kFloat64, Type::Number()); |
| 261 } |
| 262 |
| 263 static NodeOutputInfo NumberTruncatedToWord32() { |
| 264 return NodeOutputInfo(MachineRepresentation::kWord32, Type::Number()); |
| 265 } |
| 266 |
| 267 static NodeOutputInfo Int32() { |
| 268 return NodeOutputInfo(MachineRepresentation::kWord32, Type::Signed32()); |
| 269 } |
| 270 |
| 271 static NodeOutputInfo Uint32() { |
| 272 return NodeOutputInfo(MachineRepresentation::kWord32, Type::Unsigned32()); |
| 273 } |
| 274 |
| 275 static NodeOutputInfo Bool() { |
| 276 return NodeOutputInfo(MachineRepresentation::kBit, Type::Boolean()); |
| 277 } |
| 278 |
| 279 static NodeOutputInfo Int64() { |
| 280 // TODO(jarin) Fix once we have a real int64 type. |
| 281 return NodeOutputInfo(MachineRepresentation::kWord64, Type::Internal()); |
| 282 } |
| 283 |
| 284 static NodeOutputInfo Uint64() { |
| 285 // TODO(jarin) Fix once we have a real uint64 type. |
| 286 return NodeOutputInfo(MachineRepresentation::kWord64, Type::Internal()); |
| 287 } |
| 288 |
| 289 static NodeOutputInfo AnyTagged() { |
| 290 return NodeOutputInfo(MachineRepresentation::kTagged, Type::Any()); |
| 291 } |
| 292 |
| 293 static NodeOutputInfo NumberTagged() { |
| 294 return NodeOutputInfo(MachineRepresentation::kTagged, Type::Number()); |
| 295 } |
| 296 |
| 297 static NodeOutputInfo Pointer() { |
| 298 return NodeOutputInfo(MachineType::PointerRepresentation(), Type::Any()); |
| 299 } |
| 300 |
| 301 private: |
| 302 Type* type_; |
| 303 MachineRepresentation representation_; |
| 304 }; |
| 305 |
276 class NodeInfo { | 306 class NodeInfo { |
277 public: | 307 public: |
278 // Adds new use to the node. Returns true if something has changed | 308 // Adds new use to the node. Returns true if something has changed |
279 // and the node has to be requeued. | 309 // and the node has to be requeued. |
280 bool AddUse(UseInfo info) { | 310 bool AddUse(UseInfo info) { |
281 Truncation old_truncation = truncation_; | 311 Truncation old_truncation = truncation_; |
282 truncation_ = Truncation::Generalize(truncation_, info.truncation()); | 312 truncation_ = Truncation::Generalize(truncation_, info.truncation()); |
283 return truncation_ != old_truncation; | 313 return truncation_ != old_truncation; |
284 } | 314 } |
285 | 315 |
286 void set_queued(bool value) { queued_ = value; } | 316 void set_queued(bool value) { queued_ = value; } |
287 bool queued() const { return queued_; } | 317 bool queued() const { return queued_; } |
288 void set_visited() { visited_ = true; } | 318 void set_visited() { visited_ = true; } |
289 bool visited() const { return visited_; } | 319 bool visited() const { return visited_; } |
290 Truncation truncation() const { return truncation_; } | 320 Truncation truncation() const { return truncation_; } |
291 void set_output_type(MachineType type) { output_ = type; } | 321 void set_output_type(NodeOutputInfo output) { output_ = output; } |
292 MachineType output_type() const { return output_; } | 322 |
| 323 Type* output_type() const { return output_.type(); } |
| 324 MachineRepresentation representation() const { |
| 325 return output_.representation(); |
| 326 } |
293 | 327 |
294 private: | 328 private: |
295 bool queued_ = false; // Bookkeeping for the traversal. | 329 bool queued_ = false; // Bookkeeping for the traversal. |
296 bool visited_ = false; // Bookkeeping for the traversal. | 330 bool visited_ = false; // Bookkeeping for the traversal. |
297 MachineType output_ = MachineType::None(); // Output type of the node. | 331 NodeOutputInfo output_; // Output type and representation. |
298 Truncation truncation_ = Truncation::None(); // Information about uses. | 332 Truncation truncation_ = Truncation::None(); // Information about uses. |
299 }; | 333 }; |
300 | 334 |
301 RepresentationSelector(JSGraph* jsgraph, Zone* zone, | 335 RepresentationSelector(JSGraph* jsgraph, Zone* zone, |
302 RepresentationChanger* changer, | 336 RepresentationChanger* changer, |
303 SourcePositionTable* source_positions) | 337 SourcePositionTable* source_positions) |
304 : jsgraph_(jsgraph), | 338 : jsgraph_(jsgraph), |
305 count_(jsgraph->graph()->NodeCount()), | 339 count_(jsgraph->graph()->NodeCount()), |
306 info_(count_, zone), | 340 info_(count_, zone), |
307 #ifdef DEBUG | 341 #ifdef DEBUG |
(...skipping 15 matching lines...) Expand all Loading... |
323 EnqueueInitial(jsgraph_->graph()->end()); | 357 EnqueueInitial(jsgraph_->graph()->end()); |
324 // Process nodes from the queue until it is empty. | 358 // Process nodes from the queue until it is empty. |
325 while (!queue_.empty()) { | 359 while (!queue_.empty()) { |
326 Node* node = queue_.front(); | 360 Node* node = queue_.front(); |
327 NodeInfo* info = GetInfo(node); | 361 NodeInfo* info = GetInfo(node); |
328 queue_.pop(); | 362 queue_.pop(); |
329 info->set_queued(false); | 363 info->set_queued(false); |
330 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic()); | 364 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic()); |
331 VisitNode(node, info->truncation(), nullptr); | 365 VisitNode(node, info->truncation(), nullptr); |
332 TRACE(" ==> output "); | 366 TRACE(" ==> output "); |
333 PrintInfo(info->output_type()); | 367 PrintOutputInfo(info); |
334 TRACE("\n"); | 368 TRACE("\n"); |
335 } | 369 } |
336 | 370 |
337 // Run lowering and change insertion phase. | 371 // Run lowering and change insertion phase. |
338 TRACE("--{Simplified lowering phase}--\n"); | 372 TRACE("--{Simplified lowering phase}--\n"); |
339 phase_ = LOWER; | 373 phase_ = LOWER; |
340 // Process nodes from the collected {nodes_} vector. | 374 // Process nodes from the collected {nodes_} vector. |
341 for (NodeVector::iterator i = nodes_.begin(); i != nodes_.end(); ++i) { | 375 for (NodeVector::iterator i = nodes_.begin(); i != nodes_.end(); ++i) { |
342 Node* node = *i; | 376 Node* node = *i; |
343 NodeInfo* info = GetInfo(node); | 377 NodeInfo* info = GetInfo(node); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 // the end and it has not been queued yet. | 456 // the end and it has not been queued yet. |
423 if (info->visited() && !info->queued()) { | 457 if (info->visited() && !info->queued()) { |
424 queue_.push(user); | 458 queue_.push(user); |
425 info->set_queued(true); | 459 info->set_queued(true); |
426 } | 460 } |
427 } | 461 } |
428 } | 462 } |
429 } | 463 } |
430 } | 464 } |
431 | 465 |
432 void SetOutput(Node* node, MachineType output) { | 466 void SetOutputFromMachineType(Node* node, MachineType machine_type) { |
| 467 Type* type = Type::None(); |
| 468 switch (machine_type.semantic()) { |
| 469 case MachineSemantic::kNone: |
| 470 type = Type::None(); |
| 471 break; |
| 472 case MachineSemantic::kBool: |
| 473 type = Type::Boolean(); |
| 474 break; |
| 475 case MachineSemantic::kInt32: |
| 476 type = Type::Signed32(); |
| 477 break; |
| 478 case MachineSemantic::kUint32: |
| 479 type = Type::Unsigned32(); |
| 480 break; |
| 481 case MachineSemantic::kInt64: |
| 482 // TODO(jarin) Fix once we have proper int64. |
| 483 type = Type::Internal(); |
| 484 break; |
| 485 case MachineSemantic::kUint64: |
| 486 // TODO(jarin) Fix once we have proper uint64. |
| 487 type = Type::Internal(); |
| 488 break; |
| 489 case MachineSemantic::kNumber: |
| 490 type = Type::Number(); |
| 491 break; |
| 492 case MachineSemantic::kAny: |
| 493 type = Type::Any(); |
| 494 break; |
| 495 } |
| 496 return SetOutput(node, NodeOutputInfo(machine_type.representation(), type)); |
| 497 } |
| 498 |
| 499 void SetOutput(Node* node, NodeOutputInfo output_info) { |
433 // Every node should have at most one output representation. Note that | 500 // Every node should have at most one output representation. Note that |
434 // phis can have 0, if they have not been used in a representation-inducing | 501 // phis can have 0, if they have not been used in a representation-inducing |
435 // instruction. | 502 // instruction. |
436 NodeInfo* info = GetInfo(node); | 503 NodeInfo* info = GetInfo(node); |
437 DCHECK(MachineTypeRepIsSubtype(info->output_type(), output)); | 504 DCHECK(MachineRepresentationIsSubtype(info->representation(), |
438 if (output != info->output_type()) { | 505 output_info.representation())); |
| 506 DCHECK(info->output_type()->Is(output_info.type())); |
| 507 if (!output_info.type()->Is(info->output_type()) || |
| 508 output_info.representation() != info->representation()) { |
439 EnqueueUses(node); | 509 EnqueueUses(node); |
440 } | 510 } |
441 info->set_output_type(output); | 511 info->set_output_type(output_info); |
442 } | 512 } |
443 | 513 |
444 bool BothInputsAreSigned32(Node* node) { | 514 bool BothInputsAreSigned32(Node* node) { |
445 DCHECK_EQ(2, node->InputCount()); | 515 DCHECK_EQ(2, node->InputCount()); |
446 return (NodeProperties::GetType(node->InputAt(0))->Is(Type::Signed32()) || | 516 return (NodeProperties::GetType(node->InputAt(0))->Is(Type::Signed32()) || |
447 (GetInfo(node->InputAt(0))->output_type().semantic() == | 517 GetInfo(node->InputAt(0))->output_type()->Is(Type::Signed32())) && |
448 MachineSemantic::kInt32)) && | |
449 (NodeProperties::GetType(node->InputAt(1))->Is(Type::Signed32()) || | 518 (NodeProperties::GetType(node->InputAt(1))->Is(Type::Signed32()) || |
450 (GetInfo(node->InputAt(1))->output_type().semantic() == | 519 GetInfo(node->InputAt(1))->output_type()->Is(Type::Signed32())); |
451 MachineSemantic::kInt32)); | |
452 } | 520 } |
453 | 521 |
454 bool BothInputsAreUnsigned32(Node* node) { | 522 bool BothInputsAreUnsigned32(Node* node) { |
455 DCHECK_EQ(2, node->InputCount()); | 523 DCHECK_EQ(2, node->InputCount()); |
456 return (NodeProperties::GetType(node->InputAt(0))->Is(Type::Unsigned32()) || | 524 return (NodeProperties::GetType(node->InputAt(0))->Is(Type::Unsigned32()) || |
457 GetInfo(node->InputAt(0))->output_type().semantic() == | 525 GetInfo(node->InputAt(0))->output_type()->Is(Type::Unsigned32())) && |
458 MachineSemantic::kUint32) && | |
459 (NodeProperties::GetType(node->InputAt(1))->Is(Type::Unsigned32()) || | 526 (NodeProperties::GetType(node->InputAt(1))->Is(Type::Unsigned32()) || |
460 GetInfo(node->InputAt(1))->output_type().semantic() == | 527 GetInfo(node->InputAt(1))->output_type()->Is(Type::Unsigned32())); |
461 MachineSemantic::kUint32); | |
462 } | 528 } |
463 | 529 |
464 bool BothInputsAre(Node* node, Type* type) { | 530 bool BothInputsAre(Node* node, Type* type) { |
465 DCHECK_EQ(2, node->InputCount()); | 531 DCHECK_EQ(2, node->InputCount()); |
466 return NodeProperties::GetType(node->InputAt(0))->Is(type) && | 532 return NodeProperties::GetType(node->InputAt(0))->Is(type) && |
467 NodeProperties::GetType(node->InputAt(1))->Is(type); | 533 NodeProperties::GetType(node->InputAt(1))->Is(type); |
468 } | 534 } |
469 | 535 |
470 void ConvertInput(Node* node, int index, UseInfo use) { | 536 void ConvertInput(Node* node, int index, UseInfo use) { |
471 Node* input = node->InputAt(index); | 537 Node* input = node->InputAt(index); |
472 // In the change phase, insert a change before the use if necessary. | 538 // In the change phase, insert a change before the use if necessary. |
473 if (use.preferred() == MachineRepresentation::kNone) | 539 if (use.preferred() == MachineRepresentation::kNone) |
474 return; // No input requirement on the use. | 540 return; // No input requirement on the use. |
475 MachineType output = GetInfo(input)->output_type(); | 541 NodeInfo* input_info = GetInfo(input); |
476 if (output.representation() != use.preferred()) { | 542 MachineRepresentation input_rep = input_info->representation(); |
| 543 if (input_rep != use.preferred()) { |
477 // Output representation doesn't match usage. | 544 // Output representation doesn't match usage. |
478 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(), | 545 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(), |
479 index, input->id(), input->op()->mnemonic()); | 546 index, input->id(), input->op()->mnemonic()); |
480 TRACE(" from "); | 547 TRACE(" from "); |
481 PrintInfo(output); | 548 PrintOutputInfo(input_info); |
482 TRACE(" to "); | 549 TRACE(" to "); |
483 PrintUseInfo(use); | 550 PrintUseInfo(use); |
484 TRACE("\n"); | 551 TRACE("\n"); |
485 Node* n = changer_->GetRepresentationFor(input, output, use.preferred(), | 552 Node* n = changer_->GetRepresentationFor( |
486 use.truncation()); | 553 input, input_info->representation(), input_info->output_type(), |
| 554 use.preferred(), use.truncation()); |
487 node->ReplaceInput(index, n); | 555 node->ReplaceInput(index, n); |
488 } | 556 } |
489 } | 557 } |
490 | 558 |
491 void ProcessInput(Node* node, int index, UseInfo use) { | 559 void ProcessInput(Node* node, int index, UseInfo use) { |
492 if (phase_ == PROPAGATE) { | 560 if (phase_ == PROPAGATE) { |
493 EnqueueInput(node, index, use); | 561 EnqueueInput(node, index, use); |
494 } else { | 562 } else { |
495 ConvertInput(node, index, use); | 563 ConvertInput(node, index, use); |
496 } | 564 } |
(...skipping 24 matching lines...) Expand all Loading... |
521 ProcessInput(node, i, UseInfo::AnyTagged()); | 589 ProcessInput(node, i, UseInfo::AnyTagged()); |
522 } | 590 } |
523 // Only enqueue other inputs (framestates, effects, control). | 591 // Only enqueue other inputs (framestates, effects, control). |
524 for (int i = tagged_count; i < node->InputCount(); i++) { | 592 for (int i = tagged_count; i < node->InputCount(); i++) { |
525 EnqueueInput(node, i); | 593 EnqueueInput(node, i); |
526 } | 594 } |
527 } | 595 } |
528 | 596 |
529 // Helper for binops of the R x L -> O variety. | 597 // Helper for binops of the R x L -> O variety. |
530 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, | 598 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, |
531 MachineType output) { | 599 NodeOutputInfo output) { |
532 DCHECK_EQ(2, node->op()->ValueInputCount()); | 600 DCHECK_EQ(2, node->op()->ValueInputCount()); |
533 ProcessInput(node, 0, left_use); | 601 ProcessInput(node, 0, left_use); |
534 ProcessInput(node, 1, right_use); | 602 ProcessInput(node, 1, right_use); |
535 for (int i = 2; i < node->InputCount(); i++) { | 603 for (int i = 2; i < node->InputCount(); i++) { |
536 EnqueueInput(node, i); | 604 EnqueueInput(node, i); |
537 } | 605 } |
538 SetOutput(node, output); | 606 SetOutput(node, output); |
539 } | 607 } |
540 | 608 |
541 // Helper for binops of the I x I -> O variety. | 609 // Helper for binops of the I x I -> O variety. |
542 void VisitBinop(Node* node, UseInfo input_use, MachineType output) { | 610 void VisitBinop(Node* node, UseInfo input_use, NodeOutputInfo output) { |
543 VisitBinop(node, input_use, input_use, output); | 611 VisitBinop(node, input_use, input_use, output); |
544 } | 612 } |
545 | 613 |
546 // Helper for unops of the I -> O variety. | 614 // Helper for unops of the I -> O variety. |
547 void VisitUnop(Node* node, UseInfo input_use, MachineType output) { | 615 void VisitUnop(Node* node, UseInfo input_use, NodeOutputInfo output) { |
548 DCHECK_EQ(1, node->InputCount()); | 616 DCHECK_EQ(1, node->InputCount()); |
549 ProcessInput(node, 0, input_use); | 617 ProcessInput(node, 0, input_use); |
550 SetOutput(node, output); | 618 SetOutput(node, output); |
551 } | 619 } |
552 | 620 |
553 // Helper for leaf nodes. | 621 // Helper for leaf nodes. |
554 void VisitLeaf(Node* node, MachineType output) { | 622 void VisitLeaf(Node* node, NodeOutputInfo output) { |
555 DCHECK_EQ(0, node->InputCount()); | 623 DCHECK_EQ(0, node->InputCount()); |
556 SetOutput(node, output); | 624 SetOutput(node, output); |
557 } | 625 } |
558 | 626 |
559 // Helpers for specific types of binops. | 627 // Helpers for specific types of binops. |
560 void VisitFloat64Binop(Node* node) { | 628 void VisitFloat64Binop(Node* node) { |
561 VisitBinop(node, UseInfo::Float64(), MachineType::Float64()); | 629 VisitBinop(node, UseInfo::Float64(), NodeOutputInfo::Float64()); |
562 } | 630 } |
563 void VisitInt32Binop(Node* node) { | 631 void VisitInt32Binop(Node* node) { |
564 VisitBinop(node, UseInfo::TruncatingWord32(), MachineType::Int32()); | 632 VisitBinop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Int32()); |
565 } | 633 } |
566 void VisitWord32TruncatingBinop(Node* node) { | 634 void VisitWord32TruncatingBinop(Node* node) { |
567 VisitBinop( | 635 VisitBinop(node, UseInfo::TruncatingWord32(), |
568 node, UseInfo::TruncatingWord32(), | 636 NodeOutputInfo::NumberTruncatedToWord32()); |
569 MachineType(MachineRepresentation::kWord32, MachineSemantic::kNumber)); | |
570 } | 637 } |
571 void VisitUint32Binop(Node* node) { | 638 void VisitUint32Binop(Node* node) { |
572 VisitBinop(node, UseInfo::TruncatingWord32(), MachineType::Uint32()); | 639 VisitBinop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Uint32()); |
573 } | 640 } |
574 void VisitInt64Binop(Node* node) { | 641 void VisitInt64Binop(Node* node) { |
575 VisitBinop(node, UseInfo::TruncatingWord64(), MachineType::Int64()); | 642 VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Int64()); |
576 } | 643 } |
577 void VisitUint64Binop(Node* node) { | 644 void VisitUint64Binop(Node* node) { |
578 VisitBinop(node, UseInfo::TruncatingWord64(), MachineType::Uint64()); | 645 VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Uint64()); |
579 } | 646 } |
580 void VisitFloat64Cmp(Node* node) { | 647 void VisitFloat64Cmp(Node* node) { |
581 VisitBinop(node, UseInfo::Float64(), MachineType::Bool()); | 648 VisitBinop(node, UseInfo::Float64(), NodeOutputInfo::Bool()); |
582 } | 649 } |
583 void VisitInt32Cmp(Node* node) { | 650 void VisitInt32Cmp(Node* node) { |
584 VisitBinop(node, UseInfo::TruncatingWord32(), MachineType::Bool()); | 651 VisitBinop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Bool()); |
585 } | 652 } |
586 void VisitUint32Cmp(Node* node) { | 653 void VisitUint32Cmp(Node* node) { |
587 VisitBinop(node, UseInfo::TruncatingWord32(), MachineType::Bool()); | 654 VisitBinop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Bool()); |
588 } | 655 } |
589 void VisitInt64Cmp(Node* node) { | 656 void VisitInt64Cmp(Node* node) { |
590 VisitBinop(node, UseInfo::TruncatingWord64(), MachineType::Bool()); | 657 VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Bool()); |
591 } | 658 } |
592 void VisitUint64Cmp(Node* node) { | 659 void VisitUint64Cmp(Node* node) { |
593 VisitBinop(node, UseInfo::TruncatingWord64(), MachineType::Bool()); | 660 VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Bool()); |
594 } | 661 } |
595 | 662 |
596 // Infer representation for phi-like nodes. | 663 // Infer representation for phi-like nodes. |
597 static MachineRepresentation GetRepresentationForPhi(Node* node, | 664 static MachineRepresentation GetRepresentationForPhi(Node* node, |
598 Truncation use) { | 665 Truncation use) { |
599 // Phis adapt to the output representation their uses demand. | 666 // Phis adapt to the output representation their uses demand. |
600 Type* upper = NodeProperties::GetType(node); | 667 Type* type = NodeProperties::GetType(node); |
601 if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) { | 668 if (type->Is(Type::Signed32()) || type->Is(Type::Unsigned32())) { |
602 // We are within 32 bits range => pick kRepWord32. | 669 // We are within 32 bits range => pick kRepWord32. |
603 return MachineRepresentation::kWord32; | 670 return MachineRepresentation::kWord32; |
604 } else if (use.TruncatesToWord32()) { | 671 } else if (use.TruncatesToWord32()) { |
605 // We only use 32 bits. | 672 // We only use 32 bits. |
606 return MachineRepresentation::kWord32; | 673 return MachineRepresentation::kWord32; |
607 } else if (upper->Is(Type::Boolean())) { | 674 } else if (type->Is(Type::Boolean())) { |
608 // multiple uses => pick kRepBit. | 675 // multiple uses => pick kRepBit. |
609 return MachineRepresentation::kBit; | 676 return MachineRepresentation::kBit; |
610 } else if (upper->Is(Type::Number())) { | 677 } else if (type->Is(Type::Number())) { |
611 // multiple uses => pick kRepFloat64. | 678 // multiple uses => pick kRepFloat64. |
612 return MachineRepresentation::kFloat64; | 679 return MachineRepresentation::kFloat64; |
613 } else if (upper->Is(Type::Internal())) { | 680 } else if (type->Is(Type::Internal())) { |
614 return MachineType::PointerRepresentation(); | 681 return MachineType::PointerRepresentation(); |
615 } | 682 } |
616 return MachineRepresentation::kTagged; | 683 return MachineRepresentation::kTagged; |
617 } | 684 } |
618 | 685 |
619 // Helper for handling selects. | 686 // Helper for handling selects. |
620 void VisitSelect(Node* node, Truncation truncation, | 687 void VisitSelect(Node* node, Truncation truncation, |
621 SimplifiedLowering* lowering) { | 688 SimplifiedLowering* lowering) { |
622 ProcessInput(node, 0, UseInfo::Bool()); | 689 ProcessInput(node, 0, UseInfo::Bool()); |
623 MachineRepresentation output = GetRepresentationForPhi(node, truncation); | 690 MachineRepresentation output = GetRepresentationForPhi(node, truncation); |
624 | 691 |
625 Type* upper = NodeProperties::GetType(node); | 692 Type* type = NodeProperties::GetType(node); |
626 MachineType output_type = | 693 SetOutput(node, NodeOutputInfo(output, type)); |
627 MachineType(output, changer_->TypeFromUpperBound(upper)); | |
628 SetOutput(node, output_type); | |
629 | 694 |
630 if (lower()) { | 695 if (lower()) { |
631 // Update the select operator. | 696 // Update the select operator. |
632 SelectParameters p = SelectParametersOf(node->op()); | 697 SelectParameters p = SelectParametersOf(node->op()); |
633 if (output != p.representation()) { | 698 if (output != p.representation()) { |
634 NodeProperties::ChangeOp(node, | 699 NodeProperties::ChangeOp(node, |
635 lowering->common()->Select(output, p.hint())); | 700 lowering->common()->Select(output, p.hint())); |
636 } | 701 } |
637 } | 702 } |
638 // Convert inputs to the output representation of this phi, pass the | 703 // Convert inputs to the output representation of this phi, pass the |
639 // truncation truncation along. | 704 // truncation truncation along. |
640 UseInfo input_use(output, truncation); | 705 UseInfo input_use(output, truncation); |
641 ProcessInput(node, 1, input_use); | 706 ProcessInput(node, 1, input_use); |
642 ProcessInput(node, 2, input_use); | 707 ProcessInput(node, 2, input_use); |
643 } | 708 } |
644 | 709 |
645 // Helper for handling phis. | 710 // Helper for handling phis. |
646 void VisitPhi(Node* node, Truncation truncation, | 711 void VisitPhi(Node* node, Truncation truncation, |
647 SimplifiedLowering* lowering) { | 712 SimplifiedLowering* lowering) { |
648 MachineRepresentation output = GetRepresentationForPhi(node, truncation); | 713 MachineRepresentation output = GetRepresentationForPhi(node, truncation); |
649 | 714 |
650 Type* upper = NodeProperties::GetType(node); | 715 Type* type = NodeProperties::GetType(node); |
651 MachineType output_type = | 716 SetOutput(node, NodeOutputInfo(output, type)); |
652 MachineType(output, changer_->TypeFromUpperBound(upper)); | |
653 SetOutput(node, output_type); | |
654 | 717 |
655 int values = node->op()->ValueInputCount(); | 718 int values = node->op()->ValueInputCount(); |
656 | 719 |
657 if (lower()) { | 720 if (lower()) { |
658 // Update the phi operator. | 721 // Update the phi operator. |
659 if (output != PhiRepresentationOf(node->op())) { | 722 if (output != PhiRepresentationOf(node->op())) { |
660 NodeProperties::ChangeOp(node, lowering->common()->Phi(output, values)); | 723 NodeProperties::ChangeOp(node, lowering->common()->Phi(output, values)); |
661 } | 724 } |
662 } | 725 } |
663 | 726 |
(...skipping 16 matching lines...) Expand all Loading... |
680 ProcessInput(node, i, UseInfo::None()); | 743 ProcessInput(node, i, UseInfo::None()); |
681 } else if ((i - 1) < params) { | 744 } else if ((i - 1) < params) { |
682 ProcessInput(node, i, TruncatingUseInfoFromRepresentation( | 745 ProcessInput(node, i, TruncatingUseInfoFromRepresentation( |
683 sig->GetParam(i - 1).representation())); | 746 sig->GetParam(i - 1).representation())); |
684 } else { | 747 } else { |
685 ProcessInput(node, i, UseInfo::None()); | 748 ProcessInput(node, i, UseInfo::None()); |
686 } | 749 } |
687 } | 750 } |
688 | 751 |
689 if (sig->return_count() > 0) { | 752 if (sig->return_count() > 0) { |
690 SetOutput(node, desc->GetMachineSignature()->GetReturn()); | 753 SetOutputFromMachineType(node, desc->GetMachineSignature()->GetReturn()); |
691 } else { | 754 } else { |
692 SetOutput(node, MachineType::AnyTagged()); | 755 SetOutput(node, NodeOutputInfo::AnyTagged()); |
693 } | 756 } |
694 } | 757 } |
695 | 758 |
| 759 MachineSemantic DeoptValueSemanticOf(Type* type) { |
| 760 CHECK(!type->Is(Type::None())); |
| 761 // We only need signedness to do deopt correctly. |
| 762 if (type->Is(Type::Signed32())) { |
| 763 return MachineSemantic::kInt32; |
| 764 } else if (type->Is(Type::Unsigned32())) { |
| 765 return MachineSemantic::kUint32; |
| 766 } else { |
| 767 return MachineSemantic::kAny; |
| 768 } |
| 769 } |
| 770 |
696 void VisitStateValues(Node* node) { | 771 void VisitStateValues(Node* node) { |
697 if (phase_ == PROPAGATE) { | 772 if (phase_ == PROPAGATE) { |
698 for (int i = 0; i < node->InputCount(); i++) { | 773 for (int i = 0; i < node->InputCount(); i++) { |
699 EnqueueInput(node, i, UseInfo::Any()); | 774 EnqueueInput(node, i, UseInfo::Any()); |
700 } | 775 } |
701 } else { | 776 } else { |
702 Zone* zone = jsgraph_->zone(); | 777 Zone* zone = jsgraph_->zone(); |
703 ZoneVector<MachineType>* types = | 778 ZoneVector<MachineType>* types = |
704 new (zone->New(sizeof(ZoneVector<MachineType>))) | 779 new (zone->New(sizeof(ZoneVector<MachineType>))) |
705 ZoneVector<MachineType>(node->InputCount(), zone); | 780 ZoneVector<MachineType>(node->InputCount(), zone); |
706 for (int i = 0; i < node->InputCount(); i++) { | 781 for (int i = 0; i < node->InputCount(); i++) { |
707 MachineType input_type = GetInfo(node->InputAt(i))->output_type(); | 782 NodeInfo* input_info = GetInfo(node->InputAt(i)); |
708 (*types)[i] = input_type; | 783 (*types)[i] = |
| 784 MachineType(input_info->representation(), |
| 785 DeoptValueSemanticOf(input_info->output_type())); |
709 } | 786 } |
710 NodeProperties::ChangeOp(node, | 787 NodeProperties::ChangeOp(node, |
711 jsgraph_->common()->TypedStateValues(types)); | 788 jsgraph_->common()->TypedStateValues(types)); |
712 } | 789 } |
713 SetOutput(node, MachineType::AnyTagged()); | 790 SetOutput(node, NodeOutputInfo::AnyTagged()); |
714 } | 791 } |
715 | 792 |
716 const Operator* Int32Op(Node* node) { | 793 const Operator* Int32Op(Node* node) { |
717 return changer_->Int32OperatorFor(node->opcode()); | 794 return changer_->Int32OperatorFor(node->opcode()); |
718 } | 795 } |
719 | 796 |
720 const Operator* Uint32Op(Node* node) { | 797 const Operator* Uint32Op(Node* node) { |
721 return changer_->Uint32OperatorFor(node->opcode()); | 798 return changer_->Uint32OperatorFor(node->opcode()); |
722 } | 799 } |
723 | 800 |
(...skipping 25 matching lines...) Expand all Loading... |
749 // Dispatching routine for visiting the node {node} with the usage {use}. | 826 // Dispatching routine for visiting the node {node} with the usage {use}. |
750 // Depending on the operator, propagate new usage info to the inputs. | 827 // Depending on the operator, propagate new usage info to the inputs. |
751 void VisitNode(Node* node, Truncation truncation, | 828 void VisitNode(Node* node, Truncation truncation, |
752 SimplifiedLowering* lowering) { | 829 SimplifiedLowering* lowering) { |
753 switch (node->opcode()) { | 830 switch (node->opcode()) { |
754 //------------------------------------------------------------------ | 831 //------------------------------------------------------------------ |
755 // Common operators. | 832 // Common operators. |
756 //------------------------------------------------------------------ | 833 //------------------------------------------------------------------ |
757 case IrOpcode::kStart: | 834 case IrOpcode::kStart: |
758 case IrOpcode::kDead: | 835 case IrOpcode::kDead: |
759 return VisitLeaf(node, MachineType::None()); | 836 return VisitLeaf(node, NodeOutputInfo::None()); |
760 case IrOpcode::kParameter: { | 837 case IrOpcode::kParameter: { |
761 // TODO(titzer): use representation from linkage. | 838 // TODO(titzer): use representation from linkage. |
762 Type* upper = NodeProperties::GetType(node); | 839 Type* type = NodeProperties::GetType(node); |
763 ProcessInput(node, 0, UseInfo::None()); | 840 ProcessInput(node, 0, UseInfo::None()); |
764 SetOutput(node, MachineType(MachineRepresentation::kTagged, | 841 SetOutput(node, NodeOutputInfo(MachineRepresentation::kTagged, type)); |
765 changer_->TypeFromUpperBound(upper))); | |
766 return; | 842 return; |
767 } | 843 } |
768 case IrOpcode::kInt32Constant: | 844 case IrOpcode::kInt32Constant: |
769 return VisitLeaf(node, MachineType::RepWord32()); | 845 return VisitLeaf(node, NodeOutputInfo::Int32()); |
770 case IrOpcode::kInt64Constant: | 846 case IrOpcode::kInt64Constant: |
771 return VisitLeaf(node, MachineType::RepWord64()); | 847 return VisitLeaf(node, NodeOutputInfo::Int64()); |
772 case IrOpcode::kFloat32Constant: | 848 case IrOpcode::kFloat32Constant: |
773 return VisitLeaf(node, MachineType::RepFloat32()); | 849 return VisitLeaf(node, NodeOutputInfo::Float32()); |
774 case IrOpcode::kFloat64Constant: | 850 case IrOpcode::kFloat64Constant: |
775 return VisitLeaf(node, MachineType::RepFloat64()); | 851 return VisitLeaf(node, NodeOutputInfo::Float64()); |
776 case IrOpcode::kExternalConstant: | 852 case IrOpcode::kExternalConstant: |
777 return VisitLeaf(node, MachineType::Pointer()); | 853 return VisitLeaf(node, NodeOutputInfo::Pointer()); |
778 case IrOpcode::kNumberConstant: | 854 case IrOpcode::kNumberConstant: |
779 return VisitLeaf(node, MachineType::RepTagged()); | 855 return VisitLeaf(node, NodeOutputInfo::NumberTagged()); |
780 case IrOpcode::kHeapConstant: | 856 case IrOpcode::kHeapConstant: |
781 return VisitLeaf(node, MachineType::RepTagged()); | 857 return VisitLeaf(node, NodeOutputInfo::AnyTagged()); |
782 | 858 |
783 case IrOpcode::kBranch: | 859 case IrOpcode::kBranch: |
784 ProcessInput(node, 0, UseInfo::Bool()); | 860 ProcessInput(node, 0, UseInfo::Bool()); |
785 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); | 861 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); |
786 break; | 862 break; |
787 case IrOpcode::kSwitch: | 863 case IrOpcode::kSwitch: |
788 ProcessInput(node, 0, UseInfo::TruncatingWord32()); | 864 ProcessInput(node, 0, UseInfo::TruncatingWord32()); |
789 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); | 865 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); |
790 break; | 866 break; |
791 case IrOpcode::kSelect: | 867 case IrOpcode::kSelect: |
792 return VisitSelect(node, truncation, lowering); | 868 return VisitSelect(node, truncation, lowering); |
793 case IrOpcode::kPhi: | 869 case IrOpcode::kPhi: |
794 return VisitPhi(node, truncation, lowering); | 870 return VisitPhi(node, truncation, lowering); |
795 case IrOpcode::kCall: | 871 case IrOpcode::kCall: |
796 return VisitCall(node, lowering); | 872 return VisitCall(node, lowering); |
797 | 873 |
798 //------------------------------------------------------------------ | 874 //------------------------------------------------------------------ |
799 // JavaScript operators. | 875 // JavaScript operators. |
800 //------------------------------------------------------------------ | 876 //------------------------------------------------------------------ |
801 // For now, we assume that all JS operators were too complex to lower | 877 // For now, we assume that all JS operators were too complex to lower |
802 // to Simplified and that they will always require tagged value inputs | 878 // to Simplified and that they will always require tagged value inputs |
803 // and produce tagged value outputs. | 879 // and produce tagged value outputs. |
804 // TODO(turbofan): it might be possible to lower some JSOperators here, | 880 // TODO(turbofan): it might be possible to lower some JSOperators here, |
805 // but that responsibility really lies in the typed lowering phase. | 881 // but that responsibility really lies in the typed lowering phase. |
806 #define DEFINE_JS_CASE(x) case IrOpcode::k##x: | 882 #define DEFINE_JS_CASE(x) case IrOpcode::k##x: |
807 JS_OP_LIST(DEFINE_JS_CASE) | 883 JS_OP_LIST(DEFINE_JS_CASE) |
808 #undef DEFINE_JS_CASE | 884 #undef DEFINE_JS_CASE |
809 VisitInputs(node); | 885 VisitInputs(node); |
810 return SetOutput(node, MachineType::RepTagged()); | 886 return SetOutput(node, NodeOutputInfo::AnyTagged()); |
811 | 887 |
812 //------------------------------------------------------------------ | 888 //------------------------------------------------------------------ |
813 // Simplified operators. | 889 // Simplified operators. |
814 //------------------------------------------------------------------ | 890 //------------------------------------------------------------------ |
815 case IrOpcode::kBooleanNot: { | 891 case IrOpcode::kBooleanNot: { |
816 if (lower()) { | 892 if (lower()) { |
817 MachineType input = GetInfo(node->InputAt(0))->output_type(); | 893 NodeInfo* input_info = GetInfo(node->InputAt(0)); |
818 if (input.representation() == MachineRepresentation::kBit) { | 894 if (input_info->representation() == MachineRepresentation::kBit) { |
819 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) | 895 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) |
820 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); | 896 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); |
821 NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal()); | 897 NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal()); |
822 } else { | 898 } else { |
823 // BooleanNot(x: kRepTagged) => WordEqual(x, #false) | 899 // BooleanNot(x: kRepTagged) => WordEqual(x, #false) |
824 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant()); | 900 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant()); |
825 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); | 901 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
826 } | 902 } |
827 } else { | 903 } else { |
828 // No input representation requirement; adapt during lowering. | 904 // No input representation requirement; adapt during lowering. |
829 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); | 905 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); |
830 SetOutput(node, MachineType::RepBit()); | 906 SetOutput(node, NodeOutputInfo::Bool()); |
831 } | 907 } |
832 break; | 908 break; |
833 } | 909 } |
834 case IrOpcode::kBooleanToNumber: { | 910 case IrOpcode::kBooleanToNumber: { |
835 if (lower()) { | 911 if (lower()) { |
836 MachineType input = GetInfo(node->InputAt(0))->output_type(); | 912 NodeInfo* input_info = GetInfo(node->InputAt(0)); |
837 if (input.representation() == MachineRepresentation::kBit) { | 913 if (input_info->representation() == MachineRepresentation::kBit) { |
838 // BooleanToNumber(x: kRepBit) => x | 914 // BooleanToNumber(x: kRepBit) => x |
839 DeferReplacement(node, node->InputAt(0)); | 915 DeferReplacement(node, node->InputAt(0)); |
840 } else { | 916 } else { |
841 // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true) | 917 // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true) |
842 node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant()); | 918 node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant()); |
843 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); | 919 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
844 } | 920 } |
845 } else { | 921 } else { |
846 // No input representation requirement; adapt during lowering. | 922 // No input representation requirement; adapt during lowering. |
847 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); | 923 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); |
848 SetOutput(node, MachineType::Int32()); | 924 SetOutput(node, NodeOutputInfo::Int32()); |
849 } | 925 } |
850 break; | 926 break; |
851 } | 927 } |
852 case IrOpcode::kNumberEqual: | 928 case IrOpcode::kNumberEqual: |
853 case IrOpcode::kNumberLessThan: | 929 case IrOpcode::kNumberLessThan: |
854 case IrOpcode::kNumberLessThanOrEqual: { | 930 case IrOpcode::kNumberLessThanOrEqual: { |
855 // Number comparisons reduce to integer comparisons for integer inputs. | 931 // Number comparisons reduce to integer comparisons for integer inputs. |
856 if (BothInputsAreSigned32(node)) { | 932 if (BothInputsAreSigned32(node)) { |
857 // => signed Int32Cmp | 933 // => signed Int32Cmp |
858 VisitInt32Cmp(node); | 934 VisitInt32Cmp(node); |
859 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); | 935 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
860 } else if (BothInputsAreUnsigned32(node)) { | 936 } else if (BothInputsAreUnsigned32(node)) { |
861 // => unsigned Int32Cmp | 937 // => unsigned Int32Cmp |
862 VisitUint32Cmp(node); | 938 VisitUint32Cmp(node); |
863 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); | 939 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); |
864 } else { | 940 } else { |
865 // => Float64Cmp | 941 // => Float64Cmp |
866 VisitFloat64Cmp(node); | 942 VisitFloat64Cmp(node); |
867 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); | 943 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
868 } | 944 } |
869 break; | 945 break; |
870 } | 946 } |
871 case IrOpcode::kNumberAdd: | 947 case IrOpcode::kNumberAdd: |
872 case IrOpcode::kNumberSubtract: { | 948 case IrOpcode::kNumberSubtract: { |
873 // Add and subtract reduce to Int32Add/Sub if the inputs | 949 // Add and subtract reduce to Int32Add/Sub if the inputs |
874 // are safe integers and all uses are truncating. | 950 // are safe integers and all uses are truncating. |
875 if (BothInputsAre(node, type_cache_.kAdditiveSafeInteger) && | 951 if (BothInputsAre(node, type_cache_.kAdditiveSafeInteger) && |
876 truncation.TruncatesToWord32()) { | 952 truncation.TruncatesToWord32()) { |
877 // => signed Int32Add/Sub | 953 // => signed Int32Add/Sub |
878 VisitInt32Binop(node); | 954 VisitWord32TruncatingBinop(node); |
879 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); | 955 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
880 } else { | 956 } else { |
881 // => Float64Add/Sub | 957 // => Float64Add/Sub |
882 VisitFloat64Binop(node); | 958 VisitFloat64Binop(node); |
883 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); | 959 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
884 } | 960 } |
885 break; | 961 break; |
886 } | 962 } |
887 case IrOpcode::kNumberMultiply: { | 963 case IrOpcode::kNumberMultiply: { |
888 if (BothInputsAreSigned32(node)) { | 964 if (BothInputsAreSigned32(node)) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 } | 1038 } |
963 case IrOpcode::kNumberBitwiseOr: | 1039 case IrOpcode::kNumberBitwiseOr: |
964 case IrOpcode::kNumberBitwiseXor: | 1040 case IrOpcode::kNumberBitwiseXor: |
965 case IrOpcode::kNumberBitwiseAnd: { | 1041 case IrOpcode::kNumberBitwiseAnd: { |
966 VisitInt32Binop(node); | 1042 VisitInt32Binop(node); |
967 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); | 1043 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
968 break; | 1044 break; |
969 } | 1045 } |
970 case IrOpcode::kNumberShiftLeft: { | 1046 case IrOpcode::kNumberShiftLeft: { |
971 VisitBinop(node, UseInfo::TruncatingWord32(), | 1047 VisitBinop(node, UseInfo::TruncatingWord32(), |
972 UseInfo::TruncatingWord32(), MachineType::Int32()); | 1048 UseInfo::TruncatingWord32(), NodeOutputInfo::Int32()); |
973 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shl()); | 1049 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shl()); |
974 break; | 1050 break; |
975 } | 1051 } |
976 case IrOpcode::kNumberShiftRight: { | 1052 case IrOpcode::kNumberShiftRight: { |
977 VisitBinop(node, UseInfo::TruncatingWord32(), | 1053 VisitBinop(node, UseInfo::TruncatingWord32(), |
978 UseInfo::TruncatingWord32(), MachineType::Int32()); | 1054 UseInfo::TruncatingWord32(), NodeOutputInfo::Int32()); |
979 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Sar()); | 1055 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Sar()); |
980 break; | 1056 break; |
981 } | 1057 } |
982 case IrOpcode::kNumberShiftRightLogical: { | 1058 case IrOpcode::kNumberShiftRightLogical: { |
983 VisitBinop(node, UseInfo::TruncatingWord32(), | 1059 VisitBinop(node, UseInfo::TruncatingWord32(), |
984 UseInfo::TruncatingWord32(), MachineType::Uint32()); | 1060 UseInfo::TruncatingWord32(), NodeOutputInfo::Uint32()); |
985 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shr()); | 1061 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shr()); |
986 break; | 1062 break; |
987 } | 1063 } |
988 case IrOpcode::kNumberToInt32: { | 1064 case IrOpcode::kNumberToInt32: { |
989 // Just change representation if necessary. | 1065 // Just change representation if necessary. |
990 VisitUnop(node, UseInfo::TruncatingWord32(), MachineType::Int32()); | 1066 VisitUnop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Int32()); |
991 if (lower()) DeferReplacement(node, node->InputAt(0)); | 1067 if (lower()) DeferReplacement(node, node->InputAt(0)); |
992 break; | 1068 break; |
993 } | 1069 } |
994 case IrOpcode::kNumberToUint32: { | 1070 case IrOpcode::kNumberToUint32: { |
995 // Just change representation if necessary. | 1071 // Just change representation if necessary. |
996 VisitUnop(node, UseInfo::TruncatingWord32(), MachineType::Uint32()); | 1072 VisitUnop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Uint32()); |
997 if (lower()) DeferReplacement(node, node->InputAt(0)); | 1073 if (lower()) DeferReplacement(node, node->InputAt(0)); |
998 break; | 1074 break; |
999 } | 1075 } |
1000 case IrOpcode::kNumberIsHoleNaN: { | 1076 case IrOpcode::kNumberIsHoleNaN: { |
1001 VisitUnop(node, UseInfo::Float64(), MachineType::Bool()); | 1077 VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Bool()); |
1002 if (lower()) { | 1078 if (lower()) { |
1003 // NumberIsHoleNaN(x) => Word32Equal(Float64ExtractLowWord32(x), | 1079 // NumberIsHoleNaN(x) => Word32Equal(Float64ExtractLowWord32(x), |
1004 // #HoleNaNLower32) | 1080 // #HoleNaNLower32) |
1005 node->ReplaceInput(0, | 1081 node->ReplaceInput(0, |
1006 jsgraph_->graph()->NewNode( | 1082 jsgraph_->graph()->NewNode( |
1007 lowering->machine()->Float64ExtractLowWord32(), | 1083 lowering->machine()->Float64ExtractLowWord32(), |
1008 node->InputAt(0))); | 1084 node->InputAt(0))); |
1009 node->AppendInput(jsgraph_->zone(), | 1085 node->AppendInput(jsgraph_->zone(), |
1010 jsgraph_->Int32Constant(kHoleNanLower32)); | 1086 jsgraph_->Int32Constant(kHoleNanLower32)); |
1011 NodeProperties::ChangeOp(node, jsgraph_->machine()->Word32Equal()); | 1087 NodeProperties::ChangeOp(node, jsgraph_->machine()->Word32Equal()); |
1012 } | 1088 } |
1013 break; | 1089 break; |
1014 } | 1090 } |
1015 case IrOpcode::kPlainPrimitiveToNumber: { | 1091 case IrOpcode::kPlainPrimitiveToNumber: { |
1016 VisitUnop(node, UseInfo::AnyTagged(), | 1092 VisitUnop(node, UseInfo::AnyTagged(), NodeOutputInfo::NumberTagged()); |
1017 MachineType(MachineRepresentation::kTagged, | |
1018 MachineSemantic::kNumber)); | |
1019 if (lower()) { | 1093 if (lower()) { |
1020 // PlainPrimitiveToNumber(x) => Call(ToNumberStub, x, no-context) | 1094 // PlainPrimitiveToNumber(x) => Call(ToNumberStub, x, no-context) |
1021 Operator::Properties properties = node->op()->properties(); | 1095 Operator::Properties properties = node->op()->properties(); |
1022 Callable callable = CodeFactory::ToNumber(jsgraph_->isolate()); | 1096 Callable callable = CodeFactory::ToNumber(jsgraph_->isolate()); |
1023 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | 1097 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
1024 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 1098 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
1025 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, | 1099 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, |
1026 flags, properties); | 1100 flags, properties); |
1027 node->InsertInput(jsgraph_->zone(), 0, | 1101 node->InsertInput(jsgraph_->zone(), 0, |
1028 jsgraph_->HeapConstant(callable.code())); | 1102 jsgraph_->HeapConstant(callable.code())); |
1029 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); | 1103 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); |
1030 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); | 1104 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); |
1031 } | 1105 } |
1032 break; | 1106 break; |
1033 } | 1107 } |
1034 case IrOpcode::kReferenceEqual: { | 1108 case IrOpcode::kReferenceEqual: { |
1035 VisitBinop(node, UseInfo::AnyTagged(), MachineType::Bool()); | 1109 VisitBinop(node, UseInfo::AnyTagged(), NodeOutputInfo::Bool()); |
1036 if (lower()) { | 1110 if (lower()) { |
1037 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); | 1111 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
1038 } | 1112 } |
1039 break; | 1113 break; |
1040 } | 1114 } |
1041 case IrOpcode::kStringEqual: { | 1115 case IrOpcode::kStringEqual: { |
1042 VisitBinop(node, UseInfo::AnyTagged(), MachineType::Bool()); | 1116 VisitBinop(node, UseInfo::AnyTagged(), NodeOutputInfo::Bool()); |
1043 if (lower()) lowering->DoStringEqual(node); | 1117 if (lower()) lowering->DoStringEqual(node); |
1044 break; | 1118 break; |
1045 } | 1119 } |
1046 case IrOpcode::kStringLessThan: { | 1120 case IrOpcode::kStringLessThan: { |
1047 VisitBinop(node, UseInfo::AnyTagged(), MachineType::Bool()); | 1121 VisitBinop(node, UseInfo::AnyTagged(), NodeOutputInfo::Bool()); |
1048 if (lower()) lowering->DoStringLessThan(node); | 1122 if (lower()) lowering->DoStringLessThan(node); |
1049 break; | 1123 break; |
1050 } | 1124 } |
1051 case IrOpcode::kStringLessThanOrEqual: { | 1125 case IrOpcode::kStringLessThanOrEqual: { |
1052 VisitBinop(node, UseInfo::AnyTagged(), MachineType::Bool()); | 1126 VisitBinop(node, UseInfo::AnyTagged(), NodeOutputInfo::Bool()); |
1053 if (lower()) lowering->DoStringLessThanOrEqual(node); | 1127 if (lower()) lowering->DoStringLessThanOrEqual(node); |
1054 break; | 1128 break; |
1055 } | 1129 } |
1056 case IrOpcode::kAllocate: { | 1130 case IrOpcode::kAllocate: { |
1057 ProcessInput(node, 0, UseInfo::AnyTagged()); | 1131 ProcessInput(node, 0, UseInfo::AnyTagged()); |
1058 ProcessRemainingInputs(node, 1); | 1132 ProcessRemainingInputs(node, 1); |
1059 SetOutput(node, MachineType::AnyTagged()); | 1133 SetOutput(node, NodeOutputInfo::AnyTagged()); |
1060 break; | 1134 break; |
1061 } | 1135 } |
1062 case IrOpcode::kLoadField: { | 1136 case IrOpcode::kLoadField: { |
1063 FieldAccess access = FieldAccessOf(node->op()); | 1137 FieldAccess access = FieldAccessOf(node->op()); |
1064 ProcessInput(node, 0, UseInfoForBasePointer(access)); | 1138 ProcessInput(node, 0, UseInfoForBasePointer(access)); |
1065 ProcessRemainingInputs(node, 1); | 1139 ProcessRemainingInputs(node, 1); |
1066 SetOutput(node, access.machine_type); | 1140 SetOutputFromMachineType(node, access.machine_type); |
1067 break; | 1141 break; |
1068 } | 1142 } |
1069 case IrOpcode::kStoreField: { | 1143 case IrOpcode::kStoreField: { |
1070 FieldAccess access = FieldAccessOf(node->op()); | 1144 FieldAccess access = FieldAccessOf(node->op()); |
1071 ProcessInput(node, 0, UseInfoForBasePointer(access)); | 1145 ProcessInput(node, 0, UseInfoForBasePointer(access)); |
1072 ProcessInput(node, 1, TruncatingUseInfoFromRepresentation( | 1146 ProcessInput(node, 1, TruncatingUseInfoFromRepresentation( |
1073 access.machine_type.representation())); | 1147 access.machine_type.representation())); |
1074 ProcessRemainingInputs(node, 2); | 1148 ProcessRemainingInputs(node, 2); |
1075 SetOutput(node, MachineType::None()); | 1149 SetOutput(node, NodeOutputInfo::None()); |
1076 break; | 1150 break; |
1077 } | 1151 } |
1078 case IrOpcode::kLoadBuffer: { | 1152 case IrOpcode::kLoadBuffer: { |
1079 BufferAccess access = BufferAccessOf(node->op()); | 1153 BufferAccess access = BufferAccessOf(node->op()); |
1080 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer | 1154 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer |
1081 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset | 1155 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset |
1082 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length | 1156 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length |
1083 ProcessRemainingInputs(node, 3); | 1157 ProcessRemainingInputs(node, 3); |
1084 | 1158 |
1085 MachineType output_type; | 1159 NodeOutputInfo output_info; |
1086 if (truncation.TruncatesUndefinedToZeroOrNaN()) { | 1160 if (truncation.TruncatesUndefinedToZeroOrNaN()) { |
1087 if (truncation.TruncatesNaNToZero()) { | 1161 if (truncation.TruncatesNaNToZero()) { |
1088 // If undefined is truncated to a non-NaN number, we can use | 1162 // If undefined is truncated to a non-NaN number, we can use |
1089 // the load's representation. | 1163 // the load's representation. |
1090 output_type = access.machine_type(); | 1164 output_info = NodeOutputInfo(access.machine_type().representation(), |
| 1165 NodeProperties::GetType(node)); |
1091 } else { | 1166 } else { |
1092 // If undefined is truncated to a number, but the use can | 1167 // If undefined is truncated to a number, but the use can |
1093 // observe NaN, we need to output at least the float32 | 1168 // observe NaN, we need to output at least the float32 |
1094 // representation. | 1169 // representation. |
1095 if (access.machine_type().representation() == | 1170 if (access.machine_type().representation() == |
1096 MachineRepresentation::kFloat32) { | 1171 MachineRepresentation::kFloat32) { |
1097 output_type = access.machine_type(); | 1172 output_info = |
| 1173 NodeOutputInfo(access.machine_type().representation(), |
| 1174 NodeProperties::GetType(node)); |
1098 } else { | 1175 } else { |
1099 output_type = MachineType::Float64(); | 1176 output_info = NodeOutputInfo::Float64(); |
1100 } | 1177 } |
1101 } | 1178 } |
1102 } else { | 1179 } else { |
1103 // If undefined is not truncated away, we need to have the tagged | 1180 // If undefined is not truncated away, we need to have the tagged |
1104 // representation. | 1181 // representation. |
1105 output_type = MachineType::AnyTagged(); | 1182 output_info = NodeOutputInfo::AnyTagged(); |
1106 } | 1183 } |
1107 SetOutput(node, output_type); | 1184 SetOutput(node, output_info); |
1108 if (lower()) lowering->DoLoadBuffer(node, output_type, changer_); | 1185 if (lower()) |
| 1186 lowering->DoLoadBuffer(node, output_info.representation(), changer_); |
1109 break; | 1187 break; |
1110 } | 1188 } |
1111 case IrOpcode::kStoreBuffer: { | 1189 case IrOpcode::kStoreBuffer: { |
1112 BufferAccess access = BufferAccessOf(node->op()); | 1190 BufferAccess access = BufferAccessOf(node->op()); |
1113 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer | 1191 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer |
1114 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset | 1192 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset |
1115 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length | 1193 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length |
1116 ProcessInput(node, 3, | 1194 ProcessInput(node, 3, |
1117 TruncatingUseInfoFromRepresentation( | 1195 TruncatingUseInfoFromRepresentation( |
1118 access.machine_type().representation())); // value | 1196 access.machine_type().representation())); // value |
1119 ProcessRemainingInputs(node, 4); | 1197 ProcessRemainingInputs(node, 4); |
1120 SetOutput(node, MachineType::None()); | 1198 SetOutput(node, NodeOutputInfo::None()); |
1121 if (lower()) lowering->DoStoreBuffer(node); | 1199 if (lower()) lowering->DoStoreBuffer(node); |
1122 break; | 1200 break; |
1123 } | 1201 } |
1124 case IrOpcode::kLoadElement: { | 1202 case IrOpcode::kLoadElement: { |
1125 ElementAccess access = ElementAccessOf(node->op()); | 1203 ElementAccess access = ElementAccessOf(node->op()); |
1126 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base | 1204 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base |
1127 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index | 1205 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index |
1128 ProcessRemainingInputs(node, 2); | 1206 ProcessRemainingInputs(node, 2); |
1129 SetOutput(node, access.machine_type); | 1207 SetOutputFromMachineType(node, access.machine_type); |
1130 break; | 1208 break; |
1131 } | 1209 } |
1132 case IrOpcode::kStoreElement: { | 1210 case IrOpcode::kStoreElement: { |
1133 ElementAccess access = ElementAccessOf(node->op()); | 1211 ElementAccess access = ElementAccessOf(node->op()); |
1134 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base | 1212 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base |
1135 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index | 1213 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index |
1136 ProcessInput(node, 2, | 1214 ProcessInput(node, 2, |
1137 TruncatingUseInfoFromRepresentation( | 1215 TruncatingUseInfoFromRepresentation( |
1138 access.machine_type.representation())); // value | 1216 access.machine_type.representation())); // value |
1139 ProcessRemainingInputs(node, 3); | 1217 ProcessRemainingInputs(node, 3); |
1140 SetOutput(node, MachineType::None()); | 1218 SetOutput(node, NodeOutputInfo::None()); |
1141 break; | 1219 break; |
1142 } | 1220 } |
1143 case IrOpcode::kObjectIsNumber: { | 1221 case IrOpcode::kObjectIsNumber: { |
1144 ProcessInput(node, 0, UseInfo::AnyTagged()); | 1222 ProcessInput(node, 0, UseInfo::AnyTagged()); |
1145 SetOutput(node, MachineType::Bool()); | 1223 SetOutput(node, NodeOutputInfo::Bool()); |
1146 if (lower()) lowering->DoObjectIsNumber(node); | 1224 if (lower()) lowering->DoObjectIsNumber(node); |
1147 break; | 1225 break; |
1148 } | 1226 } |
1149 case IrOpcode::kObjectIsSmi: { | 1227 case IrOpcode::kObjectIsSmi: { |
1150 ProcessInput(node, 0, UseInfo::AnyTagged()); | 1228 ProcessInput(node, 0, UseInfo::AnyTagged()); |
1151 SetOutput(node, MachineType::Bool()); | 1229 SetOutput(node, NodeOutputInfo::Bool()); |
1152 if (lower()) lowering->DoObjectIsSmi(node); | 1230 if (lower()) lowering->DoObjectIsSmi(node); |
1153 break; | 1231 break; |
1154 } | 1232 } |
1155 | 1233 |
1156 //------------------------------------------------------------------ | 1234 //------------------------------------------------------------------ |
1157 // Machine-level operators. | 1235 // Machine-level operators. |
1158 //------------------------------------------------------------------ | 1236 //------------------------------------------------------------------ |
1159 case IrOpcode::kLoad: { | 1237 case IrOpcode::kLoad: { |
1160 // TODO(jarin) Eventually, we should get rid of all machine stores | 1238 // TODO(jarin) Eventually, we should get rid of all machine stores |
1161 // from the high-level phases, then this becomes UNREACHABLE. | 1239 // from the high-level phases, then this becomes UNREACHABLE. |
1162 LoadRepresentation rep = LoadRepresentationOf(node->op()); | 1240 LoadRepresentation rep = LoadRepresentationOf(node->op()); |
1163 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer | 1241 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer |
1164 ProcessInput(node, 1, UseInfo::PointerInt()); // index | 1242 ProcessInput(node, 1, UseInfo::PointerInt()); // index |
1165 ProcessRemainingInputs(node, 2); | 1243 ProcessRemainingInputs(node, 2); |
1166 SetOutput(node, rep); | 1244 SetOutputFromMachineType(node, rep); |
1167 break; | 1245 break; |
1168 } | 1246 } |
1169 case IrOpcode::kStore: { | 1247 case IrOpcode::kStore: { |
1170 // TODO(jarin) Eventually, we should get rid of all machine stores | 1248 // TODO(jarin) Eventually, we should get rid of all machine stores |
1171 // from the high-level phases, then this becomes UNREACHABLE. | 1249 // from the high-level phases, then this becomes UNREACHABLE. |
1172 StoreRepresentation rep = StoreRepresentationOf(node->op()); | 1250 StoreRepresentation rep = StoreRepresentationOf(node->op()); |
1173 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer | 1251 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer |
1174 ProcessInput(node, 1, UseInfo::PointerInt()); // index | 1252 ProcessInput(node, 1, UseInfo::PointerInt()); // index |
1175 ProcessInput(node, 2, | 1253 ProcessInput(node, 2, |
1176 TruncatingUseInfoFromRepresentation(rep.representation())); | 1254 TruncatingUseInfoFromRepresentation(rep.representation())); |
1177 ProcessRemainingInputs(node, 3); | 1255 ProcessRemainingInputs(node, 3); |
1178 SetOutput(node, MachineType::None()); | 1256 SetOutput(node, NodeOutputInfo::None()); |
1179 break; | 1257 break; |
1180 } | 1258 } |
1181 case IrOpcode::kWord32Shr: | 1259 case IrOpcode::kWord32Shr: |
1182 // We output unsigned int32 for shift right because JavaScript. | 1260 // We output unsigned int32 for shift right because JavaScript. |
1183 return VisitBinop(node, UseInfo::TruncatingWord32(), | 1261 return VisitBinop(node, UseInfo::TruncatingWord32(), |
1184 MachineType::Uint32()); | 1262 NodeOutputInfo::Uint32()); |
1185 case IrOpcode::kWord32And: | 1263 case IrOpcode::kWord32And: |
1186 case IrOpcode::kWord32Or: | 1264 case IrOpcode::kWord32Or: |
1187 case IrOpcode::kWord32Xor: | 1265 case IrOpcode::kWord32Xor: |
1188 case IrOpcode::kWord32Shl: | 1266 case IrOpcode::kWord32Shl: |
1189 case IrOpcode::kWord32Sar: | 1267 case IrOpcode::kWord32Sar: |
1190 // We use signed int32 as the output type for these word32 operations, | 1268 // We use signed int32 as the output type for these word32 operations, |
1191 // though the machine bits are the same for either signed or unsigned, | 1269 // though the machine bits are the same for either signed or unsigned, |
1192 // because JavaScript considers the result from these operations signed. | 1270 // because JavaScript considers the result from these operations signed. |
1193 return VisitBinop(node, UseInfo::TruncatingWord32(), | 1271 return VisitBinop(node, UseInfo::TruncatingWord32(), |
1194 MachineType::Int32()); | 1272 NodeOutputInfo::Int32()); |
1195 case IrOpcode::kWord32Equal: | 1273 case IrOpcode::kWord32Equal: |
1196 return VisitBinop(node, UseInfo::TruncatingWord32(), | 1274 return VisitBinop(node, UseInfo::TruncatingWord32(), |
1197 MachineType::Bool()); | 1275 NodeOutputInfo::Bool()); |
1198 | 1276 |
1199 case IrOpcode::kWord32Clz: | 1277 case IrOpcode::kWord32Clz: |
1200 return VisitUnop(node, UseInfo::TruncatingWord32(), | 1278 return VisitUnop(node, UseInfo::TruncatingWord32(), |
1201 MachineType::Uint32()); | 1279 NodeOutputInfo::Uint32()); |
1202 | 1280 |
1203 case IrOpcode::kInt32Add: | 1281 case IrOpcode::kInt32Add: |
1204 case IrOpcode::kInt32Sub: | 1282 case IrOpcode::kInt32Sub: |
1205 case IrOpcode::kInt32Mul: | 1283 case IrOpcode::kInt32Mul: |
1206 case IrOpcode::kInt32MulHigh: | 1284 case IrOpcode::kInt32MulHigh: |
1207 case IrOpcode::kInt32Div: | 1285 case IrOpcode::kInt32Div: |
1208 case IrOpcode::kInt32Mod: | 1286 case IrOpcode::kInt32Mod: |
1209 return VisitInt32Binop(node); | 1287 return VisitInt32Binop(node); |
1210 case IrOpcode::kUint32Div: | 1288 case IrOpcode::kUint32Div: |
1211 case IrOpcode::kUint32Mod: | 1289 case IrOpcode::kUint32Mod: |
(...skipping 24 matching lines...) Expand all Loading... |
1236 case IrOpcode::kUint64Mod: | 1314 case IrOpcode::kUint64Mod: |
1237 return VisitUint64Binop(node); | 1315 return VisitUint64Binop(node); |
1238 | 1316 |
1239 case IrOpcode::kWord64And: | 1317 case IrOpcode::kWord64And: |
1240 case IrOpcode::kWord64Or: | 1318 case IrOpcode::kWord64Or: |
1241 case IrOpcode::kWord64Xor: | 1319 case IrOpcode::kWord64Xor: |
1242 case IrOpcode::kWord64Shl: | 1320 case IrOpcode::kWord64Shl: |
1243 case IrOpcode::kWord64Shr: | 1321 case IrOpcode::kWord64Shr: |
1244 case IrOpcode::kWord64Sar: | 1322 case IrOpcode::kWord64Sar: |
1245 return VisitBinop(node, UseInfo::TruncatingWord64(), | 1323 return VisitBinop(node, UseInfo::TruncatingWord64(), |
1246 MachineType(MachineRepresentation::kWord64, | 1324 NodeOutputInfo::Int64()); |
1247 MachineSemantic::kNone)); | |
1248 case IrOpcode::kWord64Equal: | 1325 case IrOpcode::kWord64Equal: |
1249 return VisitBinop(node, UseInfo::TruncatingWord64(), | 1326 return VisitBinop(node, UseInfo::TruncatingWord64(), |
1250 MachineType::Bool()); | 1327 NodeOutputInfo::Bool()); |
1251 | 1328 |
1252 case IrOpcode::kChangeInt32ToInt64: | 1329 case IrOpcode::kChangeInt32ToInt64: |
1253 return VisitUnop(node, UseInfo::TruncatingWord32(), | 1330 return VisitUnop( |
1254 MachineType(MachineRepresentation::kWord64, | 1331 node, UseInfo::TruncatingWord32(), |
1255 MachineSemantic::kInt32)); | 1332 NodeOutputInfo(MachineRepresentation::kWord64, Type::Signed32())); |
1256 case IrOpcode::kChangeUint32ToUint64: | 1333 case IrOpcode::kChangeUint32ToUint64: |
1257 return VisitUnop(node, UseInfo::TruncatingWord32(), | 1334 return VisitUnop( |
1258 MachineType(MachineRepresentation::kWord64, | 1335 node, UseInfo::TruncatingWord32(), |
1259 MachineSemantic::kUint32)); | 1336 NodeOutputInfo(MachineRepresentation::kWord64, Type::Unsigned32())); |
1260 case IrOpcode::kTruncateFloat64ToFloat32: | 1337 case IrOpcode::kTruncateFloat64ToFloat32: |
1261 return VisitUnop(node, UseInfo::Float64(), MachineType::Float32()); | 1338 return VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Float32()); |
1262 case IrOpcode::kTruncateFloat64ToInt32: | 1339 case IrOpcode::kTruncateFloat64ToInt32: |
1263 return VisitUnop(node, UseInfo::Float64(), MachineType::Int32()); | 1340 return VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Int32()); |
1264 case IrOpcode::kTruncateInt64ToInt32: | 1341 case IrOpcode::kTruncateInt64ToInt32: |
1265 // TODO(titzer): Is kTypeInt32 correct here? | 1342 // TODO(titzer): Is kTypeInt32 correct here? |
1266 return VisitUnop(node, UseInfo::Word64TruncatingToWord32(), | 1343 return VisitUnop(node, UseInfo::Word64TruncatingToWord32(), |
1267 MachineType::Int32()); | 1344 NodeOutputInfo::Int32()); |
1268 | 1345 |
1269 case IrOpcode::kChangeFloat32ToFloat64: | 1346 case IrOpcode::kChangeFloat32ToFloat64: |
1270 return VisitUnop(node, UseInfo::Float32(), MachineType::Float64()); | 1347 return VisitUnop(node, UseInfo::Float32(), NodeOutputInfo::Float64()); |
1271 case IrOpcode::kChangeInt32ToFloat64: | 1348 case IrOpcode::kChangeInt32ToFloat64: |
1272 return VisitUnop(node, UseInfo::TruncatingWord32(), | 1349 return VisitUnop( |
1273 MachineType(MachineRepresentation::kFloat64, | 1350 node, UseInfo::TruncatingWord32(), |
1274 MachineSemantic::kInt32)); | 1351 NodeOutputInfo(MachineRepresentation::kFloat64, Type::Signed32())); |
1275 case IrOpcode::kChangeUint32ToFloat64: | 1352 case IrOpcode::kChangeUint32ToFloat64: |
1276 return VisitUnop(node, UseInfo::TruncatingWord32(), | 1353 return VisitUnop(node, UseInfo::TruncatingWord32(), |
1277 MachineType(MachineRepresentation::kFloat64, | 1354 NodeOutputInfo(MachineRepresentation::kFloat64, |
1278 MachineSemantic::kUint32)); | 1355 Type::Unsigned32())); |
1279 case IrOpcode::kChangeFloat64ToInt32: | 1356 case IrOpcode::kChangeFloat64ToInt32: |
1280 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(), | 1357 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(), |
1281 MachineType::Int32()); | 1358 NodeOutputInfo::Int32()); |
1282 case IrOpcode::kChangeFloat64ToUint32: | 1359 case IrOpcode::kChangeFloat64ToUint32: |
1283 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(), | 1360 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(), |
1284 MachineType::Uint32()); | 1361 NodeOutputInfo::Uint32()); |
1285 | 1362 |
1286 case IrOpcode::kFloat64Add: | 1363 case IrOpcode::kFloat64Add: |
1287 case IrOpcode::kFloat64Sub: | 1364 case IrOpcode::kFloat64Sub: |
1288 case IrOpcode::kFloat64Mul: | 1365 case IrOpcode::kFloat64Mul: |
1289 case IrOpcode::kFloat64Div: | 1366 case IrOpcode::kFloat64Div: |
1290 case IrOpcode::kFloat64Mod: | 1367 case IrOpcode::kFloat64Mod: |
1291 case IrOpcode::kFloat64Min: | 1368 case IrOpcode::kFloat64Min: |
1292 return VisitFloat64Binop(node); | 1369 return VisitFloat64Binop(node); |
1293 case IrOpcode::kFloat64Abs: | 1370 case IrOpcode::kFloat64Abs: |
1294 case IrOpcode::kFloat64Sqrt: | 1371 case IrOpcode::kFloat64Sqrt: |
1295 case IrOpcode::kFloat64RoundDown: | 1372 case IrOpcode::kFloat64RoundDown: |
1296 case IrOpcode::kFloat64RoundTruncate: | 1373 case IrOpcode::kFloat64RoundTruncate: |
1297 case IrOpcode::kFloat64RoundTiesAway: | 1374 case IrOpcode::kFloat64RoundTiesAway: |
1298 return VisitUnop(node, UseInfo::Float64(), MachineType::Float64()); | 1375 return VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Float64()); |
1299 case IrOpcode::kFloat64Equal: | 1376 case IrOpcode::kFloat64Equal: |
1300 case IrOpcode::kFloat64LessThan: | 1377 case IrOpcode::kFloat64LessThan: |
1301 case IrOpcode::kFloat64LessThanOrEqual: | 1378 case IrOpcode::kFloat64LessThanOrEqual: |
1302 return VisitFloat64Cmp(node); | 1379 return VisitFloat64Cmp(node); |
1303 case IrOpcode::kFloat64ExtractLowWord32: | 1380 case IrOpcode::kFloat64ExtractLowWord32: |
1304 case IrOpcode::kFloat64ExtractHighWord32: | 1381 case IrOpcode::kFloat64ExtractHighWord32: |
1305 return VisitUnop(node, UseInfo::Float64(), MachineType::Int32()); | 1382 return VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Int32()); |
1306 case IrOpcode::kFloat64InsertLowWord32: | 1383 case IrOpcode::kFloat64InsertLowWord32: |
1307 case IrOpcode::kFloat64InsertHighWord32: | 1384 case IrOpcode::kFloat64InsertHighWord32: |
1308 return VisitBinop(node, UseInfo::Float64(), UseInfo::TruncatingWord32(), | 1385 return VisitBinop(node, UseInfo::Float64(), UseInfo::TruncatingWord32(), |
1309 MachineType::Float64()); | 1386 NodeOutputInfo::Float64()); |
1310 case IrOpcode::kLoadStackPointer: | 1387 case IrOpcode::kLoadStackPointer: |
1311 case IrOpcode::kLoadFramePointer: | 1388 case IrOpcode::kLoadFramePointer: |
1312 return VisitLeaf(node, MachineType::Pointer()); | 1389 return VisitLeaf(node, NodeOutputInfo::Pointer()); |
1313 case IrOpcode::kStateValues: | 1390 case IrOpcode::kStateValues: |
1314 VisitStateValues(node); | 1391 VisitStateValues(node); |
1315 break; | 1392 break; |
1316 default: | 1393 default: |
1317 VisitInputs(node); | 1394 VisitInputs(node); |
1318 // Assume the output is tagged. | 1395 // Assume the output is tagged. |
1319 SetOutput(node, MachineType::AnyTagged()); | 1396 SetOutput(node, NodeOutputInfo::AnyTagged()); |
1320 break; | 1397 break; |
1321 } | 1398 } |
1322 } | 1399 } |
1323 | 1400 |
1324 void DeferReplacement(Node* node, Node* replacement) { | 1401 void DeferReplacement(Node* node, Node* replacement) { |
1325 TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(), | 1402 TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(), |
1326 node->op()->mnemonic(), replacement->id(), | 1403 node->op()->mnemonic(), replacement->id(), |
1327 replacement->op()->mnemonic()); | 1404 replacement->op()->mnemonic()); |
1328 | 1405 |
1329 if (replacement->id() < count_ && | 1406 if (replacement->id() < count_ && |
1330 GetInfo(replacement)->output_type() == GetInfo(node)->output_type()) { | 1407 GetInfo(replacement)->output_type() == GetInfo(node)->output_type()) { |
1331 // Replace with a previously existing node eagerly only if the type is the | 1408 // Replace with a previously existing node eagerly only if the type is the |
1332 // same. | 1409 // same. |
1333 node->ReplaceUses(replacement); | 1410 node->ReplaceUses(replacement); |
1334 } else { | 1411 } else { |
1335 // Otherwise, we are replacing a node with a representation change. | 1412 // Otherwise, we are replacing a node with a representation change. |
1336 // Such a substitution must be done after all lowering is done, because | 1413 // Such a substitution must be done after all lowering is done, because |
1337 // changing the type could confuse the representation change | 1414 // changing the type could confuse the representation change |
1338 // insertion for uses of the node. | 1415 // insertion for uses of the node. |
1339 replacements_.push_back(node); | 1416 replacements_.push_back(node); |
1340 replacements_.push_back(replacement); | 1417 replacements_.push_back(replacement); |
1341 } | 1418 } |
1342 node->NullAllInputs(); // Node is now dead. | 1419 node->NullAllInputs(); // Node is now dead. |
1343 } | 1420 } |
1344 | 1421 |
1345 void PrintInfo(MachineType info) { | 1422 void PrintOutputInfo(NodeInfo* info) { |
1346 if (FLAG_trace_representation) { | 1423 if (FLAG_trace_representation) { |
1347 OFStream os(stdout); | 1424 OFStream os(stdout); |
1348 os << info; | 1425 os << info->representation() << " ("; |
| 1426 info->output_type()->PrintTo(os, Type::SEMANTIC_DIM); |
| 1427 os << ")"; |
1349 } | 1428 } |
1350 } | 1429 } |
1351 | 1430 |
| 1431 void PrintRepresentation(MachineRepresentation rep) { |
| 1432 if (FLAG_trace_representation) { |
| 1433 OFStream os(stdout); |
| 1434 os << rep; |
| 1435 } |
| 1436 } |
| 1437 |
1352 void PrintTruncation(Truncation truncation) { | 1438 void PrintTruncation(Truncation truncation) { |
1353 if (FLAG_trace_representation) { | 1439 if (FLAG_trace_representation) { |
1354 OFStream os(stdout); | 1440 OFStream os(stdout); |
1355 os << truncation.description(); | 1441 os << truncation.description(); |
1356 } | 1442 } |
1357 } | 1443 } |
1358 | 1444 |
1359 void PrintUseInfo(UseInfo info) { | 1445 void PrintUseInfo(UseInfo info) { |
1360 if (FLAG_trace_representation) { | 1446 if (FLAG_trace_representation) { |
1361 OFStream os(stdout); | 1447 OFStream os(stdout); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1401 | 1487 |
1402 | 1488 |
1403 void SimplifiedLowering::LowerAllNodes() { | 1489 void SimplifiedLowering::LowerAllNodes() { |
1404 RepresentationChanger changer(jsgraph(), jsgraph()->isolate()); | 1490 RepresentationChanger changer(jsgraph(), jsgraph()->isolate()); |
1405 RepresentationSelector selector(jsgraph(), zone_, &changer, | 1491 RepresentationSelector selector(jsgraph(), zone_, &changer, |
1406 source_positions_); | 1492 source_positions_); |
1407 selector.Run(this); | 1493 selector.Run(this); |
1408 } | 1494 } |
1409 | 1495 |
1410 | 1496 |
1411 void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type, | 1497 void SimplifiedLowering::DoLoadBuffer(Node* node, |
| 1498 MachineRepresentation output_rep, |
1412 RepresentationChanger* changer) { | 1499 RepresentationChanger* changer) { |
1413 DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode()); | 1500 DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode()); |
1414 DCHECK_NE(MachineRepresentation::kNone, output_type.representation()); | 1501 DCHECK_NE(MachineRepresentation::kNone, output_rep); |
1415 MachineType const type = BufferAccessOf(node->op()).machine_type(); | 1502 MachineType const access_type = BufferAccessOf(node->op()).machine_type(); |
1416 if (output_type != type) { | 1503 if (output_rep != access_type.representation()) { |
1417 Node* const buffer = node->InputAt(0); | 1504 Node* const buffer = node->InputAt(0); |
1418 Node* const offset = node->InputAt(1); | 1505 Node* const offset = node->InputAt(1); |
1419 Node* const length = node->InputAt(2); | 1506 Node* const length = node->InputAt(2); |
1420 Node* const effect = node->InputAt(3); | 1507 Node* const effect = node->InputAt(3); |
1421 Node* const control = node->InputAt(4); | 1508 Node* const control = node->InputAt(4); |
1422 Node* const index = | 1509 Node* const index = |
1423 machine()->Is64() | 1510 machine()->Is64() |
1424 ? graph()->NewNode(machine()->ChangeUint32ToUint64(), offset) | 1511 ? graph()->NewNode(machine()->ChangeUint32ToUint64(), offset) |
1425 : offset; | 1512 : offset; |
1426 | 1513 |
1427 Node* check = graph()->NewNode(machine()->Uint32LessThan(), offset, length); | 1514 Node* check = graph()->NewNode(machine()->Uint32LessThan(), offset, length); |
1428 Node* branch = | 1515 Node* branch = |
1429 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | 1516 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
1430 | 1517 |
1431 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 1518 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
1432 Node* etrue = | 1519 Node* etrue = graph()->NewNode(machine()->Load(access_type), buffer, index, |
1433 graph()->NewNode(machine()->Load(type), buffer, index, effect, if_true); | 1520 effect, if_true); |
1434 Node* vtrue = changer->GetRepresentationFor( | 1521 Node* vtrue = changer->GetRepresentationFor( |
1435 etrue, type, output_type.representation(), Truncation::None()); | 1522 etrue, access_type.representation(), NodeProperties::GetType(node), |
| 1523 output_rep, Truncation::None()); |
1436 | 1524 |
1437 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | 1525 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
1438 Node* efalse = effect; | 1526 Node* efalse = effect; |
1439 Node* vfalse; | 1527 Node* vfalse; |
1440 if (output_type.representation() == MachineRepresentation::kTagged) { | 1528 if (output_rep == MachineRepresentation::kTagged) { |
1441 vfalse = jsgraph()->UndefinedConstant(); | 1529 vfalse = jsgraph()->UndefinedConstant(); |
1442 } else if (output_type.representation() == | 1530 } else if (output_rep == MachineRepresentation::kFloat64) { |
1443 MachineRepresentation::kFloat64) { | |
1444 vfalse = | 1531 vfalse = |
1445 jsgraph()->Float64Constant(std::numeric_limits<double>::quiet_NaN()); | 1532 jsgraph()->Float64Constant(std::numeric_limits<double>::quiet_NaN()); |
1446 } else if (output_type.representation() == | 1533 } else if (output_rep == MachineRepresentation::kFloat32) { |
1447 MachineRepresentation::kFloat32) { | |
1448 vfalse = | 1534 vfalse = |
1449 jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN()); | 1535 jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN()); |
1450 } else { | 1536 } else { |
1451 vfalse = jsgraph()->Int32Constant(0); | 1537 vfalse = jsgraph()->Int32Constant(0); |
1452 } | 1538 } |
1453 | 1539 |
1454 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); | 1540 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); |
1455 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge); | 1541 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge); |
1456 | 1542 |
1457 // Replace effect uses of {node} with the {ephi}. | 1543 // Replace effect uses of {node} with the {ephi}. |
1458 NodeProperties::ReplaceUses(node, node, ephi); | 1544 NodeProperties::ReplaceUses(node, node, ephi); |
1459 | 1545 |
1460 // Turn the {node} into a Phi. | 1546 // Turn the {node} into a Phi. |
1461 node->ReplaceInput(0, vtrue); | 1547 node->ReplaceInput(0, vtrue); |
1462 node->ReplaceInput(1, vfalse); | 1548 node->ReplaceInput(1, vfalse); |
1463 node->ReplaceInput(2, merge); | 1549 node->ReplaceInput(2, merge); |
1464 node->TrimInputCount(3); | 1550 node->TrimInputCount(3); |
1465 NodeProperties::ChangeOp(node, | 1551 NodeProperties::ChangeOp(node, common()->Phi(output_rep, 2)); |
1466 common()->Phi(output_type.representation(), 2)); | |
1467 } else { | 1552 } else { |
1468 NodeProperties::ChangeOp(node, machine()->CheckedLoad(type)); | 1553 NodeProperties::ChangeOp(node, machine()->CheckedLoad(access_type)); |
1469 } | 1554 } |
1470 } | 1555 } |
1471 | 1556 |
1472 | 1557 |
1473 void SimplifiedLowering::DoStoreBuffer(Node* node) { | 1558 void SimplifiedLowering::DoStoreBuffer(Node* node) { |
1474 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode()); | 1559 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode()); |
1475 MachineRepresentation const rep = | 1560 MachineRepresentation const rep = |
1476 BufferAccessOf(node->op()).machine_type().representation(); | 1561 BufferAccessOf(node->op()).machine_type().representation(); |
1477 NodeProperties::ChangeOp(node, machine()->CheckedStore(rep)); | 1562 NodeProperties::ChangeOp(node, machine()->CheckedStore(rep)); |
1478 } | 1563 } |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1834 ReplaceEffectUses(node, comparison); | 1919 ReplaceEffectUses(node, comparison); |
1835 node->ReplaceInput(0, comparison); | 1920 node->ReplaceInput(0, comparison); |
1836 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1921 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
1837 node->TrimInputCount(2); | 1922 node->TrimInputCount(2); |
1838 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); | 1923 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); |
1839 } | 1924 } |
1840 | 1925 |
1841 } // namespace compiler | 1926 } // namespace compiler |
1842 } // namespace internal | 1927 } // namespace internal |
1843 } // namespace v8 | 1928 } // namespace v8 |
OLD | NEW |