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

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

Issue 1921563002: [turbofan] Initial version of number type feedback. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 6 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') | src/compiler/simplified-operator.h » ('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/address-map.h" 9 #include "src/address-map.h"
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
11 #include "src/code-factory.h" 11 #include "src/code-factory.h"
12 #include "src/compiler/access-builder.h" 12 #include "src/compiler/access-builder.h"
13 #include "src/compiler/common-operator.h" 13 #include "src/compiler/common-operator.h"
14 #include "src/compiler/diamond.h" 14 #include "src/compiler/diamond.h"
15 #include "src/compiler/linkage.h" 15 #include "src/compiler/linkage.h"
16 #include "src/compiler/node-matchers.h" 16 #include "src/compiler/node-matchers.h"
17 #include "src/compiler/node-properties.h" 17 #include "src/compiler/node-properties.h"
18 #include "src/compiler/operation-typer.h"
18 #include "src/compiler/operator-properties.h" 19 #include "src/compiler/operator-properties.h"
19 #include "src/compiler/representation-change.h" 20 #include "src/compiler/representation-change.h"
20 #include "src/compiler/simplified-operator.h" 21 #include "src/compiler/simplified-operator.h"
21 #include "src/compiler/source-position.h" 22 #include "src/compiler/source-position.h"
22 #include "src/conversions-inl.h" 23 #include "src/conversions-inl.h"
23 #include "src/objects.h" 24 #include "src/objects.h"
24 #include "src/type-cache.h" 25 #include "src/type-cache.h"
25 26
26 namespace v8 { 27 namespace v8 {
27 namespace internal { 28 namespace internal {
(...skipping 27 matching lines...) Expand all
55 // removing some (redundant) nodes. 56 // removing some (redundant) nodes.
56 // During this phase, use the {RepresentationChanger} to insert 57 // During this phase, use the {RepresentationChanger} to insert
57 // representation changes between uses that demand a particular 58 // representation changes between uses that demand a particular
58 // representation and nodes that produce a different representation. 59 // representation and nodes that produce a different representation.
59 LOWER 60 LOWER
60 }; 61 };
61 62
62 63
63 namespace { 64 namespace {
64 65
65 // The {UseInfo} class is used to describe a use of an input of a node.
66 //
67 // This information is used in two different ways, based on the phase:
68 //
69 // 1. During propagation, the use info is used to inform the input node
70 // about what part of the input is used (we call this truncation) and what
71 // is the preferred representation.
72 //
73 // 2. During lowering, the use info is used to properly convert the input
74 // to the preferred representation. The preferred representation might be
75 // insufficient to do the conversion (e.g. word32->float64 conv), so we also
76 // need the signedness information to produce the correct value.
77 class UseInfo {
78 public:
79 UseInfo(MachineRepresentation preferred, Truncation truncation)
80 : preferred_(preferred), truncation_(truncation) {}
81 static UseInfo TruncatingWord32() {
82 return UseInfo(MachineRepresentation::kWord32, Truncation::Word32());
83 }
84 static UseInfo TruncatingWord64() {
85 return UseInfo(MachineRepresentation::kWord64, Truncation::Word64());
86 }
87 static UseInfo Bool() {
88 return UseInfo(MachineRepresentation::kBit, Truncation::Bool());
89 }
90 static UseInfo TruncatingFloat32() {
91 return UseInfo(MachineRepresentation::kFloat32, Truncation::Float32());
92 }
93 static UseInfo TruncatingFloat64() {
94 return UseInfo(MachineRepresentation::kFloat64, Truncation::Float64());
95 }
96 static UseInfo PointerInt() {
97 return kPointerSize == 4 ? TruncatingWord32() : TruncatingWord64();
98 }
99 static UseInfo AnyTagged() {
100 return UseInfo(MachineRepresentation::kTagged, Truncation::Any());
101 }
102
103 // Undetermined representation.
104 static UseInfo Any() {
105 return UseInfo(MachineRepresentation::kNone, Truncation::Any());
106 }
107 static UseInfo None() {
108 return UseInfo(MachineRepresentation::kNone, Truncation::None());
109 }
110 static UseInfo AnyTruncatingToBool() {
111 return UseInfo(MachineRepresentation::kNone, Truncation::Bool());
112 }
113
114 MachineRepresentation preferred() const { return preferred_; }
115 Truncation truncation() const { return truncation_; }
116
117 private:
118 MachineRepresentation preferred_;
119 Truncation truncation_;
120 };
121
122 66
123 UseInfo TruncatingUseInfoFromRepresentation(MachineRepresentation rep) { 67 UseInfo TruncatingUseInfoFromRepresentation(MachineRepresentation rep) {
124 switch (rep) { 68 switch (rep) {
125 case MachineRepresentation::kTagged: 69 case MachineRepresentation::kTagged:
126 return UseInfo::AnyTagged(); 70 return UseInfo::AnyTagged();
127 case MachineRepresentation::kFloat64: 71 case MachineRepresentation::kFloat64:
128 return UseInfo::TruncatingFloat64(); 72 return UseInfo::TruncatingFloat64();
129 case MachineRepresentation::kFloat32: 73 case MachineRepresentation::kFloat32:
130 return UseInfo::TruncatingFloat32(); 74 return UseInfo::TruncatingFloat32();
131 case MachineRepresentation::kWord64: 75 case MachineRepresentation::kWord64:
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 // Check that the new use informatin is a super-type of the old 160 // Check that the new use informatin is a super-type of the old
217 // one. 161 // one.
218 CHECK(IsUseLessGeneral(input_use_infos_[index], use_info)); 162 CHECK(IsUseLessGeneral(input_use_infos_[index], use_info));
219 input_use_infos_[index] = use_info; 163 input_use_infos_[index] = use_info;
220 } 164 }
221 165
222 private: 166 private:
223 ZoneVector<UseInfo> input_use_infos_; 167 ZoneVector<UseInfo> input_use_infos_;
224 168
225 static bool IsUseLessGeneral(UseInfo use1, UseInfo use2) { 169 static bool IsUseLessGeneral(UseInfo use1, UseInfo use2) {
226 return MachineRepresentationIsSubtype(use1.preferred(), use2.preferred()) && 170 return MachineRepresentationIsSubtype(use1.representation(),
171 use2.representation()) &&
227 use1.truncation().IsLessGeneralThan(use2.truncation()); 172 use1.truncation().IsLessGeneralThan(use2.truncation());
228 } 173 }
229 }; 174 };
230 175
231 #endif // DEBUG 176 #endif // DEBUG
232 177
233 } // namespace 178 } // namespace
234 179
235 180
236 class RepresentationSelector { 181 class RepresentationSelector {
237 public: 182 public:
238 // Information for each node tracked during the fixpoint. 183 // Information for each node tracked during the fixpoint.
239 class NodeInfo { 184 class NodeInfo {
240 public: 185 public:
241 // Adds new use to the node. Returns true if something has changed 186 // Adds new use to the node. Returns true if something has changed
242 // and the node has to be requeued. 187 // and the node has to be requeued.
243 bool AddUse(UseInfo info) { 188 bool AddUse(UseInfo info) {
244 Truncation old_truncation = truncation_; 189 Truncation old_truncation = truncation_;
245 truncation_ = Truncation::Generalize(truncation_, info.truncation()); 190 truncation_ = Truncation::Generalize(truncation_, info.truncation());
246 return truncation_ != old_truncation; 191 return truncation_ != old_truncation;
247 } 192 }
248 193
249 void set_queued(bool value) { queued_ = value; } 194 void set_queued() { state_ = kQueued; }
250 bool queued() const { return queued_; } 195 void set_visited() { state_ = kVisited; }
251 void set_visited() { visited_ = true; } 196 void set_pushed() { state_ = kPushed; }
252 bool visited() const { return visited_; } 197 void reset_state() { state_ = kUnvisited; }
198 bool visited() const { return state_ == kVisited; }
199 bool queued() const { return state_ == kQueued; }
200 bool unvisited() const { return state_ == kUnvisited; }
253 Truncation truncation() const { return truncation_; } 201 Truncation truncation() const { return truncation_; }
254 void set_output(MachineRepresentation output) { representation_ = output; } 202 void set_output(MachineRepresentation output) { representation_ = output; }
255 203
256 MachineRepresentation representation() const { return representation_; } 204 MachineRepresentation representation() const { return representation_; }
257 205
206 // Helpers for feedback typing.
207 void set_feedback_type(Type* type) { feedback_type_ = type; }
208 Type* feedback_type() { return feedback_type_; }
209 void set_weakened() { weakened_ = true; }
210 bool weakened() { return weakened_; }
211 TypeCheckKind type_check() { return type_check_; }
212 void set_type_check(TypeCheckKind type_check) { type_check_ = type_check; }
213
258 private: 214 private:
259 bool queued_ = false; // Bookkeeping for the traversal. 215 enum State : uint8_t { kUnvisited, kPushed, kVisited, kQueued };
260 bool visited_ = false; // Bookkeeping for the traversal. 216 State state_ = kUnvisited;
261 MachineRepresentation representation_ = 217 MachineRepresentation representation_ =
262 MachineRepresentation::kNone; // Output representation. 218 MachineRepresentation::kNone; // Output representation.
263 Truncation truncation_ = Truncation::None(); // Information about uses. 219 Truncation truncation_ = Truncation::None(); // Information about uses.
220 TypeCheckKind type_check_ = TypeCheckKind::kNone; // Runtime check kind.
221
222 Type* feedback_type_ = nullptr;
223 bool weakened_ = false;
264 }; 224 };
265 225
266 RepresentationSelector(JSGraph* jsgraph, Zone* zone, 226 RepresentationSelector(JSGraph* jsgraph, Zone* zone,
267 RepresentationChanger* changer, 227 RepresentationChanger* changer,
268 SourcePositionTable* source_positions) 228 SourcePositionTable* source_positions)
269 : jsgraph_(jsgraph), 229 : jsgraph_(jsgraph),
230 zone_(zone),
270 count_(jsgraph->graph()->NodeCount()), 231 count_(jsgraph->graph()->NodeCount()),
271 info_(count_, zone), 232 info_(count_, zone),
272 #ifdef DEBUG 233 #ifdef DEBUG
273 node_input_use_infos_(count_, InputUseInfos(zone), zone), 234 node_input_use_infos_(count_, InputUseInfos(zone), zone),
274 #endif 235 #endif
275 nodes_(zone), 236 nodes_(zone),
276 replacements_(zone), 237 replacements_(zone),
277 phase_(PROPAGATE), 238 phase_(PROPAGATE),
278 changer_(changer), 239 changer_(changer),
279 queue_(zone), 240 queue_(zone),
241 typing_stack_(zone),
280 source_positions_(source_positions), 242 source_positions_(source_positions),
281 type_cache_(TypeCache::Get()) { 243 type_cache_(TypeCache::Get()),
282 } 244 op_typer_(jsgraph->isolate(), graph_zone()) {
283 245 }
284 void Run(SimplifiedLowering* lowering) { 246
247 // Forward propagation of types from type feedback.
248 void RunTypePropagationPhase() {
249 DCHECK(typing_stack_.empty());
250
251 typing_stack_.push({graph()->end(), 0});
252 GetInfo(graph()->end())->set_pushed();
253 while (!typing_stack_.empty()) {
254 NodeState& current = typing_stack_.top();
255
256 // If there is an unvisited input, push it and continue.
257 bool pushed_unvisited = false;
258 while (current.input_index < current.node->InputCount()) {
259 Node* input = current.node->InputAt(current.input_index);
260 NodeInfo* input_info = GetInfo(input);
261 current.input_index++;
262 if (input_info->unvisited()) {
263 input_info->set_pushed();
264 typing_stack_.push({input, 0});
265 pushed_unvisited = true;
266 break;
267 }
268 }
269 if (pushed_unvisited) continue;
270
271 // Process the top of the stack.
272 Node* node = current.node;
273 typing_stack_.pop();
274 NodeInfo* info = GetInfo(node);
275 info->set_visited();
276 bool updated = UpdateFeedbackType(node);
277 if (updated) {
278 for (Node* const user : node->uses()) {
279 if (GetInfo(user)->visited()) {
280 GetInfo(user)->set_queued();
281 queue_.push(user);
282 }
283 }
284 }
285 }
286
287 // Process the revisit queue.
288 while (!queue_.empty()) {
289 Node* node = queue_.front();
290 queue_.pop();
291 NodeInfo* info = GetInfo(node);
292 info->set_visited();
293 bool updated = UpdateFeedbackType(node);
294 if (updated) {
295 for (Node* const user : node->uses()) {
296 if (GetInfo(user)->visited()) {
297 GetInfo(user)->set_queued();
298 queue_.push(user);
299 }
300 }
301 }
302 }
303 }
304
305 void ResetNodeInfoState() {
306 // Clean up for the next phase.
307 for (NodeInfo& info : info_) {
308 info.reset_state();
309 }
310 }
311
312 Type* TypeOf(Node* node) {
313 Type* type = GetInfo(node)->feedback_type();
314 return type == nullptr ? NodeProperties::GetType(node) : type;
315 }
316
317 Type* FeedbackTypeOf(Node* node) {
318 Type* type = GetInfo(node)->feedback_type();
319 return type == nullptr ? Type::None() : type;
320 }
321
322 Type* TypePhi(Node* node) {
323 int arity = node->op()->ValueInputCount();
324 Type* type = FeedbackTypeOf(node->InputAt(0));
325 for (int i = 1; i < arity; ++i) {
326 type = op_typer_.Merge(type, FeedbackTypeOf(node->InputAt(i)));
327 }
328 return type;
329 }
330
331 Type* TypeSelect(Node* node) {
332 return op_typer_.Merge(FeedbackTypeOf(node->InputAt(1)),
333 FeedbackTypeOf(node->InputAt(2)));
334 }
335
336 static Type* TypeOfSpeculativeOp(TypeCheckKind type_check) {
337 switch (type_check) {
338 case TypeCheckKind::kNone:
339 return Type::Any();
340 case TypeCheckKind::kSigned32:
341 return Type::Signed32();
342 case TypeCheckKind::kNumber:
343 return Type::Number();
344 // Unexpected cases.
345 case TypeCheckKind::kNumberOrUndefined:
346 FATAL("Unexpected checked type.");
347 break;
348 }
349 UNREACHABLE();
350 return nullptr;
351 }
352
353 bool UpdateFeedbackType(Node* node) {
354 if (node->op()->ValueOutputCount() == 0) return false;
355
356 NodeInfo* info = GetInfo(node);
357 Type* type = info->feedback_type();
358 Type* new_type = type;
359
360 switch (node->opcode()) {
361 case IrOpcode::kSpeculativeNumberAdd: {
362 Type* lhs = FeedbackTypeOf(node->InputAt(0));
363 Type* rhs = FeedbackTypeOf(node->InputAt(1));
364 if (lhs->Is(Type::None()) || rhs->Is(Type::None())) return false;
365 // TODO(jarin) The ToNumber conversion is too conservative here,
366 // e.g. it will treat true as 1 even though the number check will
367 // fail on a boolean. OperationTyper should have a function that
368 // computes a more precise type.
369 lhs = op_typer_.ToNumber(lhs);
370 rhs = op_typer_.ToNumber(rhs);
371 Type* static_type = op_typer_.NumericAdd(lhs, rhs);
372 if (info->type_check() == TypeCheckKind::kNone) {
373 new_type = static_type;
374 } else {
375 Type* feedback_type = TypeOfSpeculativeOp(info->type_check());
376 new_type = Type::Intersect(static_type, feedback_type, graph_zone());
377 }
378 break;
379 }
380
381 case IrOpcode::kSpeculativeNumberSubtract: {
382 Type* lhs = FeedbackTypeOf(node->InputAt(0));
383 Type* rhs = FeedbackTypeOf(node->InputAt(1));
384 if (lhs->Is(Type::None()) || rhs->Is(Type::None())) return false;
385 // TODO(jarin) The ToNumber conversion is too conservative here,
386 // e.g. it will treat true as 1 even though the number check will
387 // fail on a boolean. OperationTyper should have a function that
388 // computes a more precise type.
389 lhs = op_typer_.ToNumber(lhs);
390 rhs = op_typer_.ToNumber(rhs);
391 Type* static_type = op_typer_.NumericSubtract(lhs, rhs);
392 if (info->type_check() == TypeCheckKind::kNone) {
393 new_type = static_type;
394 } else {
395 Type* feedback_type = TypeOfSpeculativeOp(info->type_check());
396 new_type = Type::Intersect(static_type, feedback_type, graph_zone());
397 }
398 break;
399 }
400
401 case IrOpcode::kPhi: {
402 new_type = TypePhi(node);
403 if (type != nullptr) {
404 new_type = Weaken(node, type, new_type);
405 }
406 // Recompute the phi representation based on the new type.
407 MachineRepresentation output =
408 GetOutputInfoForPhi(node, GetInfo(node)->truncation(), new_type);
409 ResetOutput(node, output);
410 break;
411 }
412
413 case IrOpcode::kSelect: {
414 new_type = TypeSelect(node);
415 // Recompute representation based on the new type.
416 MachineRepresentation output =
417 GetOutputInfoForPhi(node, GetInfo(node)->truncation(), new_type);
418 ResetOutput(node, output);
419 break;
420 }
421
422 default:
423 // Shortcut for operations that we do not handle.
424 if (type == nullptr) {
425 GetInfo(node)->set_feedback_type(NodeProperties::GetType(node));
426 return true;
427 }
428 return false;
429 }
430 if (type != nullptr && new_type->Is(type)) return false;
431 GetInfo(node)->set_feedback_type(new_type);
432 if (FLAG_trace_representation) {
433 PrintNodeFeedbackType(node);
434 }
435 return true;
436 }
437
438 void PrintNodeFeedbackType(Node* n) {
439 OFStream os(stdout);
440 os << "#" << n->id() << ":" << *n->op() << "(";
441 int j = 0;
442 for (Node* const i : n->inputs()) {
443 if (j++ > 0) os << ", ";
444 os << "#" << i->id() << ":" << i->op()->mnemonic();
445 }
446 os << ")";
447 if (NodeProperties::IsTyped(n)) {
448 os << " [Static type: ";
449 Type* static_type = NodeProperties::GetType(n);
450 static_type->PrintTo(os);
451 Type* feedback_type = GetInfo(n)->feedback_type();
452 if (feedback_type != nullptr && feedback_type != static_type) {
453 os << ", Feedback type: ";
454 feedback_type->PrintTo(os);
455 }
456 os << "]";
457 }
458 os << std::endl;
459 }
460
461 Type* Weaken(Node* node, Type* previous_type, Type* current_type) {
462 // If the types have nothing to do with integers, return the types.
463 Type* const integer = type_cache_.kInteger;
464 if (!previous_type->Maybe(integer)) {
465 return current_type;
466 }
467 DCHECK(current_type->Maybe(integer));
468
469 Type* current_integer =
470 Type::Intersect(current_type, integer, graph_zone());
471 Type* previous_integer =
472 Type::Intersect(previous_type, integer, graph_zone());
473
474 // Once we start weakening a node, we should always weaken.
475 if (!GetInfo(node)->weakened()) {
476 // Only weaken if there is range involved; we should converge quickly
477 // for all other types (the exception is a union of many constants,
478 // but we currently do not increase the number of constants in unions).
479 Type* previous = previous_integer->GetRange();
480 Type* current = current_integer->GetRange();
481 if (current == nullptr || previous == nullptr) {
482 return current_type;
483 }
484 // Range is involved => we are weakening.
485 GetInfo(node)->set_weakened();
486 }
487
488 return Type::Union(current_type,
489 op_typer_.WeakenRange(previous_integer, current_integer),
490 graph_zone());
491 }
492
493 // Backward propagation of truncations.
494 void RunTruncationPropagationPhase() {
285 // Run propagation phase to a fixpoint. 495 // Run propagation phase to a fixpoint.
286 TRACE("--{Propagation phase}--\n"); 496 TRACE("--{Propagation phase}--\n");
287 phase_ = PROPAGATE; 497 phase_ = PROPAGATE;
288 EnqueueInitial(jsgraph_->graph()->end()); 498 EnqueueInitial(jsgraph_->graph()->end());
289 // Process nodes from the queue until it is empty. 499 // Process nodes from the queue until it is empty.
290 while (!queue_.empty()) { 500 while (!queue_.empty()) {
291 Node* node = queue_.front(); 501 Node* node = queue_.front();
292 NodeInfo* info = GetInfo(node); 502 NodeInfo* info = GetInfo(node);
293 queue_.pop(); 503 queue_.pop();
294 info->set_queued(false); 504 info->set_visited();
295 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic()); 505 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
296 VisitNode(node, info->truncation(), nullptr); 506 VisitNode(node, info->truncation(), nullptr);
297 TRACE(" ==> output "); 507 TRACE(" ==> output ");
298 PrintOutputInfo(info); 508 PrintOutputInfo(info);
299 TRACE("\n"); 509 TRACE("\n");
300 } 510 }
511 }
512
513 void Run(SimplifiedLowering* lowering) {
514 RunTruncationPropagationPhase();
515
516 if (lowering->flags() & SimplifiedLowering::kTypeFeedbackEnabled) {
517 ResetNodeInfoState();
518 RunTypePropagationPhase();
519 }
301 520
302 // Run lowering and change insertion phase. 521 // Run lowering and change insertion phase.
303 TRACE("--{Simplified lowering phase}--\n"); 522 TRACE("--{Simplified lowering phase}--\n");
304 phase_ = LOWER; 523 phase_ = LOWER;
305 // Process nodes from the collected {nodes_} vector. 524 // Process nodes from the collected {nodes_} vector.
306 for (NodeVector::iterator i = nodes_.begin(); i != nodes_.end(); ++i) { 525 for (NodeVector::iterator i = nodes_.begin(); i != nodes_.end(); ++i) {
307 Node* node = *i; 526 Node* node = *i;
308 NodeInfo* info = GetInfo(node); 527 NodeInfo* info = GetInfo(node);
309 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic()); 528 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
310 // Reuse {VisitNode()} so the representation rules are in one place. 529 // Reuse {VisitNode()} so the representation rules are in one place.
311 SourcePositionTable::Scope scope( 530 SourcePositionTable::Scope scope(
312 source_positions_, source_positions_->GetSourcePosition(node)); 531 source_positions_, source_positions_->GetSourcePosition(node));
313 VisitNode(node, info->truncation(), lowering); 532 VisitNode(node, info->truncation(), lowering);
314 } 533 }
315 534
316 // Perform the final replacements. 535 // Perform the final replacements.
317 for (NodeVector::iterator i = replacements_.begin(); 536 for (NodeVector::iterator i = replacements_.begin();
318 i != replacements_.end(); ++i) { 537 i != replacements_.end(); ++i) {
319 Node* node = *i; 538 Node* node = *i;
320 Node* replacement = *(++i); 539 Node* replacement = *(++i);
321 node->ReplaceUses(replacement); 540 node->ReplaceUses(replacement);
541 node->Kill();
322 // We also need to replace the node in the rest of the vector. 542 // We also need to replace the node in the rest of the vector.
323 for (NodeVector::iterator j = i + 1; j != replacements_.end(); ++j) { 543 for (NodeVector::iterator j = i + 1; j != replacements_.end(); ++j) {
324 ++j; 544 ++j;
325 if (*j == node) *j = replacement; 545 if (*j == node) *j = replacement;
326 } 546 }
327 } 547 }
328 } 548 }
329 549
330 void EnqueueInitial(Node* node) { 550 void EnqueueInitial(Node* node) {
331 NodeInfo* info = GetInfo(node); 551 NodeInfo* info = GetInfo(node);
332 info->set_visited(); 552 info->set_queued();
333 info->set_queued(true);
334 nodes_.push_back(node); 553 nodes_.push_back(node);
335 queue_.push(node); 554 queue_.push(node);
336 } 555 }
337 556
338 // Enqueue {use_node}'s {index} input if the {use} contains new information 557 // Enqueue {use_node}'s {index} input if the {use} contains new information
339 // for that input node. Add the input to {nodes_} if this is the first time 558 // for that input node. Add the input to {nodes_} if this is the first time
340 // it's been visited. 559 // it's been visited.
341 void EnqueueInput(Node* use_node, int index, 560 void EnqueueInput(Node* use_node, int index,
342 UseInfo use_info = UseInfo::None()) { 561 UseInfo use_info = UseInfo::None()) {
343 Node* node = use_node->InputAt(index); 562 Node* node = use_node->InputAt(index);
344 if (phase_ != PROPAGATE) return; 563 if (phase_ != PROPAGATE) return;
345 NodeInfo* info = GetInfo(node); 564 NodeInfo* info = GetInfo(node);
346 #ifdef DEBUG 565 #ifdef DEBUG
347 // Check monotonicity of input requirements. 566 // Check monotonicity of input requirements.
348 node_input_use_infos_[use_node->id()].SetAndCheckInput(use_node, index, 567 node_input_use_infos_[use_node->id()].SetAndCheckInput(use_node, index,
349 use_info); 568 use_info);
350 #endif // DEBUG 569 #endif // DEBUG
351 if (!info->visited()) { 570 if (info->unvisited()) {
352 // First visit of this node. 571 // First visit of this node.
353 info->set_visited(); 572 info->set_queued();
354 info->set_queued(true);
355 nodes_.push_back(node); 573 nodes_.push_back(node);
356 queue_.push(node); 574 queue_.push(node);
357 TRACE(" initial: "); 575 TRACE(" initial: ");
358 info->AddUse(use_info); 576 info->AddUse(use_info);
359 PrintTruncation(info->truncation()); 577 PrintTruncation(info->truncation());
360 return; 578 return;
361 } 579 }
362 TRACE(" queue?: "); 580 TRACE(" queue?: ");
363 PrintTruncation(info->truncation()); 581 PrintTruncation(info->truncation());
364 if (info->AddUse(use_info)) { 582 if (info->AddUse(use_info)) {
365 // New usage information for the node is available. 583 // New usage information for the node is available.
366 if (!info->queued()) { 584 if (!info->queued()) {
367 queue_.push(node); 585 queue_.push(node);
368 info->set_queued(true); 586 info->set_queued();
369 TRACE(" added: "); 587 TRACE(" added: ");
370 } else { 588 } else {
371 TRACE(" inqueue: "); 589 TRACE(" inqueue: ");
372 } 590 }
373 PrintTruncation(info->truncation()); 591 PrintTruncation(info->truncation());
374 } 592 }
375 } 593 }
376 594
377 bool lower() { return phase_ == LOWER; } 595 bool lower() { return phase_ == LOWER; }
596 bool propagate() { return phase_ == PROPAGATE; }
378 597
379 void EnqueueUses(Node* node) { 598 void SetOutput(Node* node, MachineRepresentation representation,
380 for (Edge edge : node->use_edges()) { 599 TypeCheckKind type_check = TypeCheckKind::kNone) {
381 if (NodeProperties::IsValueEdge(edge)) { 600 DCHECK(MachineRepresentationIsSubtype(GetInfo(node)->representation(),
382 Node* const user = edge.from(); 601 representation));
383 if (user->id() < count_) { 602 ResetOutput(node, representation, type_check);
384 // New type information for the node is available.
385 NodeInfo* info = GetInfo(user);
386 // Enqueue the node only if we are sure it is reachable from
387 // the end and it has not been queued yet.
388 if (info->visited() && !info->queued()) {
389 queue_.push(user);
390 info->set_queued(true);
391 }
392 }
393 }
394 }
395 } 603 }
396 604
397 void SetOutput(Node* node, MachineRepresentation representation) { 605 void ResetOutput(Node* node, MachineRepresentation representation,
606 TypeCheckKind type_check = TypeCheckKind::kNone) {
398 NodeInfo* info = GetInfo(node); 607 NodeInfo* info = GetInfo(node);
399 DCHECK(
400 MachineRepresentationIsSubtype(info->representation(), representation));
401 info->set_output(representation); 608 info->set_output(representation);
609 info->set_type_check(type_check);
402 } 610 }
403 611
404 Type* GetUpperBound(Node* node) { return NodeProperties::GetType(node); } 612 Type* GetUpperBound(Node* node) { return NodeProperties::GetType(node); }
405 613
406 bool BothInputsAreSigned32(Node* node) { 614 bool BothInputsAreSigned32(Node* node) {
407 DCHECK_EQ(2, node->InputCount()); 615 DCHECK_EQ(2, node->InputCount());
408 return GetUpperBound(node->InputAt(0))->Is(Type::Signed32()) && 616 return GetUpperBound(node->InputAt(0))->Is(Type::Signed32()) &&
409 GetUpperBound(node->InputAt(1))->Is(Type::Signed32()); 617 GetUpperBound(node->InputAt(1))->Is(Type::Signed32());
410 } 618 }
411 619
412 bool BothInputsAreUnsigned32(Node* node) { 620 bool BothInputsAreUnsigned32(Node* node) {
413 DCHECK_EQ(2, node->InputCount()); 621 DCHECK_EQ(2, node->InputCount());
414 return GetUpperBound(node->InputAt(0))->Is(Type::Unsigned32()) && 622 return GetUpperBound(node->InputAt(0))->Is(Type::Unsigned32()) &&
415 GetUpperBound(node->InputAt(1))->Is(Type::Unsigned32()); 623 GetUpperBound(node->InputAt(1))->Is(Type::Unsigned32());
416 } 624 }
417 625
418 bool BothInputsAre(Node* node, Type* type) { 626 bool BothInputsAre(Node* node, Type* type) {
419 DCHECK_EQ(2, node->InputCount()); 627 DCHECK_EQ(2, node->op()->ValueInputCount());
420 return GetUpperBound(node->InputAt(0))->Is(type) && 628 return GetUpperBound(node->InputAt(0))->Is(type) &&
421 GetUpperBound(node->InputAt(1))->Is(type); 629 GetUpperBound(node->InputAt(1))->Is(type);
422 } 630 }
423 631
424 void ConvertInput(Node* node, int index, UseInfo use) { 632 void ConvertInput(Node* node, int index, UseInfo use) {
425 Node* input = node->InputAt(index); 633 Node* input = node->InputAt(index);
426 // In the change phase, insert a change before the use if necessary. 634 // In the change phase, insert a change before the use if necessary.
427 if (use.preferred() == MachineRepresentation::kNone) 635 if (use.representation() == MachineRepresentation::kNone)
428 return; // No input requirement on the use. 636 return; // No input requirement on the use.
429 NodeInfo* input_info = GetInfo(input); 637 NodeInfo* input_info = GetInfo(input);
430 MachineRepresentation input_rep = input_info->representation(); 638 MachineRepresentation input_rep = input_info->representation();
431 if (input_rep != use.preferred()) { 639 if (input_rep != use.representation() ||
640 use.type_check() != TypeCheckKind::kNone) {
432 // Output representation doesn't match usage. 641 // Output representation doesn't match usage.
433 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(), 642 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(),
434 index, input->id(), input->op()->mnemonic()); 643 index, input->id(), input->op()->mnemonic());
435 TRACE(" from "); 644 TRACE(" from ");
436 PrintOutputInfo(input_info); 645 PrintOutputInfo(input_info);
437 TRACE(" to "); 646 TRACE(" to ");
438 PrintUseInfo(use); 647 PrintUseInfo(use);
439 TRACE("\n"); 648 TRACE("\n");
440 Node* n = changer_->GetRepresentationFor( 649 Node* n = changer_->GetRepresentationFor(
441 input, input_info->representation(), GetUpperBound(input), 650 input, input_info->representation(), TypeOf(input), node, use);
442 use.preferred(), use.truncation());
443 node->ReplaceInput(index, n); 651 node->ReplaceInput(index, n);
444 } 652 }
445 } 653 }
446 654
447 void ProcessInput(Node* node, int index, UseInfo use) { 655 void ProcessInput(Node* node, int index, UseInfo use) {
448 if (phase_ == PROPAGATE) { 656 if (phase_ == PROPAGATE) {
449 EnqueueInput(node, index, use); 657 EnqueueInput(node, index, use);
450 } else { 658 } else {
451 ConvertInput(node, index, use); 659 ConvertInput(node, index, use);
452 } 660 }
(...skipping 24 matching lines...) Expand all
477 ProcessInput(node, i, UseInfo::AnyTagged()); 685 ProcessInput(node, i, UseInfo::AnyTagged());
478 } 686 }
479 // Only enqueue other inputs (framestates, effects, control). 687 // Only enqueue other inputs (framestates, effects, control).
480 for (int i = tagged_count; i < node->InputCount(); i++) { 688 for (int i = tagged_count; i < node->InputCount(); i++) {
481 EnqueueInput(node, i); 689 EnqueueInput(node, i);
482 } 690 }
483 } 691 }
484 692
485 // Helper for binops of the R x L -> O variety. 693 // Helper for binops of the R x L -> O variety.
486 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, 694 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use,
487 MachineRepresentation output) { 695 MachineRepresentation output,
696 TypeCheckKind type_check = TypeCheckKind::kNone) {
488 DCHECK_EQ(2, node->op()->ValueInputCount()); 697 DCHECK_EQ(2, node->op()->ValueInputCount());
489 ProcessInput(node, 0, left_use); 698 ProcessInput(node, 0, left_use);
490 ProcessInput(node, 1, right_use); 699 ProcessInput(node, 1, right_use);
491 for (int i = 2; i < node->InputCount(); i++) { 700 for (int i = 2; i < node->InputCount(); i++) {
492 EnqueueInput(node, i); 701 EnqueueInput(node, i);
493 } 702 }
494 SetOutput(node, output); 703 SetOutput(node, output, type_check);
495 } 704 }
496 705
497 // Helper for binops of the I x I -> O variety. 706 // Helper for binops of the I x I -> O variety.
498 void VisitBinop(Node* node, UseInfo input_use, MachineRepresentation output) { 707 void VisitBinop(Node* node, UseInfo input_use, MachineRepresentation output,
499 VisitBinop(node, input_use, input_use, output); 708 TypeCheckKind type_check = TypeCheckKind::kNone) {
709 VisitBinop(node, input_use, input_use, output, type_check);
500 } 710 }
501 711
502 // Helper for unops of the I -> O variety. 712 // Helper for unops of the I -> O variety.
503 void VisitUnop(Node* node, UseInfo input_use, MachineRepresentation output) { 713 void VisitUnop(Node* node, UseInfo input_use, MachineRepresentation output) {
504 DCHECK_EQ(1, node->InputCount()); 714 DCHECK_EQ(1, node->InputCount());
505 ProcessInput(node, 0, input_use); 715 ProcessInput(node, 0, input_use);
506 SetOutput(node, output); 716 SetOutput(node, output);
507 } 717 }
508 718
509 // Helper for leaf nodes. 719 // Helper for leaf nodes.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 VisitBinop(node, UseInfo::TruncatingWord32(), MachineRepresentation::kBit); 757 VisitBinop(node, UseInfo::TruncatingWord32(), MachineRepresentation::kBit);
548 } 758 }
549 void VisitInt64Cmp(Node* node) { 759 void VisitInt64Cmp(Node* node) {
550 VisitBinop(node, UseInfo::TruncatingWord64(), MachineRepresentation::kBit); 760 VisitBinop(node, UseInfo::TruncatingWord64(), MachineRepresentation::kBit);
551 } 761 }
552 void VisitUint64Cmp(Node* node) { 762 void VisitUint64Cmp(Node* node) {
553 VisitBinop(node, UseInfo::TruncatingWord64(), MachineRepresentation::kBit); 763 VisitBinop(node, UseInfo::TruncatingWord64(), MachineRepresentation::kBit);
554 } 764 }
555 765
556 // Infer representation for phi-like nodes. 766 // Infer representation for phi-like nodes.
557 MachineRepresentation GetOutputInfoForPhi(Node* node, Truncation use) { 767 MachineRepresentation GetOutputInfoForPhi(Node* node, Truncation use,
768 Type* type = nullptr) {
558 // Compute the representation. 769 // Compute the representation.
559 Type* type = GetUpperBound(node); 770 if (type == nullptr) {
771 type = TypeOf(node);
772 }
560 if (type->Is(Type::None())) { 773 if (type->Is(Type::None())) {
561 return MachineRepresentation::kNone; 774 return MachineRepresentation::kNone;
562 } else if (type->Is(Type::Signed32()) || type->Is(Type::Unsigned32())) { 775 } else if (type->Is(Type::Signed32()) || type->Is(Type::Unsigned32())) {
563 return MachineRepresentation::kWord32; 776 return MachineRepresentation::kWord32;
564 } else if (use.TruncatesToWord32()) { 777 } else if (use.TruncatesToWord32()) {
565 return MachineRepresentation::kWord32; 778 return MachineRepresentation::kWord32;
566 } else if (type->Is(Type::Boolean())) { 779 } else if (type->Is(Type::Boolean())) {
567 return MachineRepresentation::kBit; 780 return MachineRepresentation::kBit;
568 } else if (type->Is(Type::Number())) { 781 } else if (type->Is(Type::Number())) {
569 return MachineRepresentation::kFloat64; 782 return MachineRepresentation::kFloat64;
570 } else if (use.TruncatesToFloat64()) { 783 } else if (use.TruncatesToFloat64()) {
571 return MachineRepresentation::kFloat64; 784 return MachineRepresentation::kFloat64;
572 } else if (type->Is(Type::Internal())) { 785 } else if (type->Is(Type::Internal())) {
573 // We mark (u)int64 as Type::Internal. 786 // We mark (u)int64 as Type::Internal.
574 // TODO(jarin) This is a workaround for our lack of (u)int64 787 // TODO(jarin) This is a workaround for our lack of (u)int64
575 // types. This can be removed once we can represent (u)int64 788 // types. This can be removed once we can represent (u)int64
576 // unambiguously. (At the moment internal objects, such as the hole, 789 // unambiguously. (At the moment internal objects, such as the hole,
577 // are also Type::Internal()). 790 // are also Type::Internal()).
578 bool is_word64 = GetInfo(node->InputAt(0))->representation() == 791 bool is_word64 = GetInfo(node->InputAt(0))->representation() ==
579 MachineRepresentation::kWord64; 792 MachineRepresentation::kWord64;
580 #ifdef DEBUG 793 #ifdef DEBUG
581 // Check that all the inputs agree on being Word64. 794 // Check that all the inputs agree on being Word64.
795 DCHECK_EQ(IrOpcode::kPhi, node->opcode()); // This only works for phis.
582 for (int i = 1; i < node->op()->ValueInputCount(); i++) { 796 for (int i = 1; i < node->op()->ValueInputCount(); i++) {
583 DCHECK_EQ(is_word64, GetInfo(node->InputAt(i))->representation() == 797 DCHECK_EQ(is_word64, GetInfo(node->InputAt(i))->representation() ==
584 MachineRepresentation::kWord64); 798 MachineRepresentation::kWord64);
585 } 799 }
586 #endif 800 #endif
587 return is_word64 ? MachineRepresentation::kWord64 801 return is_word64 ? MachineRepresentation::kWord64
588 : MachineRepresentation::kTagged; 802 : MachineRepresentation::kTagged;
589 } 803 }
590 return MachineRepresentation::kTagged; 804 return MachineRepresentation::kTagged;
591 } 805 }
(...skipping 18 matching lines...) Expand all
610 // truncation truncation along. 824 // truncation truncation along.
611 UseInfo input_use(output, truncation); 825 UseInfo input_use(output, truncation);
612 ProcessInput(node, 1, input_use); 826 ProcessInput(node, 1, input_use);
613 ProcessInput(node, 2, input_use); 827 ProcessInput(node, 2, input_use);
614 } 828 }
615 829
616 // Helper for handling phis. 830 // Helper for handling phis.
617 void VisitPhi(Node* node, Truncation truncation, 831 void VisitPhi(Node* node, Truncation truncation,
618 SimplifiedLowering* lowering) { 832 SimplifiedLowering* lowering) {
619 MachineRepresentation output = GetOutputInfoForPhi(node, truncation); 833 MachineRepresentation output = GetOutputInfoForPhi(node, truncation);
834 // Only set the output representation if not running with type
835 // feedback. (Feedback typing will set the representation.)
620 SetOutput(node, output); 836 SetOutput(node, output);
621 837
622 int values = node->op()->ValueInputCount(); 838 int values = node->op()->ValueInputCount();
623 if (lower()) { 839 if (lower()) {
624 // Update the phi operator. 840 // Update the phi operator.
625 if (output != PhiRepresentationOf(node->op())) { 841 if (output != PhiRepresentationOf(node->op())) {
626 NodeProperties::ChangeOp(node, lowering->common()->Phi(output, values)); 842 NodeProperties::ChangeOp(node, lowering->common()->Phi(output, values));
627 } 843 }
628 } 844 }
629 845
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 } 895 }
680 } else { 896 } else {
681 Zone* zone = jsgraph_->zone(); 897 Zone* zone = jsgraph_->zone();
682 ZoneVector<MachineType>* types = 898 ZoneVector<MachineType>* types =
683 new (zone->New(sizeof(ZoneVector<MachineType>))) 899 new (zone->New(sizeof(ZoneVector<MachineType>)))
684 ZoneVector<MachineType>(node->InputCount(), zone); 900 ZoneVector<MachineType>(node->InputCount(), zone);
685 for (int i = 0; i < node->InputCount(); i++) { 901 for (int i = 0; i < node->InputCount(); i++) {
686 Node* input = node->InputAt(i); 902 Node* input = node->InputAt(i);
687 NodeInfo* input_info = GetInfo(input); 903 NodeInfo* input_info = GetInfo(input);
688 MachineType machine_type(input_info->representation(), 904 MachineType machine_type(input_info->representation(),
689 DeoptValueSemanticOf(GetUpperBound(input))); 905 DeoptValueSemanticOf(TypeOf(input)));
690 DCHECK(machine_type.representation() != 906 DCHECK(machine_type.representation() !=
691 MachineRepresentation::kWord32 || 907 MachineRepresentation::kWord32 ||
692 machine_type.semantic() == MachineSemantic::kInt32 || 908 machine_type.semantic() == MachineSemantic::kInt32 ||
693 machine_type.semantic() == MachineSemantic::kUint32); 909 machine_type.semantic() == MachineSemantic::kUint32);
694 (*types)[i] = machine_type; 910 (*types)[i] = machine_type;
695 } 911 }
696 NodeProperties::ChangeOp(node, 912 NodeProperties::ChangeOp(node,
697 jsgraph_->common()->TypedStateValues(types)); 913 jsgraph_->common()->TypedStateValues(types));
698 } 914 }
699 SetOutput(node, MachineRepresentation::kTagged); 915 SetOutput(node, MachineRepresentation::kTagged);
700 } 916 }
701 917
702 const Operator* Int32Op(Node* node) { 918 const Operator* Int32Op(Node* node) {
703 return changer_->Int32OperatorFor(node->opcode()); 919 return changer_->Int32OperatorFor(node->opcode());
704 } 920 }
705 921
922 const Operator* Int32OverflowOp(Node* node) {
923 return changer_->Int32OverflowOperatorFor(node->opcode());
924 }
925
706 const Operator* Uint32Op(Node* node) { 926 const Operator* Uint32Op(Node* node) {
707 return changer_->Uint32OperatorFor(node->opcode()); 927 return changer_->Uint32OperatorFor(node->opcode());
708 } 928 }
709 929
710 const Operator* Float64Op(Node* node) { 930 const Operator* Float64Op(Node* node) {
711 return changer_->Float64OperatorFor(node->opcode()); 931 return changer_->Float64OperatorFor(node->opcode());
712 } 932 }
713 933
714 WriteBarrierKind WriteBarrierKindFor( 934 WriteBarrierKind WriteBarrierKindFor(
715 BaseTaggedness base_taggedness, 935 BaseTaggedness base_taggedness,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 MachineRepresentation field_representation, int field_offset, 989 MachineRepresentation field_representation, int field_offset,
770 Type* field_type, Node* value) { 990 Type* field_type, Node* value) {
771 if (base_taggedness == kTaggedBase && 991 if (base_taggedness == kTaggedBase &&
772 field_offset == HeapObject::kMapOffset) { 992 field_offset == HeapObject::kMapOffset) {
773 return kMapWriteBarrier; 993 return kMapWriteBarrier;
774 } 994 }
775 return WriteBarrierKindFor(base_taggedness, field_representation, 995 return WriteBarrierKindFor(base_taggedness, field_representation,
776 field_type, value); 996 field_type, value);
777 } 997 }
778 998
999 Graph* graph() const { return jsgraph_->graph(); }
1000 CommonOperatorBuilder* common() const { return jsgraph_->common(); }
1001 SimplifiedOperatorBuilder* simplified() const {
1002 return jsgraph_->simplified();
1003 }
1004
1005 void ChangeToPureOp(Node* node, const Operator* new_op) {
1006 // Disconnect the node from effect and control chains.
1007 Node* control = NodeProperties::GetControlInput(node);
1008 Node* effect = NodeProperties::GetEffectInput(node);
1009 for (Edge edge : node->use_edges()) {
1010 if (NodeProperties::IsControlEdge(edge)) {
1011 edge.UpdateTo(control);
1012 } else if (NodeProperties::IsEffectEdge(edge)) {
1013 edge.UpdateTo(effect);
1014 } else {
1015 DCHECK(NodeProperties::IsValueEdge(edge));
1016 }
1017 }
1018
1019 node->TrimInputCount(new_op->ValueInputCount());
1020 NodeProperties::ChangeOp(node, new_op);
1021 }
1022
1023 void ReplaceEffectControlUses(Node* node, Node* effect, Node* control) {
1024 for (Edge edge : node->use_edges()) {
1025 if (NodeProperties::IsControlEdge(edge)) {
1026 edge.UpdateTo(control);
1027 } else if (NodeProperties::IsEffectEdge(edge)) {
1028 edge.UpdateTo(effect);
1029 } else {
1030 DCHECK(NodeProperties::IsValueEdge(edge));
1031 }
1032 }
1033 }
1034
1035 void ChangeToInt32OverflowOp(Node* node, const Operator* op) {
1036 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
1037 Node* effect = NodeProperties::GetEffectInput(node);
1038 Node* control = NodeProperties::GetControlInput(node);
1039 Node* arith = graph()->NewNode(op, node->InputAt(0), node->InputAt(1));
1040 Node* overflow = graph()->NewNode(common()->Projection(1), arith);
1041 control = effect = graph()->NewNode(common()->DeoptimizeIf(), overflow,
1042 frame_state, effect, control);
1043
1044 Node* value = graph()->NewNode(common()->Projection(0), arith);
1045 ReplaceEffectControlUses(node, effect, control);
1046 DeferReplacement(node, value);
1047 }
1048
1049 void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation,
1050 SimplifiedLowering* lowering) {
1051 if (BothInputsAre(node, Type::Signed32()) &&
1052 NodeProperties::GetType(node)->Is(Type::Signed32())) {
1053 // int32 + int32 = int32 ==> signed Int32Add/Sub
1054 VisitInt32Binop(node);
1055 if (lower()) ChangeToPureOp(node, Int32Op(node));
1056 return;
1057 }
1058
1059 // Use truncation if available.
1060 if (BothInputsAre(node, type_cache_.kAdditiveSafeInteger) &&
1061 truncation.TruncatesToWord32()) {
1062 // safe-int + safe-int = x (truncated to int32)
1063 // => signed Int32Add/Sub (truncated)
1064 VisitWord32TruncatingBinop(node);
1065 if (lower()) ChangeToPureOp(node, Int32Op(node));
1066 return;
1067 }
1068
1069 // Try to use type feedback.
1070 BinaryOperationHints::Hint hint = BinaryOperationHintOf(node->op());
1071
1072 // TODO(jarin) This might not be necessary (covered by the next case).
1073 // The only real difference is that this one actually treats the
1074 // inputs as truncated to word32.
1075 if (BothInputsAre(node, Type::Signed32())) {
1076 // If both the inputs the feedback are int32, use the overflow op.
1077 if (hint == BinaryOperationHints::kSignedSmall ||
1078 hint == BinaryOperationHints::kSigned32) {
1079 VisitBinop(node, UseInfo::TruncatingWord32(),
1080 MachineRepresentation::kWord32, TypeCheckKind::kSigned32);
1081 if (lower()) {
1082 ChangeToInt32OverflowOp(node, Int32OverflowOp(node));
1083 }
1084 return;
1085 }
1086 }
1087
1088 if (hint == BinaryOperationHints::kSignedSmall ||
1089 hint == BinaryOperationHints::kSigned32) {
1090 VisitBinop(node, UseInfo::CheckedSigned32AsWord32(),
1091 MachineRepresentation::kWord32, TypeCheckKind::kSigned32);
1092 if (lower()) {
1093 ChangeToInt32OverflowOp(node, Int32OverflowOp(node));
1094 }
1095 return;
1096 }
1097
1098 // default case => Float64Add/Sub
1099 VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(),
1100 MachineRepresentation::kFloat64, TypeCheckKind::kNumber);
1101 if (lower()) {
1102 ChangeToPureOp(node, Float64Op(node));
1103 }
1104 return;
1105 }
1106
779 // Dispatching routine for visiting the node {node} with the usage {use}. 1107 // Dispatching routine for visiting the node {node} with the usage {use}.
780 // Depending on the operator, propagate new usage info to the inputs. 1108 // Depending on the operator, propagate new usage info to the inputs.
781 void VisitNode(Node* node, Truncation truncation, 1109 void VisitNode(Node* node, Truncation truncation,
782 SimplifiedLowering* lowering) { 1110 SimplifiedLowering* lowering) {
783 switch (node->opcode()) { 1111 switch (node->opcode()) {
784 //------------------------------------------------------------------ 1112 //------------------------------------------------------------------
785 // Common operators. 1113 // Common operators.
786 //------------------------------------------------------------------ 1114 //------------------------------------------------------------------
787 case IrOpcode::kStart: 1115 case IrOpcode::kStart:
788 case IrOpcode::kDead: 1116 case IrOpcode::kDead:
(...skipping 17 matching lines...) Expand all
806 case IrOpcode::kNumberConstant: 1134 case IrOpcode::kNumberConstant:
807 return VisitLeaf(node, MachineRepresentation::kTagged); 1135 return VisitLeaf(node, MachineRepresentation::kTagged);
808 case IrOpcode::kHeapConstant: 1136 case IrOpcode::kHeapConstant:
809 return VisitLeaf(node, MachineRepresentation::kTagged); 1137 return VisitLeaf(node, MachineRepresentation::kTagged);
810 1138
811 case IrOpcode::kDeoptimizeIf: 1139 case IrOpcode::kDeoptimizeIf:
812 case IrOpcode::kDeoptimizeUnless: 1140 case IrOpcode::kDeoptimizeUnless:
813 ProcessInput(node, 0, UseInfo::Bool()); 1141 ProcessInput(node, 0, UseInfo::Bool());
814 ProcessInput(node, 1, UseInfo::AnyTagged()); 1142 ProcessInput(node, 1, UseInfo::AnyTagged());
815 ProcessRemainingInputs(node, 2); 1143 ProcessRemainingInputs(node, 2);
816 break; 1144 return;
817 case IrOpcode::kBranch: 1145 case IrOpcode::kBranch:
818 ProcessInput(node, 0, UseInfo::Bool()); 1146 ProcessInput(node, 0, UseInfo::Bool());
819 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); 1147 EnqueueInput(node, NodeProperties::FirstControlIndex(node));
820 break; 1148 return;
821 case IrOpcode::kSwitch: 1149 case IrOpcode::kSwitch:
822 ProcessInput(node, 0, UseInfo::TruncatingWord32()); 1150 ProcessInput(node, 0, UseInfo::TruncatingWord32());
823 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); 1151 EnqueueInput(node, NodeProperties::FirstControlIndex(node));
824 break; 1152 return;
825 case IrOpcode::kSelect: 1153 case IrOpcode::kSelect:
826 return VisitSelect(node, truncation, lowering); 1154 return VisitSelect(node, truncation, lowering);
827 case IrOpcode::kPhi: 1155 case IrOpcode::kPhi:
828 return VisitPhi(node, truncation, lowering); 1156 return VisitPhi(node, truncation, lowering);
829 case IrOpcode::kCall: 1157 case IrOpcode::kCall:
830 return VisitCall(node, lowering); 1158 return VisitCall(node, lowering);
831 1159
832 //------------------------------------------------------------------ 1160 //------------------------------------------------------------------
833 // JavaScript operators. 1161 // JavaScript operators.
834 //------------------------------------------------------------------ 1162 //------------------------------------------------------------------
835 case IrOpcode::kJSToNumber: { 1163 case IrOpcode::kJSToNumber: {
836 VisitInputs(node); 1164 VisitInputs(node);
837 // TODO(bmeurer): Optimize somewhat based on input type? 1165 // TODO(bmeurer): Optimize somewhat based on input type?
838 if (truncation.TruncatesToWord32()) { 1166 if (truncation.TruncatesToWord32()) {
839 SetOutput(node, MachineRepresentation::kWord32); 1167 SetOutput(node, MachineRepresentation::kWord32);
840 if (lower()) lowering->DoJSToNumberTruncatesToWord32(node, this); 1168 if (lower()) lowering->DoJSToNumberTruncatesToWord32(node, this);
841 } else if (truncation.TruncatesToFloat64()) { 1169 } else if (truncation.TruncatesToFloat64()) {
842 SetOutput(node, MachineRepresentation::kFloat64); 1170 SetOutput(node, MachineRepresentation::kFloat64);
843 if (lower()) lowering->DoJSToNumberTruncatesToFloat64(node, this); 1171 if (lower()) lowering->DoJSToNumberTruncatesToFloat64(node, this);
844 } else { 1172 } else {
845 SetOutput(node, MachineRepresentation::kTagged); 1173 SetOutput(node, MachineRepresentation::kTagged);
846 } 1174 }
847 break; 1175 return;
848 } 1176 }
849 1177
850 //------------------------------------------------------------------ 1178 //------------------------------------------------------------------
851 // Simplified operators. 1179 // Simplified operators.
852 //------------------------------------------------------------------ 1180 //------------------------------------------------------------------
853 case IrOpcode::kBooleanNot: { 1181 case IrOpcode::kBooleanNot: {
854 if (lower()) { 1182 if (lower()) {
855 NodeInfo* input_info = GetInfo(node->InputAt(0)); 1183 NodeInfo* input_info = GetInfo(node->InputAt(0));
856 if (input_info->representation() == MachineRepresentation::kBit) { 1184 if (input_info->representation() == MachineRepresentation::kBit) {
857 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) 1185 // BooleanNot(x: kRepBit) => Word32Equal(x, #0)
858 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); 1186 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0));
859 NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal()); 1187 NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal());
860 } else { 1188 } else {
861 // BooleanNot(x: kRepTagged) => WordEqual(x, #false) 1189 // BooleanNot(x: kRepTagged) => WordEqual(x, #false)
862 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant()); 1190 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant());
863 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); 1191 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
864 } 1192 }
865 } else { 1193 } else {
866 // No input representation requirement; adapt during lowering. 1194 // No input representation requirement; adapt during lowering.
867 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); 1195 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool());
868 SetOutput(node, MachineRepresentation::kBit); 1196 SetOutput(node, MachineRepresentation::kBit);
869 } 1197 }
870 break; 1198 return;
871 } 1199 }
872 case IrOpcode::kBooleanToNumber: { 1200 case IrOpcode::kBooleanToNumber: {
873 if (lower()) { 1201 if (lower()) {
874 NodeInfo* input_info = GetInfo(node->InputAt(0)); 1202 NodeInfo* input_info = GetInfo(node->InputAt(0));
875 if (input_info->representation() == MachineRepresentation::kBit) { 1203 if (input_info->representation() == MachineRepresentation::kBit) {
876 // BooleanToNumber(x: kRepBit) => x 1204 // BooleanToNumber(x: kRepBit) => x
877 DeferReplacement(node, node->InputAt(0)); 1205 DeferReplacement(node, node->InputAt(0));
878 } else { 1206 } else {
879 // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true) 1207 // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true)
880 node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant()); 1208 node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant());
881 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); 1209 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
882 } 1210 }
883 } else { 1211 } else {
884 // No input representation requirement; adapt during lowering. 1212 // No input representation requirement; adapt during lowering.
885 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); 1213 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool());
886 SetOutput(node, MachineRepresentation::kWord32); 1214 SetOutput(node, MachineRepresentation::kWord32);
887 } 1215 }
888 break; 1216 return;
889 } 1217 }
890 case IrOpcode::kNumberEqual: 1218 case IrOpcode::kNumberEqual:
891 case IrOpcode::kNumberLessThan: 1219 case IrOpcode::kNumberLessThan:
892 case IrOpcode::kNumberLessThanOrEqual: { 1220 case IrOpcode::kNumberLessThanOrEqual: {
893 // Number comparisons reduce to integer comparisons for integer inputs. 1221 // Number comparisons reduce to integer comparisons for integer inputs.
894 if (BothInputsAreSigned32(node)) { 1222 if (BothInputsAreSigned32(node)) {
895 // => signed Int32Cmp 1223 // => signed Int32Cmp
896 VisitInt32Cmp(node); 1224 VisitInt32Cmp(node);
897 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); 1225 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
898 } else if (BothInputsAreUnsigned32(node)) { 1226 } else if (BothInputsAreUnsigned32(node)) {
899 // => unsigned Int32Cmp 1227 // => unsigned Int32Cmp
900 VisitUint32Cmp(node); 1228 VisitUint32Cmp(node);
901 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); 1229 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
902 } else { 1230 } else {
903 // => Float64Cmp 1231 // => Float64Cmp
904 VisitFloat64Cmp(node); 1232 VisitFloat64Cmp(node);
905 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); 1233 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
906 } 1234 }
907 break; 1235 return;
908 } 1236 }
1237
1238 case IrOpcode::kSpeculativeNumberAdd:
1239 case IrOpcode::kSpeculativeNumberSubtract:
1240 return VisitSpeculativeAdditiveOp(node, truncation, lowering);
1241
909 case IrOpcode::kNumberAdd: 1242 case IrOpcode::kNumberAdd:
910 case IrOpcode::kNumberSubtract: { 1243 case IrOpcode::kNumberSubtract: {
911 if (BothInputsAre(node, Type::Signed32()) && 1244 if (BothInputsAre(node, Type::Signed32()) &&
912 NodeProperties::GetType(node)->Is(Type::Signed32())) { 1245 NodeProperties::GetType(node)->Is(Type::Signed32())) {
913 // int32 + int32 = int32 1246 // int32 + int32 = int32
914 // => signed Int32Add/Sub 1247 // => signed Int32Add/Sub
915 VisitInt32Binop(node); 1248 VisitInt32Binop(node);
916 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); 1249 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
917 } else if (BothInputsAre(node, type_cache_.kAdditiveSafeInteger) && 1250 } else if (BothInputsAre(node, type_cache_.kAdditiveSafeInteger) &&
918 truncation.TruncatesToWord32()) { 1251 truncation.TruncatesToWord32()) {
919 // safe-int + safe-int = x (truncated to int32) 1252 // safe-int + safe-int = x (truncated to int32)
920 // => signed Int32Add/Sub (truncated) 1253 // => signed Int32Add/Sub (truncated)
921 VisitWord32TruncatingBinop(node); 1254 VisitWord32TruncatingBinop(node);
922 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); 1255 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
923 } else { 1256 } else {
924 // => Float64Add/Sub 1257 // => Float64Add/Sub
925 VisitFloat64Binop(node); 1258 VisitFloat64Binop(node);
926 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); 1259 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
927 } 1260 }
928 break; 1261 return;
929 } 1262 }
930 case IrOpcode::kNumberMultiply: { 1263 case IrOpcode::kNumberMultiply: {
931 if (BothInputsAreSigned32(node)) { 1264 if (BothInputsAreSigned32(node)) {
932 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { 1265 if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
933 // Multiply reduces to Int32Mul if the inputs and the output 1266 // Multiply reduces to Int32Mul if the inputs and the output
934 // are integers. 1267 // are integers.
935 VisitInt32Binop(node); 1268 VisitInt32Binop(node);
936 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); 1269 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
937 break; 1270 return;
938 } 1271 }
939 if (truncation.TruncatesToWord32() && 1272 if (truncation.TruncatesToWord32() &&
940 NodeProperties::GetType(node)->Is(type_cache_.kSafeInteger)) { 1273 NodeProperties::GetType(node)->Is(type_cache_.kSafeInteger)) {
941 // Multiply reduces to Int32Mul if the inputs are integers, 1274 // Multiply reduces to Int32Mul if the inputs are integers,
942 // the uses are truncating and the result is in the safe 1275 // the uses are truncating and the result is in the safe
943 // integer range. 1276 // integer range.
944 VisitWord32TruncatingBinop(node); 1277 VisitWord32TruncatingBinop(node);
945 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); 1278 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
946 break; 1279 return;
947 } 1280 }
948 } 1281 }
949 // => Float64Mul 1282 // => Float64Mul
950 VisitFloat64Binop(node); 1283 VisitFloat64Binop(node);
951 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); 1284 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
952 break; 1285 return;
953 } 1286 }
954 case IrOpcode::kNumberDivide: { 1287 case IrOpcode::kNumberDivide: {
955 if (BothInputsAreSigned32(node)) { 1288 if (BothInputsAreSigned32(node)) {
956 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { 1289 if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
957 // => signed Int32Div 1290 // => signed Int32Div
958 VisitInt32Binop(node); 1291 VisitInt32Binop(node);
959 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); 1292 if (lower()) DeferReplacement(node, lowering->Int32Div(node));
960 break; 1293 return;
961 } 1294 }
962 if (truncation.TruncatesToWord32()) { 1295 if (truncation.TruncatesToWord32()) {
963 // => signed Int32Div 1296 // => signed Int32Div
964 VisitWord32TruncatingBinop(node); 1297 VisitWord32TruncatingBinop(node);
965 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); 1298 if (lower()) DeferReplacement(node, lowering->Int32Div(node));
966 break; 1299 return;
967 } 1300 }
968 } 1301 }
969 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { 1302 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) {
970 // => unsigned Uint32Div 1303 // => unsigned Uint32Div
971 VisitWord32TruncatingBinop(node); 1304 VisitWord32TruncatingBinop(node);
972 if (lower()) DeferReplacement(node, lowering->Uint32Div(node)); 1305 if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
973 break; 1306 return;
974 } 1307 }
975 // => Float64Div 1308 // => Float64Div
976 VisitFloat64Binop(node); 1309 VisitFloat64Binop(node);
977 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); 1310 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
978 break; 1311 return;
979 } 1312 }
980 case IrOpcode::kNumberModulus: { 1313 case IrOpcode::kNumberModulus: {
981 if (BothInputsAreSigned32(node)) { 1314 if (BothInputsAreSigned32(node)) {
982 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { 1315 if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
983 // => signed Int32Mod 1316 // => signed Int32Mod
984 VisitInt32Binop(node); 1317 VisitInt32Binop(node);
985 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); 1318 if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
986 break; 1319 return;
987 } 1320 }
988 if (truncation.TruncatesToWord32()) { 1321 if (truncation.TruncatesToWord32()) {
989 // => signed Int32Mod 1322 // => signed Int32Mod
990 VisitWord32TruncatingBinop(node); 1323 VisitWord32TruncatingBinop(node);
991 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); 1324 if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
992 break; 1325 return;
993 } 1326 }
994 } 1327 }
995 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { 1328 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) {
996 // => unsigned Uint32Mod 1329 // => unsigned Uint32Mod
997 VisitWord32TruncatingBinop(node); 1330 VisitWord32TruncatingBinop(node);
998 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); 1331 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
999 break; 1332 return;
1000 } 1333 }
1001 // => Float64Mod 1334 // => Float64Mod
1002 VisitFloat64Binop(node); 1335 VisitFloat64Binop(node);
1003 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); 1336 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
1004 break; 1337 return;
1005 } 1338 }
1006 case IrOpcode::kNumberBitwiseOr: 1339 case IrOpcode::kNumberBitwiseOr:
1007 case IrOpcode::kNumberBitwiseXor: 1340 case IrOpcode::kNumberBitwiseXor:
1008 case IrOpcode::kNumberBitwiseAnd: { 1341 case IrOpcode::kNumberBitwiseAnd: {
1009 VisitInt32Binop(node); 1342 VisitInt32Binop(node);
1010 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); 1343 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
1011 break; 1344 return;
1012 } 1345 }
1013 case IrOpcode::kNumberShiftLeft: { 1346 case IrOpcode::kNumberShiftLeft: {
1014 Type* rhs_type = GetUpperBound(node->InputAt(1)); 1347 Type* rhs_type = GetUpperBound(node->InputAt(1));
1015 VisitBinop(node, UseInfo::TruncatingWord32(), 1348 VisitBinop(node, UseInfo::TruncatingWord32(),
1016 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32); 1349 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
1017 if (lower()) { 1350 if (lower()) {
1018 lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type); 1351 lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
1019 } 1352 }
1020 break; 1353 return;
1021 } 1354 }
1022 case IrOpcode::kNumberShiftRight: { 1355 case IrOpcode::kNumberShiftRight: {
1023 Type* rhs_type = GetUpperBound(node->InputAt(1)); 1356 Type* rhs_type = GetUpperBound(node->InputAt(1));
1024 VisitBinop(node, UseInfo::TruncatingWord32(), 1357 VisitBinop(node, UseInfo::TruncatingWord32(),
1025 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32); 1358 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
1026 if (lower()) { 1359 if (lower()) {
1027 lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type); 1360 lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type);
1028 } 1361 }
1029 break; 1362 return;
1030 } 1363 }
1031 case IrOpcode::kNumberShiftRightLogical: { 1364 case IrOpcode::kNumberShiftRightLogical: {
1032 Type* rhs_type = GetUpperBound(node->InputAt(1)); 1365 Type* rhs_type = GetUpperBound(node->InputAt(1));
1033 VisitBinop(node, UseInfo::TruncatingWord32(), 1366 VisitBinop(node, UseInfo::TruncatingWord32(),
1034 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32); 1367 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
1035 if (lower()) { 1368 if (lower()) {
1036 lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type); 1369 lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
1037 } 1370 }
1038 break; 1371 return;
1039 } 1372 }
1040 case IrOpcode::kNumberClz32: { 1373 case IrOpcode::kNumberClz32: {
1041 VisitUnop(node, UseInfo::TruncatingWord32(), 1374 VisitUnop(node, UseInfo::TruncatingWord32(),
1042 MachineRepresentation::kWord32); 1375 MachineRepresentation::kWord32);
1043 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); 1376 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
1044 break; 1377 return;
1045 } 1378 }
1046 case IrOpcode::kNumberImul: { 1379 case IrOpcode::kNumberImul: {
1047 VisitBinop(node, UseInfo::TruncatingWord32(), 1380 VisitBinop(node, UseInfo::TruncatingWord32(),
1048 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32); 1381 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
1049 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); 1382 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
1050 break; 1383 return;
1051 } 1384 }
1052 case IrOpcode::kNumberCeil: { 1385 case IrOpcode::kNumberCeil: {
1053 VisitUnop(node, UseInfo::TruncatingFloat64(), 1386 VisitUnop(node, UseInfo::TruncatingFloat64(),
1054 MachineRepresentation::kFloat64); 1387 MachineRepresentation::kFloat64);
1055 if (lower()) DeferReplacement(node, lowering->Float64Ceil(node)); 1388 if (lower()) DeferReplacement(node, lowering->Float64Ceil(node));
1056 break; 1389 return;
1057 } 1390 }
1058 case IrOpcode::kNumberFloor: { 1391 case IrOpcode::kNumberFloor: {
1059 VisitUnop(node, UseInfo::TruncatingFloat64(), 1392 VisitUnop(node, UseInfo::TruncatingFloat64(),
1060 MachineRepresentation::kFloat64); 1393 MachineRepresentation::kFloat64);
1061 if (lower()) DeferReplacement(node, lowering->Float64Floor(node)); 1394 if (lower()) DeferReplacement(node, lowering->Float64Floor(node));
1062 break; 1395 return;
1063 } 1396 }
1064 case IrOpcode::kNumberRound: { 1397 case IrOpcode::kNumberRound: {
1065 VisitUnop(node, UseInfo::TruncatingFloat64(), 1398 VisitUnop(node, UseInfo::TruncatingFloat64(),
1066 MachineRepresentation::kFloat64); 1399 MachineRepresentation::kFloat64);
1067 if (lower()) DeferReplacement(node, lowering->Float64Round(node)); 1400 if (lower()) DeferReplacement(node, lowering->Float64Round(node));
1068 break; 1401 return;
1069 } 1402 }
1070 case IrOpcode::kNumberTrunc: { 1403 case IrOpcode::kNumberTrunc: {
1071 VisitUnop(node, UseInfo::TruncatingFloat64(), 1404 VisitUnop(node, UseInfo::TruncatingFloat64(),
1072 MachineRepresentation::kFloat64); 1405 MachineRepresentation::kFloat64);
1073 if (lower()) DeferReplacement(node, lowering->Float64Trunc(node)); 1406 if (lower()) DeferReplacement(node, lowering->Float64Trunc(node));
1074 break; 1407 return;
1075 } 1408 }
1076 case IrOpcode::kNumberToInt32: { 1409 case IrOpcode::kNumberToInt32: {
1077 // Just change representation if necessary. 1410 // Just change representation if necessary.
1078 VisitUnop(node, UseInfo::TruncatingWord32(), 1411 VisitUnop(node, UseInfo::TruncatingWord32(),
1079 MachineRepresentation::kWord32); 1412 MachineRepresentation::kWord32);
1080 if (lower()) DeferReplacement(node, node->InputAt(0)); 1413 if (lower()) DeferReplacement(node, node->InputAt(0));
1081 break; 1414 return;
1082 } 1415 }
1083 case IrOpcode::kNumberToUint32: { 1416 case IrOpcode::kNumberToUint32: {
1084 // Just change representation if necessary. 1417 // Just change representation if necessary.
1085 VisitUnop(node, UseInfo::TruncatingWord32(), 1418 VisitUnop(node, UseInfo::TruncatingWord32(),
1086 MachineRepresentation::kWord32); 1419 MachineRepresentation::kWord32);
1087 if (lower()) DeferReplacement(node, node->InputAt(0)); 1420 if (lower()) DeferReplacement(node, node->InputAt(0));
1088 break; 1421 return;
1089 } 1422 }
1090 case IrOpcode::kNumberIsHoleNaN: { 1423 case IrOpcode::kNumberIsHoleNaN: {
1091 VisitUnop(node, UseInfo::TruncatingFloat64(), 1424 VisitUnop(node, UseInfo::TruncatingFloat64(),
1092 MachineRepresentation::kBit); 1425 MachineRepresentation::kBit);
1093 if (lower()) { 1426 if (lower()) {
1094 // NumberIsHoleNaN(x) => Word32Equal(Float64ExtractHighWord32(x), 1427 // NumberIsHoleNaN(x) => Word32Equal(Float64ExtractHighWord32(x),
1095 // #HoleNanUpper32) 1428 // #HoleNanUpper32)
1096 node->ReplaceInput( 1429 node->ReplaceInput(
1097 0, jsgraph_->graph()->NewNode( 1430 0, jsgraph_->graph()->NewNode(
1098 lowering->machine()->Float64ExtractHighWord32(), 1431 lowering->machine()->Float64ExtractHighWord32(),
1099 node->InputAt(0))); 1432 node->InputAt(0)));
1100 node->AppendInput(jsgraph_->zone(), 1433 node->AppendInput(jsgraph_->zone(),
1101 jsgraph_->Int32Constant(kHoleNanUpper32)); 1434 jsgraph_->Int32Constant(kHoleNanUpper32));
1102 NodeProperties::ChangeOp(node, jsgraph_->machine()->Word32Equal()); 1435 NodeProperties::ChangeOp(node, jsgraph_->machine()->Word32Equal());
1103 } 1436 }
1104 break; 1437 return;
1105 } 1438 }
1106 case IrOpcode::kReferenceEqual: { 1439 case IrOpcode::kReferenceEqual: {
1107 VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit); 1440 VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
1108 if (lower()) { 1441 if (lower()) {
1109 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); 1442 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
1110 } 1443 }
1111 break; 1444 return;
1112 } 1445 }
1113 case IrOpcode::kStringEqual: { 1446 case IrOpcode::kStringEqual: {
1114 VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged); 1447 VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
1115 if (lower()) { 1448 if (lower()) {
1116 // StringEqual(x, y) => Call(StringEqualStub, x, y, no-context) 1449 // StringEqual(x, y) => Call(StringEqualStub, x, y, no-context)
1117 Operator::Properties properties = 1450 Operator::Properties properties =
1118 Operator::kCommutative | Operator::kNoThrow; 1451 Operator::kCommutative | Operator::kNoThrow;
1119 Callable callable = CodeFactory::StringEqual(jsgraph_->isolate()); 1452 Callable callable = CodeFactory::StringEqual(jsgraph_->isolate());
1120 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; 1453 CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
1121 CallDescriptor* desc = Linkage::GetStubCallDescriptor( 1454 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
1122 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, 1455 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0,
1123 flags, properties); 1456 flags, properties);
1124 node->InsertInput(jsgraph_->zone(), 0, 1457 node->InsertInput(jsgraph_->zone(), 0,
1125 jsgraph_->HeapConstant(callable.code())); 1458 jsgraph_->HeapConstant(callable.code()));
1126 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); 1459 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant());
1127 node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start()); 1460 node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start());
1128 node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start()); 1461 node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start());
1129 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); 1462 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc));
1130 } 1463 }
1131 break; 1464 return;
1132 } 1465 }
1133 case IrOpcode::kStringLessThan: { 1466 case IrOpcode::kStringLessThan: {
1134 VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged); 1467 VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
1135 if (lower()) { 1468 if (lower()) {
1136 // StringLessThan(x, y) => Call(StringLessThanStub, x, y, no-context) 1469 // StringLessThan(x, y) => Call(StringLessThanStub, x, y, no-context)
1137 Operator::Properties properties = Operator::kNoThrow; 1470 Operator::Properties properties = Operator::kNoThrow;
1138 Callable callable = CodeFactory::StringLessThan(jsgraph_->isolate()); 1471 Callable callable = CodeFactory::StringLessThan(jsgraph_->isolate());
1139 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; 1472 CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
1140 CallDescriptor* desc = Linkage::GetStubCallDescriptor( 1473 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
1141 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, 1474 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0,
1142 flags, properties); 1475 flags, properties);
1143 node->InsertInput(jsgraph_->zone(), 0, 1476 node->InsertInput(jsgraph_->zone(), 0,
1144 jsgraph_->HeapConstant(callable.code())); 1477 jsgraph_->HeapConstant(callable.code()));
1145 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); 1478 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant());
1146 node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start()); 1479 node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start());
1147 node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start()); 1480 node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start());
1148 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); 1481 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc));
1149 } 1482 }
1150 break; 1483 return;
1151 } 1484 }
1152 case IrOpcode::kStringLessThanOrEqual: { 1485 case IrOpcode::kStringLessThanOrEqual: {
1153 VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged); 1486 VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
1154 if (lower()) { 1487 if (lower()) {
1155 // StringLessThanOrEqual(x, y) 1488 // StringLessThanOrEqual(x, y)
1156 // => Call(StringLessThanOrEqualStub, x, y, no-context) 1489 // => Call(StringLessThanOrEqualStub, x, y, no-context)
1157 Operator::Properties properties = Operator::kNoThrow; 1490 Operator::Properties properties = Operator::kNoThrow;
1158 Callable callable = 1491 Callable callable =
1159 CodeFactory::StringLessThanOrEqual(jsgraph_->isolate()); 1492 CodeFactory::StringLessThanOrEqual(jsgraph_->isolate());
1160 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; 1493 CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
1161 CallDescriptor* desc = Linkage::GetStubCallDescriptor( 1494 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
1162 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, 1495 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0,
1163 flags, properties); 1496 flags, properties);
1164 node->InsertInput(jsgraph_->zone(), 0, 1497 node->InsertInput(jsgraph_->zone(), 0,
1165 jsgraph_->HeapConstant(callable.code())); 1498 jsgraph_->HeapConstant(callable.code()));
1166 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); 1499 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant());
1167 node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start()); 1500 node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start());
1168 node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start()); 1501 node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start());
1169 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); 1502 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc));
1170 } 1503 }
1171 break; 1504 return;
1172 } 1505 }
1173 case IrOpcode::kStringFromCharCode: { 1506 case IrOpcode::kStringFromCharCode: {
1174 VisitUnop(node, UseInfo::TruncatingWord32(), 1507 VisitUnop(node, UseInfo::TruncatingWord32(),
1175 MachineRepresentation::kTagged); 1508 MachineRepresentation::kTagged);
1176 break; 1509 return;
1177 } 1510 }
1178 case IrOpcode::kStringToNumber: { 1511 case IrOpcode::kStringToNumber: {
1179 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged); 1512 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
1180 if (lower()) { 1513 if (lower()) {
1181 // StringToNumber(x) => Call(StringToNumberStub, x, no-context) 1514 // StringToNumber(x) => Call(StringToNumberStub, x, no-context)
1182 Operator::Properties properties = Operator::kNoThrow; 1515 Operator::Properties properties = Operator::kNoThrow;
1183 Callable callable = CodeFactory::StringToNumber(jsgraph_->isolate()); 1516 Callable callable = CodeFactory::StringToNumber(jsgraph_->isolate());
1184 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; 1517 CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
1185 CallDescriptor* desc = Linkage::GetStubCallDescriptor( 1518 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
1186 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, 1519 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0,
1187 flags, properties); 1520 flags, properties);
1188 node->InsertInput(jsgraph_->zone(), 0, 1521 node->InsertInput(jsgraph_->zone(), 0,
1189 jsgraph_->HeapConstant(callable.code())); 1522 jsgraph_->HeapConstant(callable.code()));
1190 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); 1523 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant());
1191 node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start()); 1524 node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start());
1192 node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start()); 1525 node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start());
1193 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); 1526 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc));
1194 } 1527 }
1195 break; 1528 return;
1196 } 1529 }
1197 case IrOpcode::kAllocate: { 1530 case IrOpcode::kAllocate: {
1198 ProcessInput(node, 0, UseInfo::TruncatingWord32()); 1531 ProcessInput(node, 0, UseInfo::TruncatingWord32());
1199 ProcessRemainingInputs(node, 1); 1532 ProcessRemainingInputs(node, 1);
1200 SetOutput(node, MachineRepresentation::kTagged); 1533 SetOutput(node, MachineRepresentation::kTagged);
1201 break; 1534 return;
1202 } 1535 }
1203 case IrOpcode::kLoadField: { 1536 case IrOpcode::kLoadField: {
1204 FieldAccess access = FieldAccessOf(node->op()); 1537 FieldAccess access = FieldAccessOf(node->op());
1205 ProcessInput(node, 0, UseInfoForBasePointer(access)); 1538 ProcessInput(node, 0, UseInfoForBasePointer(access));
1206 ProcessRemainingInputs(node, 1); 1539 ProcessRemainingInputs(node, 1);
1207 SetOutput(node, access.machine_type.representation()); 1540 SetOutput(node, access.machine_type.representation());
1208 break; 1541 return;
1209 } 1542 }
1210 case IrOpcode::kStoreField: { 1543 case IrOpcode::kStoreField: {
1211 FieldAccess access = FieldAccessOf(node->op()); 1544 FieldAccess access = FieldAccessOf(node->op());
1212 ProcessInput(node, 0, UseInfoForBasePointer(access)); 1545 ProcessInput(node, 0, UseInfoForBasePointer(access));
1213 ProcessInput(node, 1, TruncatingUseInfoFromRepresentation( 1546 ProcessInput(node, 1, TruncatingUseInfoFromRepresentation(
1214 access.machine_type.representation())); 1547 access.machine_type.representation()));
1215 ProcessRemainingInputs(node, 2); 1548 ProcessRemainingInputs(node, 2);
1216 SetOutput(node, MachineRepresentation::kNone); 1549 SetOutput(node, MachineRepresentation::kNone);
1217 if (lower()) { 1550 if (lower()) {
1218 WriteBarrierKind write_barrier_kind = WriteBarrierKindFor( 1551 WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
1219 access.base_is_tagged, access.machine_type.representation(), 1552 access.base_is_tagged, access.machine_type.representation(),
1220 access.offset, access.type, node->InputAt(1)); 1553 access.offset, access.type, node->InputAt(1));
1221 if (write_barrier_kind < access.write_barrier_kind) { 1554 if (write_barrier_kind < access.write_barrier_kind) {
1222 access.write_barrier_kind = write_barrier_kind; 1555 access.write_barrier_kind = write_barrier_kind;
1223 NodeProperties::ChangeOp( 1556 NodeProperties::ChangeOp(
1224 node, jsgraph_->simplified()->StoreField(access)); 1557 node, jsgraph_->simplified()->StoreField(access));
1225 } 1558 }
1226 } 1559 }
1227 break; 1560 return;
1228 } 1561 }
1229 case IrOpcode::kLoadBuffer: { 1562 case IrOpcode::kLoadBuffer: {
1230 BufferAccess access = BufferAccessOf(node->op()); 1563 BufferAccess access = BufferAccessOf(node->op());
1231 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer 1564 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer
1232 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset 1565 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset
1233 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length 1566 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length
1234 ProcessRemainingInputs(node, 3); 1567 ProcessRemainingInputs(node, 3);
1235 1568
1236 MachineRepresentation output; 1569 MachineRepresentation output;
1237 if (truncation.TruncatesUndefinedToZeroOrNaN()) { 1570 if (truncation.TruncatesUndefinedToZeroOrNaN()) {
(...skipping 12 matching lines...) Expand all
1250 output = MachineRepresentation::kFloat64; 1583 output = MachineRepresentation::kFloat64;
1251 } 1584 }
1252 } 1585 }
1253 } else { 1586 } else {
1254 // If undefined is not truncated away, we need to have the tagged 1587 // If undefined is not truncated away, we need to have the tagged
1255 // representation. 1588 // representation.
1256 output = MachineRepresentation::kTagged; 1589 output = MachineRepresentation::kTagged;
1257 } 1590 }
1258 SetOutput(node, output); 1591 SetOutput(node, output);
1259 if (lower()) lowering->DoLoadBuffer(node, output, changer_); 1592 if (lower()) lowering->DoLoadBuffer(node, output, changer_);
1260 break; 1593 return;
1261 } 1594 }
1262 case IrOpcode::kStoreBuffer: { 1595 case IrOpcode::kStoreBuffer: {
1263 BufferAccess access = BufferAccessOf(node->op()); 1596 BufferAccess access = BufferAccessOf(node->op());
1264 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer 1597 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer
1265 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset 1598 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset
1266 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length 1599 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length
1267 ProcessInput(node, 3, 1600 ProcessInput(node, 3,
1268 TruncatingUseInfoFromRepresentation( 1601 TruncatingUseInfoFromRepresentation(
1269 access.machine_type().representation())); // value 1602 access.machine_type().representation())); // value
1270 ProcessRemainingInputs(node, 4); 1603 ProcessRemainingInputs(node, 4);
1271 SetOutput(node, MachineRepresentation::kNone); 1604 SetOutput(node, MachineRepresentation::kNone);
1272 if (lower()) lowering->DoStoreBuffer(node); 1605 if (lower()) lowering->DoStoreBuffer(node);
1273 break; 1606 return;
1274 } 1607 }
1275 case IrOpcode::kLoadElement: { 1608 case IrOpcode::kLoadElement: {
1276 ElementAccess access = ElementAccessOf(node->op()); 1609 ElementAccess access = ElementAccessOf(node->op());
1277 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base 1610 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base
1278 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index 1611 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index
1279 ProcessRemainingInputs(node, 2); 1612 ProcessRemainingInputs(node, 2);
1280 SetOutput(node, access.machine_type.representation()); 1613 SetOutput(node, access.machine_type.representation());
1281 break; 1614 return;
1282 } 1615 }
1283 case IrOpcode::kStoreElement: { 1616 case IrOpcode::kStoreElement: {
1284 ElementAccess access = ElementAccessOf(node->op()); 1617 ElementAccess access = ElementAccessOf(node->op());
1285 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base 1618 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base
1286 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index 1619 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index
1287 ProcessInput(node, 2, 1620 ProcessInput(node, 2,
1288 TruncatingUseInfoFromRepresentation( 1621 TruncatingUseInfoFromRepresentation(
1289 access.machine_type.representation())); // value 1622 access.machine_type.representation())); // value
1290 ProcessRemainingInputs(node, 3); 1623 ProcessRemainingInputs(node, 3);
1291 SetOutput(node, MachineRepresentation::kNone); 1624 SetOutput(node, MachineRepresentation::kNone);
1292 if (lower()) { 1625 if (lower()) {
1293 WriteBarrierKind write_barrier_kind = WriteBarrierKindFor( 1626 WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
1294 access.base_is_tagged, access.machine_type.representation(), 1627 access.base_is_tagged, access.machine_type.representation(),
1295 access.type, node->InputAt(2)); 1628 access.type, node->InputAt(2));
1296 if (write_barrier_kind < access.write_barrier_kind) { 1629 if (write_barrier_kind < access.write_barrier_kind) {
1297 access.write_barrier_kind = write_barrier_kind; 1630 access.write_barrier_kind = write_barrier_kind;
1298 NodeProperties::ChangeOp( 1631 NodeProperties::ChangeOp(
1299 node, jsgraph_->simplified()->StoreElement(access)); 1632 node, jsgraph_->simplified()->StoreElement(access));
1300 } 1633 }
1301 } 1634 }
1302 break; 1635 return;
1303 } 1636 }
1304 case IrOpcode::kObjectIsCallable: 1637 case IrOpcode::kObjectIsCallable:
1305 case IrOpcode::kObjectIsNumber: 1638 case IrOpcode::kObjectIsNumber:
1306 case IrOpcode::kObjectIsReceiver: 1639 case IrOpcode::kObjectIsReceiver:
1307 case IrOpcode::kObjectIsSmi: 1640 case IrOpcode::kObjectIsSmi:
1308 case IrOpcode::kObjectIsString: 1641 case IrOpcode::kObjectIsString:
1309 case IrOpcode::kObjectIsUndetectable: { 1642 case IrOpcode::kObjectIsUndetectable: {
1310 ProcessInput(node, 0, UseInfo::AnyTagged()); 1643 ProcessInput(node, 0, UseInfo::AnyTagged());
1311 SetOutput(node, MachineRepresentation::kBit); 1644 SetOutput(node, MachineRepresentation::kBit);
1312 break; 1645 return;
1313 } 1646 }
1314 1647
1315 //------------------------------------------------------------------ 1648 //------------------------------------------------------------------
1316 // Machine-level operators. 1649 // Machine-level operators.
1317 //------------------------------------------------------------------ 1650 //------------------------------------------------------------------
1318 case IrOpcode::kLoad: { 1651 case IrOpcode::kLoad: {
1319 // TODO(jarin) Eventually, we should get rid of all machine stores 1652 // TODO(jarin) Eventually, we should get rid of all machine stores
1320 // from the high-level phases, then this becomes UNREACHABLE. 1653 // from the high-level phases, then this becomes UNREACHABLE.
1321 LoadRepresentation rep = LoadRepresentationOf(node->op()); 1654 LoadRepresentation rep = LoadRepresentationOf(node->op());
1322 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer 1655 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer
1323 ProcessInput(node, 1, UseInfo::PointerInt()); // index 1656 ProcessInput(node, 1, UseInfo::PointerInt()); // index
1324 ProcessRemainingInputs(node, 2); 1657 ProcessRemainingInputs(node, 2);
1325 SetOutput(node, rep.representation()); 1658 return SetOutput(node, rep.representation());
1326 break;
1327 } 1659 }
1328 case IrOpcode::kStore: { 1660 case IrOpcode::kStore: {
1329 // TODO(jarin) Eventually, we should get rid of all machine stores 1661 // TODO(jarin) Eventually, we should get rid of all machine stores
1330 // from the high-level phases, then this becomes UNREACHABLE. 1662 // from the high-level phases, then this becomes UNREACHABLE.
1331 StoreRepresentation rep = StoreRepresentationOf(node->op()); 1663 StoreRepresentation rep = StoreRepresentationOf(node->op());
1332 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer 1664 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer
1333 ProcessInput(node, 1, UseInfo::PointerInt()); // index 1665 ProcessInput(node, 1, UseInfo::PointerInt()); // index
1334 ProcessInput(node, 2, 1666 ProcessInput(node, 2,
1335 TruncatingUseInfoFromRepresentation(rep.representation())); 1667 TruncatingUseInfoFromRepresentation(rep.representation()));
1336 ProcessRemainingInputs(node, 3); 1668 ProcessRemainingInputs(node, 3);
1337 SetOutput(node, MachineRepresentation::kNone); 1669 return SetOutput(node, MachineRepresentation::kNone);
1338 break;
1339 } 1670 }
1340 case IrOpcode::kWord32Shr: 1671 case IrOpcode::kWord32Shr:
1341 // We output unsigned int32 for shift right because JavaScript. 1672 // We output unsigned int32 for shift right because JavaScript.
1342 return VisitBinop(node, UseInfo::TruncatingWord32(), 1673 return VisitBinop(node, UseInfo::TruncatingWord32(),
1343 MachineRepresentation::kWord32); 1674 MachineRepresentation::kWord32);
1344 case IrOpcode::kWord32And: 1675 case IrOpcode::kWord32And:
1345 case IrOpcode::kWord32Or: 1676 case IrOpcode::kWord32Or:
1346 case IrOpcode::kWord32Xor: 1677 case IrOpcode::kWord32Xor:
1347 case IrOpcode::kWord32Shl: 1678 case IrOpcode::kWord32Shl:
1348 case IrOpcode::kWord32Sar: 1679 case IrOpcode::kWord32Sar:
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1413 case IrOpcode::kChangeUint32ToUint64: 1744 case IrOpcode::kChangeUint32ToUint64:
1414 return VisitUnop(node, UseInfo::TruncatingWord32(), 1745 return VisitUnop(node, UseInfo::TruncatingWord32(),
1415 MachineRepresentation::kWord64); 1746 MachineRepresentation::kWord64);
1416 case IrOpcode::kTruncateFloat64ToFloat32: 1747 case IrOpcode::kTruncateFloat64ToFloat32:
1417 return VisitUnop(node, UseInfo::TruncatingFloat64(), 1748 return VisitUnop(node, UseInfo::TruncatingFloat64(),
1418 MachineRepresentation::kFloat32); 1749 MachineRepresentation::kFloat32);
1419 case IrOpcode::kTruncateFloat64ToWord32: 1750 case IrOpcode::kTruncateFloat64ToWord32:
1420 return VisitUnop(node, UseInfo::TruncatingFloat64(), 1751 return VisitUnop(node, UseInfo::TruncatingFloat64(),
1421 MachineRepresentation::kWord32); 1752 MachineRepresentation::kWord32);
1422 1753
1423 case IrOpcode::kChangeFloat32ToFloat64:
1424 UNREACHABLE();
1425 return VisitUnop(node, UseInfo::TruncatingFloat32(),
1426 MachineRepresentation::kFloat64);
1427 case IrOpcode::kChangeInt32ToFloat64: 1754 case IrOpcode::kChangeInt32ToFloat64:
1428 return VisitUnop(node, UseInfo::TruncatingWord32(), 1755 return VisitUnop(node, UseInfo::TruncatingWord32(),
1429 MachineRepresentation::kFloat64); 1756 MachineRepresentation::kFloat64);
1430 case IrOpcode::kChangeUint32ToFloat64: 1757 case IrOpcode::kChangeUint32ToFloat64:
1431 return VisitUnop(node, UseInfo::TruncatingWord32(), 1758 return VisitUnop(node, UseInfo::TruncatingWord32(),
1432 MachineRepresentation::kFloat64); 1759 MachineRepresentation::kFloat64);
1433 case IrOpcode::kFloat64Add: 1760 case IrOpcode::kFloat64Add:
1434 case IrOpcode::kFloat64Sub: 1761 case IrOpcode::kFloat64Sub:
1435 case IrOpcode::kFloat64Mul: 1762 case IrOpcode::kFloat64Mul:
1436 case IrOpcode::kFloat64Div: 1763 case IrOpcode::kFloat64Div:
(...skipping 19 matching lines...) Expand all
1456 case IrOpcode::kFloat64InsertLowWord32: 1783 case IrOpcode::kFloat64InsertLowWord32:
1457 case IrOpcode::kFloat64InsertHighWord32: 1784 case IrOpcode::kFloat64InsertHighWord32:
1458 return VisitBinop(node, UseInfo::TruncatingFloat64(), 1785 return VisitBinop(node, UseInfo::TruncatingFloat64(),
1459 UseInfo::TruncatingWord32(), 1786 UseInfo::TruncatingWord32(),
1460 MachineRepresentation::kFloat64); 1787 MachineRepresentation::kFloat64);
1461 case IrOpcode::kLoadStackPointer: 1788 case IrOpcode::kLoadStackPointer:
1462 case IrOpcode::kLoadFramePointer: 1789 case IrOpcode::kLoadFramePointer:
1463 case IrOpcode::kLoadParentFramePointer: 1790 case IrOpcode::kLoadParentFramePointer:
1464 return VisitLeaf(node, MachineType::PointerRepresentation()); 1791 return VisitLeaf(node, MachineType::PointerRepresentation());
1465 case IrOpcode::kStateValues: 1792 case IrOpcode::kStateValues:
1466 VisitStateValues(node); 1793 return VisitStateValues(node);
1467 break;
1468 1794
1469 // The following opcodes are not produced before representation 1795 // The following opcodes are not produced before representation
1470 // inference runs, so we do not have any real test coverage. 1796 // inference runs, so we do not have any real test coverage.
1471 // Simply fail here. 1797 // Simply fail here.
1472 case IrOpcode::kChangeFloat64ToInt32: 1798 case IrOpcode::kChangeFloat64ToInt32:
1473 case IrOpcode::kChangeFloat64ToUint32: 1799 case IrOpcode::kChangeFloat64ToUint32:
1474 case IrOpcode::kTruncateInt64ToInt32: 1800 case IrOpcode::kTruncateInt64ToInt32:
1801 case IrOpcode::kChangeFloat32ToFloat64:
1802 case IrOpcode::kCheckedUint32ToInt32:
1803 case IrOpcode::kCheckedFloat64ToInt32:
1804 case IrOpcode::kCheckedTaggedToInt32:
1805 case IrOpcode::kCheckedTaggedToFloat64:
1475 FATAL("Representation inference: unsupported opcodes."); 1806 FATAL("Representation inference: unsupported opcodes.");
1807 break;
1476 1808
1477 default: 1809 default:
1478 VisitInputs(node); 1810 VisitInputs(node);
1479 // Assume the output is tagged. 1811 // Assume the output is tagged.
1480 SetOutput(node, MachineRepresentation::kTagged); 1812 return SetOutput(node, MachineRepresentation::kTagged);
1481 break;
1482 } 1813 }
1814 UNREACHABLE();
1483 } 1815 }
1484 1816
1485 void DeferReplacement(Node* node, Node* replacement) { 1817 void DeferReplacement(Node* node, Node* replacement) {
1486 TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(), 1818 TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(),
1487 node->op()->mnemonic(), replacement->id(), 1819 node->op()->mnemonic(), replacement->id(),
1488 replacement->op()->mnemonic()); 1820 replacement->op()->mnemonic());
1489 1821
1490 if (replacement->id() < count_ && 1822 if (replacement->id() < count_ &&
1491 GetUpperBound(node)->Is(GetUpperBound(replacement))) { 1823 GetUpperBound(node)->Is(GetUpperBound(replacement)) &&
1824 TypeOf(node)->Is(TypeOf(replacement))) {
1492 // Replace with a previously existing node eagerly only if the type is the 1825 // Replace with a previously existing node eagerly only if the type is the
1493 // same. 1826 // same.
1494 node->ReplaceUses(replacement); 1827 node->ReplaceUses(replacement);
1495 } else { 1828 } else {
1496 // Otherwise, we are replacing a node with a representation change. 1829 // Otherwise, we are replacing a node with a representation change.
1497 // Such a substitution must be done after all lowering is done, because 1830 // Such a substitution must be done after all lowering is done, because
1498 // changing the type could confuse the representation change 1831 // changing the type could confuse the representation change
1499 // insertion for uses of the node. 1832 // insertion for uses of the node.
1500 replacements_.push_back(node); 1833 replacements_.push_back(node);
1501 replacements_.push_back(replacement); 1834 replacements_.push_back(replacement);
(...skipping 11 matching lines...) Expand all
1513 void PrintRepresentation(MachineRepresentation rep) { 1846 void PrintRepresentation(MachineRepresentation rep) {
1514 if (FLAG_trace_representation) { 1847 if (FLAG_trace_representation) {
1515 OFStream os(stdout); 1848 OFStream os(stdout);
1516 os << rep; 1849 os << rep;
1517 } 1850 }
1518 } 1851 }
1519 1852
1520 void PrintTruncation(Truncation truncation) { 1853 void PrintTruncation(Truncation truncation) {
1521 if (FLAG_trace_representation) { 1854 if (FLAG_trace_representation) {
1522 OFStream os(stdout); 1855 OFStream os(stdout);
1523 os << truncation.description(); 1856 os << truncation.description() << std::endl;
1524 } 1857 }
1525 } 1858 }
1526 1859
1527 void PrintUseInfo(UseInfo info) { 1860 void PrintUseInfo(UseInfo info) {
1528 if (FLAG_trace_representation) { 1861 if (FLAG_trace_representation) {
1529 OFStream os(stdout); 1862 OFStream os(stdout);
1530 os << info.preferred() << ":" << info.truncation().description(); 1863 os << info.representation() << ":" << info.truncation().description();
1531 } 1864 }
1532 } 1865 }
1533 1866
1534 private: 1867 private:
1535 JSGraph* jsgraph_; 1868 JSGraph* jsgraph_;
1869 Zone* zone_; // Temporary zone.
1536 size_t const count_; // number of nodes in the graph 1870 size_t const count_; // number of nodes in the graph
1537 ZoneVector<NodeInfo> info_; // node id -> usage information 1871 ZoneVector<NodeInfo> info_; // node id -> usage information
1538 #ifdef DEBUG 1872 #ifdef DEBUG
1539 ZoneVector<InputUseInfos> node_input_use_infos_; // Debug information about 1873 ZoneVector<InputUseInfos> node_input_use_infos_; // Debug information about
1540 // requirements on inputs. 1874 // requirements on inputs.
1541 #endif // DEBUG 1875 #endif // DEBUG
1542 NodeVector nodes_; // collected nodes 1876 NodeVector nodes_; // collected nodes
1543 NodeVector replacements_; // replacements to be done after lowering 1877 NodeVector replacements_; // replacements to be done after lowering
1544 Phase phase_; // current phase of algorithm 1878 Phase phase_; // current phase of algorithm
1545 RepresentationChanger* changer_; // for inserting representation changes 1879 RepresentationChanger* changer_; // for inserting representation changes
1546 ZoneQueue<Node*> queue_; // queue for traversing the graph 1880 ZoneQueue<Node*> queue_; // queue for traversing the graph
1881
1882 struct NodeState {
1883 Node* node;
1884 int input_index;
1885 };
1886 ZoneStack<NodeState> typing_stack_; // stack for graph typing.
1547 // TODO(danno): RepresentationSelector shouldn't know anything about the 1887 // TODO(danno): RepresentationSelector shouldn't know anything about the
1548 // source positions table, but must for now since there currently is no other 1888 // source positions table, but must for now since there currently is no other
1549 // way to pass down source position information to nodes created during 1889 // way to pass down source position information to nodes created during
1550 // lowering. Once this phase becomes a vanilla reducer, it should get source 1890 // lowering. Once this phase becomes a vanilla reducer, it should get source
1551 // position information via the SourcePositionWrapper like all other reducers. 1891 // position information via the SourcePositionWrapper like all other reducers.
1552 SourcePositionTable* source_positions_; 1892 SourcePositionTable* source_positions_;
1553 TypeCache const& type_cache_; 1893 TypeCache const& type_cache_;
1894 OperationTyper op_typer_; // helper for the feedback typer
1554 1895
1555 NodeInfo* GetInfo(Node* node) { 1896 NodeInfo* GetInfo(Node* node) {
1556 DCHECK(node->id() >= 0); 1897 DCHECK(node->id() >= 0);
1557 DCHECK(node->id() < count_); 1898 DCHECK(node->id() < count_);
1558 return &info_[node->id()]; 1899 return &info_[node->id()];
1559 } 1900 }
1901 Zone* zone() { return zone_; }
1902 Zone* graph_zone() { return jsgraph_->zone(); }
1560 }; 1903 };
1561 1904
1562
1563 SimplifiedLowering::SimplifiedLowering(JSGraph* jsgraph, Zone* zone, 1905 SimplifiedLowering::SimplifiedLowering(JSGraph* jsgraph, Zone* zone,
1564 SourcePositionTable* source_positions) 1906 SourcePositionTable* source_positions,
1907 Flags flags)
1565 : jsgraph_(jsgraph), 1908 : jsgraph_(jsgraph),
1566 zone_(zone), 1909 zone_(zone),
1567 type_cache_(TypeCache::Get()), 1910 type_cache_(TypeCache::Get()),
1911 flags_(flags),
1568 source_positions_(source_positions) {} 1912 source_positions_(source_positions) {}
1569 1913
1570
1571 void SimplifiedLowering::LowerAllNodes() { 1914 void SimplifiedLowering::LowerAllNodes() {
1572 RepresentationChanger changer(jsgraph(), jsgraph()->isolate()); 1915 RepresentationChanger changer(jsgraph(), jsgraph()->isolate());
1573 RepresentationSelector selector(jsgraph(), zone_, &changer, 1916 RepresentationSelector selector(jsgraph(), zone_, &changer,
1574 source_positions_); 1917 source_positions_);
1575 selector.Run(this); 1918 selector.Run(this);
1576 } 1919 }
1577 1920
1578 void SimplifiedLowering::DoJSToNumberTruncatesToFloat64( 1921 void SimplifiedLowering::DoJSToNumberTruncatesToFloat64(
1579 Node* node, RepresentationSelector* selector) { 1922 Node* node, RepresentationSelector* selector) {
1580 DCHECK_EQ(IrOpcode::kJSToNumber, node->opcode()); 1923 DCHECK_EQ(IrOpcode::kJSToNumber, node->opcode());
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1756 Node* check = graph()->NewNode(machine()->Uint32LessThan(), offset, length); 2099 Node* check = graph()->NewNode(machine()->Uint32LessThan(), offset, length);
1757 Node* branch = 2100 Node* branch =
1758 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); 2101 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
1759 2102
1760 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 2103 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1761 Node* etrue = graph()->NewNode(machine()->Load(access_type), buffer, index, 2104 Node* etrue = graph()->NewNode(machine()->Load(access_type), buffer, index,
1762 effect, if_true); 2105 effect, if_true);
1763 Type* element_type = 2106 Type* element_type =
1764 Type::Intersect(NodeProperties::GetType(node), Type::Number(), zone()); 2107 Type::Intersect(NodeProperties::GetType(node), Type::Number(), zone());
1765 Node* vtrue = changer->GetRepresentationFor( 2108 Node* vtrue = changer->GetRepresentationFor(
1766 etrue, access_type.representation(), element_type, output_rep, 2109 etrue, access_type.representation(), element_type, node,
1767 Truncation::None()); 2110 UseInfo(output_rep, Truncation::None()));
1768 2111
1769 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 2112 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1770 Node* efalse = effect; 2113 Node* efalse = effect;
1771 Node* vfalse; 2114 Node* vfalse;
1772 if (output_rep == MachineRepresentation::kTagged) { 2115 if (output_rep == MachineRepresentation::kTagged) {
1773 vfalse = jsgraph()->UndefinedConstant(); 2116 vfalse = jsgraph()->UndefinedConstant();
1774 } else if (output_rep == MachineRepresentation::kFloat64) { 2117 } else if (output_rep == MachineRepresentation::kFloat64) {
1775 vfalse = 2118 vfalse =
1776 jsgraph()->Float64Constant(std::numeric_limits<double>::quiet_NaN()); 2119 jsgraph()->Float64Constant(std::numeric_limits<double>::quiet_NaN());
1777 } else if (output_rep == MachineRepresentation::kFloat32) { 2120 } else if (output_rep == MachineRepresentation::kFloat32) {
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after
2471 isolate(), graph()->zone(), callable.descriptor(), 0, flags, 2814 isolate(), graph()->zone(), callable.descriptor(), 0, flags,
2472 Operator::kNoProperties); 2815 Operator::kNoProperties);
2473 to_number_operator_.set(common()->Call(desc)); 2816 to_number_operator_.set(common()->Call(desc));
2474 } 2817 }
2475 return to_number_operator_.get(); 2818 return to_number_operator_.get();
2476 } 2819 }
2477 2820
2478 } // namespace compiler 2821 } // namespace compiler
2479 } // namespace internal 2822 } // namespace internal
2480 } // namespace v8 2823 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | src/compiler/simplified-operator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698