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

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

Issue 1473733007: [turbofan] Checking monotonicity of representation inference outputs and inputs. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Tweaks Created 5 years 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/representation-change.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/simplified-lowering.h" 5 #include "src/compiler/simplified-lowering.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 147
148 UseInfo UseInfoForBasePointer(const FieldAccess& access) { 148 UseInfo UseInfoForBasePointer(const FieldAccess& access) {
149 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); 149 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt();
150 } 150 }
151 151
152 152
153 UseInfo UseInfoForBasePointer(const ElementAccess& access) { 153 UseInfo UseInfoForBasePointer(const ElementAccess& access) {
154 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); 154 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt();
155 } 155 }
156 156
157
158 #ifdef DEBUG
159 // Helpers for monotonicity checking.
160
161 bool MachineTypeIsSubtype(MachineType t1, MachineType t2) {
162 switch (t1) {
163 case kMachNone:
164 return true;
165 case kTypeBool:
166 return t2 == kTypeBool || t2 == kTypeNumber || t2 == kTypeAny;
167 case kTypeInt32:
168 return t2 == kTypeInt32 || t2 == kTypeNumber || t2 == kTypeAny;
169 case kTypeUint32:
170 return t2 == kTypeUint32 || t2 == kTypeNumber || t2 == kTypeAny;
171 case kTypeInt64:
172 return t2 == kTypeInt64;
173 case kTypeUint64:
174 return t2 == kTypeUint64;
175 case kTypeNumber:
176 return t2 == kTypeNumber || t2 == kTypeAny;
177 case kTypeAny:
178 return t2 == kTypeAny;
179 default:
180 break;
181 }
182 UNREACHABLE();
183 return false;
184 }
185
186
187 bool MachineRepresentationIsSubtype(MachineType r1, MachineType r2) {
188 switch (r1) {
189 case kMachNone:
190 return true;
191 case kRepBit:
192 return r2 == kRepBit || r2 == kRepTagged;
193 case kRepWord8:
194 return r2 == kRepWord8 || r2 == kRepWord16 || r2 == kRepWord32 ||
195 r2 == kRepWord64 || r2 == kRepFloat32 || r2 == kRepFloat64 ||
196 r2 == kRepTagged;
197 case kRepWord16:
198 return r2 == kRepWord16 || r2 == kRepWord32 || r2 == kRepWord64 ||
199 r2 == kRepFloat32 || r2 == kRepFloat64 || r2 == kRepTagged;
200 case kRepWord32:
201 return r2 == kRepWord32 || r2 == kRepWord64 || r2 == kRepFloat64 ||
202 r2 == kRepTagged;
203 case kRepWord64:
204 return r2 == kRepWord64;
205 case kRepFloat32:
206 return r2 == kRepFloat32 || r2 == kRepFloat64 || r2 == kRepTagged;
207 case kRepFloat64:
208 return r2 == kRepFloat64 || r2 == kRepTagged;
209 case kRepTagged:
210 return r2 == kRepTagged;
211 default:
212 break;
213 }
214 UNREACHABLE();
215 return false;
216 }
217
218
219 bool MachineTypeRepIsSubtype(MachineTypeUnion m1, MachineTypeUnion m2) {
220 return MachineTypeIsSubtype(static_cast<MachineType>(m1 & kTypeMask),
221 static_cast<MachineType>(m2 & kTypeMask)) &&
222 MachineRepresentationIsSubtype(
223 static_cast<MachineType>(m1 & kRepMask),
224 static_cast<MachineType>(m2 & kRepMask));
225 }
226
227
228 class InputUseInfos {
229 public:
230 explicit InputUseInfos(Zone* zone) : input_use_infos_(zone) {}
231
232 void SetAndCheckInput(Node* node, int index, UseInfo use_info) {
233 if (input_use_infos_.empty()) {
234 input_use_infos_.resize(node->InputCount(), UseInfo::None());
235 }
236 // Check that the new use informatin is a super-type of the old
237 // one.
238 CHECK(IsUseLessGeneral(input_use_infos_[index], use_info));
239 input_use_infos_[index] = use_info;
240 }
241
242 private:
243 ZoneVector<UseInfo> input_use_infos_;
244
245 static bool IsUseLessGeneral(UseInfo use1, UseInfo use2) {
246 return MachineRepresentationIsSubtype(use1.preferred(), use2.preferred()) &&
247 use1.truncation().IsLessGeneralThan(use2.truncation());
248 }
249 };
250
251 #endif // DEBUG
252
157 } // namespace 253 } // namespace
158 254
159 255
160 class RepresentationSelector { 256 class RepresentationSelector {
161 public: 257 public:
162 // Information for each node tracked during the fixpoint. 258 // Information for each node tracked during the fixpoint.
163 class NodeInfo { 259 class NodeInfo {
164 public: 260 public:
165 // Adds new use to the node. Returns true if something has changed 261 // Adds new use to the node. Returns true if something has changed
166 // and the node has to be requeued. 262 // and the node has to be requeued.
(...skipping 17 matching lines...) Expand all
184 MachineTypeUnion output_ = kMachNone; // Output type of the node. 280 MachineTypeUnion output_ = kMachNone; // Output type of the node.
185 Truncation truncation_ = Truncation::None(); // Information about uses. 281 Truncation truncation_ = Truncation::None(); // Information about uses.
186 }; 282 };
187 283
188 RepresentationSelector(JSGraph* jsgraph, Zone* zone, 284 RepresentationSelector(JSGraph* jsgraph, Zone* zone,
189 RepresentationChanger* changer, 285 RepresentationChanger* changer,
190 SourcePositionTable* source_positions) 286 SourcePositionTable* source_positions)
191 : jsgraph_(jsgraph), 287 : jsgraph_(jsgraph),
192 count_(jsgraph->graph()->NodeCount()), 288 count_(jsgraph->graph()->NodeCount()),
193 info_(count_, zone), 289 info_(count_, zone),
290 #ifdef DEBUG
291 node_input_use_infos_(count_, InputUseInfos(zone), zone),
292 #endif
194 nodes_(zone), 293 nodes_(zone),
195 replacements_(zone), 294 replacements_(zone),
196 phase_(PROPAGATE), 295 phase_(PROPAGATE),
197 changer_(changer), 296 changer_(changer),
198 queue_(zone), 297 queue_(zone),
199 source_positions_(source_positions), 298 source_positions_(source_positions),
200 type_cache_(TypeCache::Get()) {} 299 type_cache_(TypeCache::Get()) {
300 }
201 301
202 void Run(SimplifiedLowering* lowering) { 302 void Run(SimplifiedLowering* lowering) {
203 // Run propagation phase to a fixpoint. 303 // Run propagation phase to a fixpoint.
204 TRACE("--{Propagation phase}--\n"); 304 TRACE("--{Propagation phase}--\n");
205 phase_ = PROPAGATE; 305 phase_ = PROPAGATE;
206 Enqueue(jsgraph_->graph()->end()); 306 EnqueueInitial(jsgraph_->graph()->end());
207 // Process nodes from the queue until it is empty. 307 // Process nodes from the queue until it is empty.
208 while (!queue_.empty()) { 308 while (!queue_.empty()) {
209 Node* node = queue_.front(); 309 Node* node = queue_.front();
210 NodeInfo* info = GetInfo(node); 310 NodeInfo* info = GetInfo(node);
211 queue_.pop(); 311 queue_.pop();
212 info->set_queued(false); 312 info->set_queued(false);
213 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic()); 313 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
214 VisitNode(node, info->truncation(), NULL); 314 VisitNode(node, info->truncation(), NULL);
215 TRACE(" ==> output "); 315 TRACE(" ==> output ");
216 PrintInfo(info->output_type()); 316 PrintInfo(info->output_type());
(...skipping 21 matching lines...) Expand all
238 Node* replacement = *(++i); 338 Node* replacement = *(++i);
239 node->ReplaceUses(replacement); 339 node->ReplaceUses(replacement);
240 // We also need to replace the node in the rest of the vector. 340 // We also need to replace the node in the rest of the vector.
241 for (NodeVector::iterator j = i + 1; j != replacements_.end(); ++j) { 341 for (NodeVector::iterator j = i + 1; j != replacements_.end(); ++j) {
242 ++j; 342 ++j;
243 if (*j == node) *j = replacement; 343 if (*j == node) *j = replacement;
244 } 344 }
245 } 345 }
246 } 346 }
247 347
248 // Enqueue {node} if the {use} contains new information for that node. 348 void EnqueueInitial(Node* node) {
249 // Add {node} to {nodes_} if this is the first time it's been visited. 349 NodeInfo* info = GetInfo(node);
250 void Enqueue(Node* node, UseInfo use_info = UseInfo::None()) { 350 info->set_visited();
351 info->set_queued(true);
352 nodes_.push_back(node);
353 queue_.push(node);
354 }
355
356 // Enqueue {use_node}'s {index} input if the {use} contains new information
357 // for that input node. Add the input to {nodes_} if this is the first time
358 // it's been visited.
359 void EnqueueInput(Node* use_node, int index,
360 UseInfo use_info = UseInfo::None()) {
361 Node* node = use_node->InputAt(index);
251 if (phase_ != PROPAGATE) return; 362 if (phase_ != PROPAGATE) return;
252 NodeInfo* info = GetInfo(node); 363 NodeInfo* info = GetInfo(node);
364 #ifdef DEBUG
365 // Check monotonicity of input requirements.
366 node_input_use_infos_[use_node->id()].SetAndCheckInput(use_node, index,
367 use_info);
368 #endif // DEBUG
253 if (!info->visited()) { 369 if (!info->visited()) {
254 // First visit of this node. 370 // First visit of this node.
255 info->set_visited(); 371 info->set_visited();
256 info->set_queued(true); 372 info->set_queued(true);
257 nodes_.push_back(node); 373 nodes_.push_back(node);
258 queue_.push(node); 374 queue_.push(node);
259 TRACE(" initial: "); 375 TRACE(" initial: ");
260 info->AddUse(use_info); 376 info->AddUse(use_info);
261 PrintTruncation(info->truncation()); 377 PrintTruncation(info->truncation());
262 return; 378 return;
(...skipping 14 matching lines...) Expand all
277 } 393 }
278 394
279 bool lower() { return phase_ == LOWER; } 395 bool lower() { return phase_ == LOWER; }
280 396
281 void SetOutput(Node* node, MachineTypeUnion output) { 397 void SetOutput(Node* node, MachineTypeUnion output) {
282 // Every node should have at most one output representation. Note that 398 // Every node should have at most one output representation. Note that
283 // phis can have 0, if they have not been used in a representation-inducing 399 // phis can have 0, if they have not been used in a representation-inducing
284 // instruction. 400 // instruction.
285 DCHECK((output & kRepMask) == 0 || 401 DCHECK((output & kRepMask) == 0 ||
286 base::bits::IsPowerOfTwo32(output & kRepMask)); 402 base::bits::IsPowerOfTwo32(output & kRepMask));
287 GetInfo(node)->set_output_type(output); 403 NodeInfo* info = GetInfo(node);
404 DCHECK(MachineTypeRepIsSubtype(info->output_type(), output));
405 info->set_output_type(output);
288 } 406 }
289 407
290 bool BothInputsAre(Node* node, Type* type) { 408 bool BothInputsAre(Node* node, Type* type) {
291 DCHECK_EQ(2, node->InputCount()); 409 DCHECK_EQ(2, node->InputCount());
292 return NodeProperties::GetType(node->InputAt(0))->Is(type) && 410 return NodeProperties::GetType(node->InputAt(0))->Is(type) &&
293 NodeProperties::GetType(node->InputAt(1))->Is(type); 411 NodeProperties::GetType(node->InputAt(1))->Is(type);
294 } 412 }
295 413
296 void EnqueueInputUse(Node* node, int index, UseInfo use) {
297 Enqueue(node->InputAt(index), use);
298 }
299
300 void ConvertInput(Node* node, int index, UseInfo use) { 414 void ConvertInput(Node* node, int index, UseInfo use) {
301 Node* input = node->InputAt(index); 415 Node* input = node->InputAt(index);
302 // In the change phase, insert a change before the use if necessary. 416 // In the change phase, insert a change before the use if necessary.
303 if (use.preferred() == kMachNone) 417 if (use.preferred() == kMachNone)
304 return; // No input requirement on the use. 418 return; // No input requirement on the use.
305 MachineTypeUnion output = GetInfo(input)->output_type(); 419 MachineTypeUnion output = GetInfo(input)->output_type();
306 if ((output & kRepMask) != use.preferred()) { 420 if ((output & kRepMask) != use.preferred()) {
307 // Output representation doesn't match usage. 421 // Output representation doesn't match usage.
308 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(), 422 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(),
309 index, input->id(), input->op()->mnemonic()); 423 index, input->id(), input->op()->mnemonic());
310 TRACE(" from "); 424 TRACE(" from ");
311 PrintInfo(output); 425 PrintInfo(output);
312 TRACE(" to "); 426 TRACE(" to ");
313 PrintUseInfo(use); 427 PrintUseInfo(use);
314 TRACE("\n"); 428 TRACE("\n");
315 Node* n = changer_->GetRepresentationFor(input, output, use.preferred(), 429 Node* n = changer_->GetRepresentationFor(input, output, use.preferred(),
316 use.truncation()); 430 use.truncation());
317 node->ReplaceInput(index, n); 431 node->ReplaceInput(index, n);
318 } 432 }
319 } 433 }
320 434
321 void ProcessInput(Node* node, int index, UseInfo use) { 435 void ProcessInput(Node* node, int index, UseInfo use) {
322 if (phase_ == PROPAGATE) { 436 if (phase_ == PROPAGATE) {
323 EnqueueInputUse(node, index, use); 437 EnqueueInput(node, index, use);
324 } else { 438 } else {
325 ConvertInput(node, index, use); 439 ConvertInput(node, index, use);
326 } 440 }
327 } 441 }
328 442
329 void ProcessRemainingInputs(Node* node, int index) { 443 void ProcessRemainingInputs(Node* node, int index) {
330 DCHECK_GE(index, NodeProperties::PastValueIndex(node)); 444 DCHECK_GE(index, NodeProperties::PastValueIndex(node));
331 DCHECK_GE(index, NodeProperties::PastContextIndex(node)); 445 DCHECK_GE(index, NodeProperties::PastContextIndex(node));
332 for (int i = std::max(index, NodeProperties::FirstEffectIndex(node)); 446 for (int i = std::max(index, NodeProperties::FirstEffectIndex(node));
333 i < NodeProperties::PastEffectIndex(node); ++i) { 447 i < NodeProperties::PastEffectIndex(node); ++i) {
334 Enqueue(node->InputAt(i)); // Effect inputs: just visit 448 EnqueueInput(node, i); // Effect inputs: just visit
335 } 449 }
336 for (int i = std::max(index, NodeProperties::FirstControlIndex(node)); 450 for (int i = std::max(index, NodeProperties::FirstControlIndex(node));
337 i < NodeProperties::PastControlIndex(node); ++i) { 451 i < NodeProperties::PastControlIndex(node); ++i) {
338 Enqueue(node->InputAt(i)); // Control inputs: just visit 452 EnqueueInput(node, i); // Control inputs: just visit
339 } 453 }
340 } 454 }
341 455
342 // The default, most general visitation case. For {node}, process all value, 456 // The default, most general visitation case. For {node}, process all value,
343 // context, frame state, effect, and control inputs, assuming that value 457 // context, frame state, effect, and control inputs, assuming that value
344 // inputs should have {kRepTagged} representation and can observe all output 458 // inputs should have {kRepTagged} representation and can observe all output
345 // values {kTypeAny}. 459 // values {kTypeAny}.
346 void VisitInputs(Node* node) { 460 void VisitInputs(Node* node) {
347 int tagged_count = node->op()->ValueInputCount() + 461 int tagged_count = node->op()->ValueInputCount() +
348 OperatorProperties::GetContextInputCount(node->op()); 462 OperatorProperties::GetContextInputCount(node->op());
349 // Visit value and context inputs as tagged. 463 // Visit value and context inputs as tagged.
350 for (int i = 0; i < tagged_count; i++) { 464 for (int i = 0; i < tagged_count; i++) {
351 ProcessInput(node, i, UseInfo::AnyTagged()); 465 ProcessInput(node, i, UseInfo::AnyTagged());
352 } 466 }
353 // Only enqueue other inputs (framestates, effects, control). 467 // Only enqueue other inputs (framestates, effects, control).
354 for (int i = tagged_count; i < node->InputCount(); i++) { 468 for (int i = tagged_count; i < node->InputCount(); i++) {
355 Enqueue(node->InputAt(i)); 469 EnqueueInput(node, i);
356 } 470 }
357 // Assume the output is tagged.
358 SetOutput(node, kMachAnyTagged);
359 } 471 }
360 472
361 // Helper for binops of the R x L -> O variety. 473 // Helper for binops of the R x L -> O variety.
362 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, 474 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use,
363 MachineTypeUnion output) { 475 MachineTypeUnion output) {
364 DCHECK_EQ(2, node->op()->ValueInputCount()); 476 DCHECK_EQ(2, node->op()->ValueInputCount());
365 ProcessInput(node, 0, left_use); 477 ProcessInput(node, 0, left_use);
366 ProcessInput(node, 1, right_use); 478 ProcessInput(node, 1, right_use);
367 for (int i = 2; i < node->InputCount(); i++) { 479 for (int i = 2; i < node->InputCount(); i++) {
368 Enqueue(node->InputAt(i)); 480 EnqueueInput(node, i);
369 } 481 }
370 SetOutput(node, output); 482 SetOutput(node, output);
371 } 483 }
372 484
373 // Helper for binops of the I x I -> O variety. 485 // Helper for binops of the I x I -> O variety.
374 void VisitBinop(Node* node, UseInfo input_use, MachineTypeUnion output) { 486 void VisitBinop(Node* node, UseInfo input_use, MachineTypeUnion output) {
375 VisitBinop(node, input_use, input_use, output); 487 VisitBinop(node, input_use, input_use, output);
376 } 488 }
377 489
378 // Helper for unops of the I -> O variety. 490 // Helper for unops of the I -> O variety.
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 if (sig->return_count() > 0) { 628 if (sig->return_count() > 0) {
517 SetOutput(node, desc->GetMachineSignature()->GetReturn()); 629 SetOutput(node, desc->GetMachineSignature()->GetReturn());
518 } else { 630 } else {
519 SetOutput(node, kMachAnyTagged); 631 SetOutput(node, kMachAnyTagged);
520 } 632 }
521 } 633 }
522 634
523 void VisitStateValues(Node* node) { 635 void VisitStateValues(Node* node) {
524 if (phase_ == PROPAGATE) { 636 if (phase_ == PROPAGATE) {
525 for (int i = 0; i < node->InputCount(); i++) { 637 for (int i = 0; i < node->InputCount(); i++) {
526 Enqueue(node->InputAt(i), UseInfo::Any()); 638 EnqueueInput(node, i, UseInfo::Any());
527 } 639 }
528 } else { 640 } else {
529 Zone* zone = jsgraph_->zone(); 641 Zone* zone = jsgraph_->zone();
530 ZoneVector<MachineType>* types = 642 ZoneVector<MachineType>* types =
531 new (zone->New(sizeof(ZoneVector<MachineType>))) 643 new (zone->New(sizeof(ZoneVector<MachineType>)))
532 ZoneVector<MachineType>(node->InputCount(), zone); 644 ZoneVector<MachineType>(node->InputCount(), zone);
533 for (int i = 0; i < node->InputCount(); i++) { 645 for (int i = 0; i < node->InputCount(); i++) {
534 MachineTypeUnion input_type = GetInfo(node->InputAt(i))->output_type(); 646 MachineTypeUnion input_type = GetInfo(node->InputAt(i))->output_type();
535 (*types)[i] = static_cast<MachineType>(input_type); 647 (*types)[i] = static_cast<MachineType>(input_type);
536 } 648 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 return VisitLeaf(node, kRepFloat64); 718 return VisitLeaf(node, kRepFloat64);
607 case IrOpcode::kExternalConstant: 719 case IrOpcode::kExternalConstant:
608 return VisitLeaf(node, kMachPtr); 720 return VisitLeaf(node, kMachPtr);
609 case IrOpcode::kNumberConstant: 721 case IrOpcode::kNumberConstant:
610 return VisitLeaf(node, kRepTagged); 722 return VisitLeaf(node, kRepTagged);
611 case IrOpcode::kHeapConstant: 723 case IrOpcode::kHeapConstant:
612 return VisitLeaf(node, kRepTagged); 724 return VisitLeaf(node, kRepTagged);
613 725
614 case IrOpcode::kBranch: 726 case IrOpcode::kBranch:
615 ProcessInput(node, 0, UseInfo::Bool()); 727 ProcessInput(node, 0, UseInfo::Bool());
616 Enqueue(NodeProperties::GetControlInput(node, 0)); 728 EnqueueInput(node, NodeProperties::FirstControlIndex(node));
617 break; 729 break;
618 case IrOpcode::kSwitch: 730 case IrOpcode::kSwitch:
619 ProcessInput(node, 0, UseInfo::TruncatingWord32()); 731 ProcessInput(node, 0, UseInfo::TruncatingWord32());
620 Enqueue(NodeProperties::GetControlInput(node, 0)); 732 EnqueueInput(node, NodeProperties::FirstControlIndex(node));
621 break; 733 break;
622 case IrOpcode::kSelect: 734 case IrOpcode::kSelect:
623 return VisitSelect(node, truncation, lowering); 735 return VisitSelect(node, truncation, lowering);
624 case IrOpcode::kPhi: 736 case IrOpcode::kPhi:
625 return VisitPhi(node, truncation, lowering); 737 return VisitPhi(node, truncation, lowering);
626 case IrOpcode::kCall: 738 case IrOpcode::kCall:
627 return VisitCall(node, lowering); 739 return VisitCall(node, lowering);
628 740
629 //------------------------------------------------------------------ 741 //------------------------------------------------------------------
630 // JavaScript operators. 742 // JavaScript operators.
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
1097 return VisitBinop(node, UseInfo::Float64(), UseInfo::TruncatingWord32(), 1209 return VisitBinop(node, UseInfo::Float64(), UseInfo::TruncatingWord32(),
1098 kMachFloat64); 1210 kMachFloat64);
1099 case IrOpcode::kLoadStackPointer: 1211 case IrOpcode::kLoadStackPointer:
1100 case IrOpcode::kLoadFramePointer: 1212 case IrOpcode::kLoadFramePointer:
1101 return VisitLeaf(node, kMachPtr); 1213 return VisitLeaf(node, kMachPtr);
1102 case IrOpcode::kStateValues: 1214 case IrOpcode::kStateValues:
1103 VisitStateValues(node); 1215 VisitStateValues(node);
1104 break; 1216 break;
1105 default: 1217 default:
1106 VisitInputs(node); 1218 VisitInputs(node);
1219 // Assume the output is tagged.
1220 SetOutput(node, kMachAnyTagged);
1107 break; 1221 break;
1108 } 1222 }
1109 } 1223 }
1110 1224
1111 void DeferReplacement(Node* node, Node* replacement) { 1225 void DeferReplacement(Node* node, Node* replacement) {
1112 TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(), 1226 TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(),
1113 node->op()->mnemonic(), replacement->id(), 1227 node->op()->mnemonic(), replacement->id(),
1114 replacement->op()->mnemonic()); 1228 replacement->op()->mnemonic());
1115 1229
1116 if (replacement->id() < count_ && 1230 if (replacement->id() < count_ &&
(...skipping 30 matching lines...) Expand all
1147 if (FLAG_trace_representation) { 1261 if (FLAG_trace_representation) {
1148 OFStream os(stdout); 1262 OFStream os(stdout);
1149 os << info.preferred() << ":" << info.truncation().description(); 1263 os << info.preferred() << ":" << info.truncation().description();
1150 } 1264 }
1151 } 1265 }
1152 1266
1153 private: 1267 private:
1154 JSGraph* jsgraph_; 1268 JSGraph* jsgraph_;
1155 size_t const count_; // number of nodes in the graph 1269 size_t const count_; // number of nodes in the graph
1156 ZoneVector<NodeInfo> info_; // node id -> usage information 1270 ZoneVector<NodeInfo> info_; // node id -> usage information
1271 #ifdef DEBUG
1272 ZoneVector<InputUseInfos> node_input_use_infos_; // Debug information about
1273 // requirements on inputs.
1274 #endif // DEBUG
1157 NodeVector nodes_; // collected nodes 1275 NodeVector nodes_; // collected nodes
1158 NodeVector replacements_; // replacements to be done after lowering 1276 NodeVector replacements_; // replacements to be done after lowering
1159 Phase phase_; // current phase of algorithm 1277 Phase phase_; // current phase of algorithm
1160 RepresentationChanger* changer_; // for inserting representation changes 1278 RepresentationChanger* changer_; // for inserting representation changes
1161 ZoneQueue<Node*> queue_; // queue for traversing the graph 1279 ZoneQueue<Node*> queue_; // queue for traversing the graph
1162 // TODO(danno): RepresentationSelector shouldn't know anything about the 1280 // TODO(danno): RepresentationSelector shouldn't know anything about the
1163 // source positions table, but must for now since there currently is no other 1281 // source positions table, but must for now since there currently is no other
1164 // way to pass down source position information to nodes created during 1282 // way to pass down source position information to nodes created during
1165 // lowering. Once this phase becomes a vanilla reducer, it should get source 1283 // lowering. Once this phase becomes a vanilla reducer, it should get source
1166 // position information via the SourcePositionWrapper like all other reducers. 1284 // position information via the SourcePositionWrapper like all other reducers.
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
1610 ReplaceEffectUses(node, comparison); 1728 ReplaceEffectUses(node, comparison);
1611 node->ReplaceInput(0, comparison); 1729 node->ReplaceInput(0, comparison);
1612 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); 1730 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
1613 node->TrimInputCount(2); 1731 node->TrimInputCount(2);
1614 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); 1732 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual());
1615 } 1733 }
1616 1734
1617 } // namespace compiler 1735 } // namespace compiler
1618 } // namespace internal 1736 } // namespace internal
1619 } // namespace v8 1737 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/representation-change.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698