Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: src/compiler/simplified-lowering.cc

Issue 1571263004: [turbofan] Replace MachineSemantic with Type in simplified lowering. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rename upper -> type Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | test/cctest/compiler/test-representation-change.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | test/cctest/compiler/test-representation-change.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698