OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 count_(jsgraph->graph()->NodeCount()), | 70 count_(jsgraph->graph()->NodeCount()), |
71 info_(zone->NewArray<NodeInfo>(count_)), | 71 info_(zone->NewArray<NodeInfo>(count_)), |
72 nodes_(zone), | 72 nodes_(zone), |
73 replacements_(zone), | 73 replacements_(zone), |
74 phase_(PROPAGATE), | 74 phase_(PROPAGATE), |
75 changer_(changer), | 75 changer_(changer), |
76 queue_(zone) { | 76 queue_(zone) { |
77 memset(info_, 0, sizeof(NodeInfo) * count_); | 77 memset(info_, 0, sizeof(NodeInfo) * count_); |
78 | 78 |
79 Factory* f = zone->isolate()->factory(); | 79 Factory* f = zone->isolate()->factory(); |
80 safe_bit_range_ = | |
81 Type::Union(Type::Boolean(), | |
82 Type::Range(f->NewNumber(0), f->NewNumber(1), zone), zone); | |
83 safe_int_additive_range_ = | 80 safe_int_additive_range_ = |
84 Type::Range(f->NewNumber(-std::pow(2.0, 52.0)), | 81 Type::Range(f->NewNumber(-std::pow(2.0, 52.0)), |
85 f->NewNumber(std::pow(2.0, 52.0)), zone); | 82 f->NewNumber(std::pow(2.0, 52.0)), zone); |
86 } | 83 } |
87 | 84 |
88 void Run(SimplifiedLowering* lowering) { | 85 void Run(SimplifiedLowering* lowering) { |
89 // Run propagation phase to a fixpoint. | 86 // Run propagation phase to a fixpoint. |
90 TRACE(("--{Propagation phase}--\n")); | 87 TRACE(("--{Propagation phase}--\n")); |
91 phase_ = PROPAGATE; | 88 phase_ = PROPAGATE; |
92 Enqueue(jsgraph_->graph()->end()); | 89 Enqueue(jsgraph_->graph()->end()); |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 // multiple uses, but we are within 32 bits range => pick kRepWord32. | 313 // multiple uses, but we are within 32 bits range => pick kRepWord32. |
317 return kRepWord32; | 314 return kRepWord32; |
318 } else if ((use & kRepMask) == kRepWord32 || | 315 } else if ((use & kRepMask) == kRepWord32 || |
319 (use & kTypeMask) == kTypeInt32 || | 316 (use & kTypeMask) == kTypeInt32 || |
320 (use & kTypeMask) == kTypeUint32) { | 317 (use & kTypeMask) == kTypeUint32) { |
321 // We only use 32 bits or we use the result consistently. | 318 // We only use 32 bits or we use the result consistently. |
322 return kRepWord32; | 319 return kRepWord32; |
323 } else { | 320 } else { |
324 return kRepFloat64; | 321 return kRepFloat64; |
325 } | 322 } |
326 } else if (IsSafeBitOperand(node)) { | 323 } else if (upper->Is(Type::Boolean())) { |
327 // multiple uses => pick kRepBit. | 324 // multiple uses => pick kRepBit. |
328 return kRepBit; | 325 return kRepBit; |
329 } else if (upper->Is(Type::Number())) { | 326 } else if (upper->Is(Type::Number())) { |
330 // multiple uses => pick kRepFloat64. | 327 // multiple uses => pick kRepFloat64. |
331 return kRepFloat64; | 328 return kRepFloat64; |
332 } | 329 } |
333 return kRepTagged; | 330 return kRepTagged; |
334 } | 331 } |
335 | 332 |
336 // Helper for handling selects. | 333 // Helper for handling selects. |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 } | 407 } |
411 | 408 |
412 const Operator* Float64Op(Node* node) { | 409 const Operator* Float64Op(Node* node) { |
413 return changer_->Float64OperatorFor(node->opcode()); | 410 return changer_->Float64OperatorFor(node->opcode()); |
414 } | 411 } |
415 | 412 |
416 bool CanLowerToInt32Binop(Node* node, MachineTypeUnion use) { | 413 bool CanLowerToInt32Binop(Node* node, MachineTypeUnion use) { |
417 return BothInputsAre(node, Type::Signed32()) && !CanObserveNonInt32(use); | 414 return BothInputsAre(node, Type::Signed32()) && !CanObserveNonInt32(use); |
418 } | 415 } |
419 | 416 |
420 bool IsSafeBitOperand(Node* node) { | |
421 Type* type = NodeProperties::GetBounds(node).upper; | |
422 return type->Is(safe_bit_range_); | |
423 } | |
424 | |
425 bool IsSafeIntAdditiveOperand(Node* node) { | 417 bool IsSafeIntAdditiveOperand(Node* node) { |
426 Type* type = NodeProperties::GetBounds(node).upper; | 418 Type* type = NodeProperties::GetBounds(node).upper; |
427 // TODO(jarin): Unfortunately, bitset types are not subtypes of larger | 419 // TODO(jarin): Unfortunately, bitset types are not subtypes of larger |
428 // range types, so we have to explicitly check for Integral32 here | 420 // range types, so we have to explicitly check for Integral32 here |
429 // (in addition to the safe integer range). Once we fix subtyping for | 421 // (in addition to the safe integer range). Once we fix subtyping for |
430 // ranges, we should simplify this. | 422 // ranges, we should simplify this. |
431 return type->Is(safe_int_additive_range_) || type->Is(Type::Integral32()); | 423 return type->Is(safe_int_additive_range_) || type->Is(Type::Integral32()); |
432 } | 424 } |
433 | 425 |
434 bool CanLowerToInt32AdditiveBinop(Node* node, MachineTypeUnion use) { | 426 bool CanLowerToInt32AdditiveBinop(Node* node, MachineTypeUnion use) { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 #define DEFINE_JS_CASE(x) case IrOpcode::k##x: | 515 #define DEFINE_JS_CASE(x) case IrOpcode::k##x: |
524 JS_OP_LIST(DEFINE_JS_CASE) | 516 JS_OP_LIST(DEFINE_JS_CASE) |
525 #undef DEFINE_JS_CASE | 517 #undef DEFINE_JS_CASE |
526 VisitInputs(node); | 518 VisitInputs(node); |
527 return SetOutput(node, kRepTagged); | 519 return SetOutput(node, kRepTagged); |
528 | 520 |
529 //------------------------------------------------------------------ | 521 //------------------------------------------------------------------ |
530 // Simplified operators. | 522 // Simplified operators. |
531 //------------------------------------------------------------------ | 523 //------------------------------------------------------------------ |
532 case IrOpcode::kAnyToBoolean: { | 524 case IrOpcode::kAnyToBoolean: { |
533 if (IsSafeBitOperand(node->InputAt(0))) { | 525 VisitUnop(node, kMachAnyTagged, kTypeBool | kRepTagged); |
534 VisitUnop(node, kRepBit, kRepBit); | 526 if (lower()) { |
535 if (lower()) DeferReplacement(node, node->InputAt(0)); | 527 // AnyToBoolean(x) => Call(ToBooleanStub, x, no-context) |
536 } else { | 528 Operator::Properties properties = node->op()->properties(); |
537 VisitUnop(node, kMachAnyTagged, kTypeBool | kRepTagged); | 529 Callable callable = CodeFactory::ToBoolean( |
538 if (lower()) { | 530 jsgraph_->isolate(), ToBooleanStub::RESULT_AS_ODDBALL); |
539 // AnyToBoolean(x) => Call(ToBooleanStub, x, no-context) | 531 CallDescriptor::Flags flags = CallDescriptor::kPatchableCallSite; |
540 Operator::Properties properties = node->op()->properties(); | 532 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
541 Callable callable = CodeFactory::ToBoolean( | 533 callable.descriptor(), 0, flags, properties, jsgraph_->zone()); |
542 jsgraph_->isolate(), ToBooleanStub::RESULT_AS_ODDBALL); | 534 node->set_op(jsgraph_->common()->Call(desc)); |
543 CallDescriptor::Flags flags = CallDescriptor::kPatchableCallSite; | 535 node->InsertInput(jsgraph_->zone(), 0, |
544 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 536 jsgraph_->HeapConstant(callable.code())); |
545 callable.descriptor(), 0, flags, properties, jsgraph_->zone()); | 537 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); |
546 node->set_op(jsgraph_->common()->Call(desc)); | |
547 node->InsertInput(jsgraph_->zone(), 0, | |
548 jsgraph_->HeapConstant(callable.code())); | |
549 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); | |
550 } | |
551 } | 538 } |
552 break; | 539 break; |
553 } | 540 } |
554 case IrOpcode::kBooleanNot: { | 541 case IrOpcode::kBooleanNot: { |
555 if (lower()) { | 542 if (lower()) { |
556 MachineTypeUnion input = GetInfo(node->InputAt(0))->output; | 543 MachineTypeUnion input = GetInfo(node->InputAt(0))->output; |
557 if (input & kRepBit) { | 544 if (input & kRepBit) { |
558 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) | 545 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) |
559 node->set_op(lowering->machine()->Word32Equal()); | 546 node->set_op(lowering->machine()->Word32Equal()); |
560 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); | 547 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1073 | 1060 |
1074 private: | 1061 private: |
1075 JSGraph* jsgraph_; | 1062 JSGraph* jsgraph_; |
1076 int count_; // number of nodes in the graph | 1063 int count_; // number of nodes in the graph |
1077 NodeInfo* info_; // node id -> usage information | 1064 NodeInfo* info_; // node id -> usage information |
1078 NodeVector nodes_; // collected nodes | 1065 NodeVector nodes_; // collected nodes |
1079 NodeVector replacements_; // replacements to be done after lowering | 1066 NodeVector replacements_; // replacements to be done after lowering |
1080 Phase phase_; // current phase of algorithm | 1067 Phase phase_; // current phase of algorithm |
1081 RepresentationChanger* changer_; // for inserting representation changes | 1068 RepresentationChanger* changer_; // for inserting representation changes |
1082 ZoneQueue<Node*> queue_; // queue for traversing the graph | 1069 ZoneQueue<Node*> queue_; // queue for traversing the graph |
1083 Type* safe_bit_range_; | |
1084 Type* safe_int_additive_range_; | 1070 Type* safe_int_additive_range_; |
1085 | 1071 |
1086 NodeInfo* GetInfo(Node* node) { | 1072 NodeInfo* GetInfo(Node* node) { |
1087 DCHECK(node->id() >= 0); | 1073 DCHECK(node->id() >= 0); |
1088 DCHECK(node->id() < count_); | 1074 DCHECK(node->id() < count_); |
1089 return &info_[node->id()]; | 1075 return &info_[node->id()]; |
1090 } | 1076 } |
1091 | 1077 |
1092 MachineTypeUnion GetUseInfo(Node* node) { return GetInfo(node)->use; } | 1078 MachineTypeUnion GetUseInfo(Node* node) { return GetInfo(node)->use; } |
1093 }; | 1079 }; |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1524 | 1510 |
1525 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { | 1511 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { |
1526 node->set_op(machine()->IntLessThanOrEqual()); | 1512 node->set_op(machine()->IntLessThanOrEqual()); |
1527 node->ReplaceInput(0, StringComparison(node, true)); | 1513 node->ReplaceInput(0, StringComparison(node, true)); |
1528 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1514 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
1529 } | 1515 } |
1530 | 1516 |
1531 } // namespace compiler | 1517 } // namespace compiler |
1532 } // namespace internal | 1518 } // namespace internal |
1533 } // namespace v8 | 1519 } // namespace v8 |
OLD | NEW |