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); |
80 safe_int_additive_range_ = | 83 safe_int_additive_range_ = |
81 Type::Range(f->NewNumber(-std::pow(2.0, 52.0)), | 84 Type::Range(f->NewNumber(-std::pow(2.0, 52.0)), |
82 f->NewNumber(std::pow(2.0, 52.0)), zone); | 85 f->NewNumber(std::pow(2.0, 52.0)), zone); |
83 } | 86 } |
84 | 87 |
85 void Run(SimplifiedLowering* lowering) { | 88 void Run(SimplifiedLowering* lowering) { |
86 // Run propagation phase to a fixpoint. | 89 // Run propagation phase to a fixpoint. |
87 TRACE(("--{Propagation phase}--\n")); | 90 TRACE(("--{Propagation phase}--\n")); |
88 phase_ = PROPAGATE; | 91 phase_ = PROPAGATE; |
89 Enqueue(jsgraph_->graph()->end()); | 92 Enqueue(jsgraph_->graph()->end()); |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 // multiple uses, but we are within 32 bits range => pick kRepWord32. | 316 // multiple uses, but we are within 32 bits range => pick kRepWord32. |
314 return kRepWord32; | 317 return kRepWord32; |
315 } else if ((use & kRepMask) == kRepWord32 || | 318 } else if ((use & kRepMask) == kRepWord32 || |
316 (use & kTypeMask) == kTypeInt32 || | 319 (use & kTypeMask) == kTypeInt32 || |
317 (use & kTypeMask) == kTypeUint32) { | 320 (use & kTypeMask) == kTypeUint32) { |
318 // The type is a safe integer, but we only use 32 bits. | 321 // The type is a safe integer, but we only use 32 bits. |
319 return kRepWord32; | 322 return kRepWord32; |
320 } else { | 323 } else { |
321 return kRepFloat64; | 324 return kRepFloat64; |
322 } | 325 } |
323 } else if (upper->Is(Type::Boolean())) { | 326 } else if (IsSafeBitOperand(node)) { |
324 // multiple uses => pick kRepBit. | 327 // multiple uses => pick kRepBit. |
325 return kRepBit; | 328 return kRepBit; |
326 } else if (upper->Is(Type::Number())) { | 329 } else if (upper->Is(Type::Number())) { |
327 // multiple uses => pick kRepFloat64. | 330 // multiple uses => pick kRepFloat64. |
328 return kRepFloat64; | 331 return kRepFloat64; |
329 } | 332 } |
330 return kRepTagged; | 333 return kRepTagged; |
331 } | 334 } |
332 | 335 |
333 // Helper for handling selects. | 336 // Helper for handling selects. |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 } | 410 } |
408 | 411 |
409 const Operator* Float64Op(Node* node) { | 412 const Operator* Float64Op(Node* node) { |
410 return changer_->Float64OperatorFor(node->opcode()); | 413 return changer_->Float64OperatorFor(node->opcode()); |
411 } | 414 } |
412 | 415 |
413 bool CanLowerToInt32Binop(Node* node, MachineTypeUnion use) { | 416 bool CanLowerToInt32Binop(Node* node, MachineTypeUnion use) { |
414 return BothInputsAre(node, Type::Signed32()) && !CanObserveNonInt32(use); | 417 return BothInputsAre(node, Type::Signed32()) && !CanObserveNonInt32(use); |
415 } | 418 } |
416 | 419 |
| 420 bool IsSafeBitOperand(Node* node) { |
| 421 Type* type = NodeProperties::GetBounds(node).upper; |
| 422 return type->Is(safe_bit_range_); |
| 423 } |
| 424 |
417 bool IsSafeIntAdditiveOperand(Node* node) { | 425 bool IsSafeIntAdditiveOperand(Node* node) { |
418 Type* type = NodeProperties::GetBounds(node).upper; | 426 Type* type = NodeProperties::GetBounds(node).upper; |
419 // TODO(jarin): Unfortunately, bitset types are not subtypes of larger | 427 // TODO(jarin): Unfortunately, bitset types are not subtypes of larger |
420 // range types, so we have to explicitly check for Integral32 here | 428 // range types, so we have to explicitly check for Integral32 here |
421 // (in addition to the safe integer range). Once we fix subtyping for | 429 // (in addition to the safe integer range). Once we fix subtyping for |
422 // ranges, we should simplify this. | 430 // ranges, we should simplify this. |
423 return type->Is(safe_int_additive_range_) || type->Is(Type::Integral32()); | 431 return type->Is(safe_int_additive_range_) || type->Is(Type::Integral32()); |
424 } | 432 } |
425 | 433 |
426 bool CanLowerToInt32AdditiveBinop(Node* node, MachineTypeUnion use) { | 434 bool CanLowerToInt32AdditiveBinop(Node* node, MachineTypeUnion use) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 // but that responsibility really lies in the typed lowering phase. | 522 // but that responsibility really lies in the typed lowering phase. |
515 #define DEFINE_JS_CASE(x) case IrOpcode::k##x: | 523 #define DEFINE_JS_CASE(x) case IrOpcode::k##x: |
516 JS_OP_LIST(DEFINE_JS_CASE) | 524 JS_OP_LIST(DEFINE_JS_CASE) |
517 #undef DEFINE_JS_CASE | 525 #undef DEFINE_JS_CASE |
518 VisitInputs(node); | 526 VisitInputs(node); |
519 return SetOutput(node, kRepTagged); | 527 return SetOutput(node, kRepTagged); |
520 | 528 |
521 //------------------------------------------------------------------ | 529 //------------------------------------------------------------------ |
522 // Simplified operators. | 530 // Simplified operators. |
523 //------------------------------------------------------------------ | 531 //------------------------------------------------------------------ |
| 532 case IrOpcode::kAnyToBoolean: { |
| 533 if (IsSafeBitOperand(node->InputAt(0))) { |
| 534 VisitUnop(node, kRepBit, kRepBit); |
| 535 if (lower()) DeferReplacement(node, node->InputAt(0)); |
| 536 } else { |
| 537 VisitUnop(node, kMachAnyTagged, kTypeBool | kRepTagged); |
| 538 if (lower()) { |
| 539 // AnyToBoolean(x) => Call(ToBooleanStub, x, no-context) |
| 540 Operator::Properties properties = node->op()->properties(); |
| 541 Callable callable = CodeFactory::ToBoolean( |
| 542 jsgraph_->isolate(), ToBooleanStub::RESULT_AS_ODDBALL); |
| 543 CallDescriptor::Flags flags = CallDescriptor::kPatchableCallSite; |
| 544 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 545 callable.descriptor(), 0, flags, properties, jsgraph_->zone()); |
| 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 } |
| 552 break; |
| 553 } |
524 case IrOpcode::kBooleanNot: { | 554 case IrOpcode::kBooleanNot: { |
525 if (lower()) { | 555 if (lower()) { |
526 MachineTypeUnion input = GetInfo(node->InputAt(0))->output; | 556 MachineTypeUnion input = GetInfo(node->InputAt(0))->output; |
527 if (input & kRepBit) { | 557 if (input & kRepBit) { |
528 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) | 558 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) |
529 node->set_op(lowering->machine()->Word32Equal()); | 559 node->set_op(lowering->machine()->Word32Equal()); |
530 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); | 560 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); |
531 } else { | 561 } else { |
532 // BooleanNot(x: kRepTagged) => WordEqual(x, #false) | 562 // BooleanNot(x: kRepTagged) => WordEqual(x, #false) |
533 node->set_op(lowering->machine()->WordEqual()); | 563 node->set_op(lowering->machine()->WordEqual()); |
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1027 | 1057 |
1028 private: | 1058 private: |
1029 JSGraph* jsgraph_; | 1059 JSGraph* jsgraph_; |
1030 int count_; // number of nodes in the graph | 1060 int count_; // number of nodes in the graph |
1031 NodeInfo* info_; // node id -> usage information | 1061 NodeInfo* info_; // node id -> usage information |
1032 NodeVector nodes_; // collected nodes | 1062 NodeVector nodes_; // collected nodes |
1033 NodeVector replacements_; // replacements to be done after lowering | 1063 NodeVector replacements_; // replacements to be done after lowering |
1034 Phase phase_; // current phase of algorithm | 1064 Phase phase_; // current phase of algorithm |
1035 RepresentationChanger* changer_; // for inserting representation changes | 1065 RepresentationChanger* changer_; // for inserting representation changes |
1036 ZoneQueue<Node*> queue_; // queue for traversing the graph | 1066 ZoneQueue<Node*> queue_; // queue for traversing the graph |
| 1067 Type* safe_bit_range_; |
1037 Type* safe_int_additive_range_; | 1068 Type* safe_int_additive_range_; |
1038 | 1069 |
1039 NodeInfo* GetInfo(Node* node) { | 1070 NodeInfo* GetInfo(Node* node) { |
1040 DCHECK(node->id() >= 0); | 1071 DCHECK(node->id() >= 0); |
1041 DCHECK(node->id() < count_); | 1072 DCHECK(node->id() < count_); |
1042 return &info_[node->id()]; | 1073 return &info_[node->id()]; |
1043 } | 1074 } |
1044 | 1075 |
1045 MachineTypeUnion GetUseInfo(Node* node) { return GetInfo(node)->use; } | 1076 MachineTypeUnion GetUseInfo(Node* node) { return GetInfo(node)->use; } |
1046 }; | 1077 }; |
1047 | 1078 |
1048 | 1079 |
1049 Node* SimplifiedLowering::IsTagged(Node* node) { | 1080 Node* SimplifiedLowering::IsTagged(Node* node) { |
1050 // TODO(titzer): factor this out to a TaggingScheme abstraction. | 1081 // TODO(titzer): factor this out to a TaggingScheme abstraction. |
1051 STATIC_ASSERT(kSmiTagMask == 1); // Only works if tag is the low bit. | 1082 STATIC_ASSERT(kSmiTagMask == 1); // Only works if tag is the low bit. |
1052 return graph()->NewNode(machine()->WordAnd(), node, | 1083 return graph()->NewNode(machine()->WordAnd(), node, |
1053 jsgraph()->Int32Constant(kSmiTagMask)); | 1084 jsgraph()->Int32Constant(kSmiTagMask)); |
1054 } | 1085 } |
1055 | 1086 |
1056 | 1087 |
1057 void SimplifiedLowering::LowerAllNodes() { | 1088 void SimplifiedLowering::LowerAllNodes() { |
1058 SimplifiedOperatorBuilder simplified(graph()->zone()); | 1089 SimplifiedOperatorBuilder simplified(graph()->zone()); |
1059 RepresentationChanger changer(jsgraph(), &simplified, | 1090 RepresentationChanger changer(jsgraph(), &simplified, |
1060 graph()->zone()->isolate()); | 1091 graph()->zone()->isolate()); |
1061 RepresentationSelector selector(jsgraph(), zone(), &changer); | 1092 RepresentationSelector selector(jsgraph(), zone_, &changer); |
1062 selector.Run(this); | 1093 selector.Run(this); |
1063 } | 1094 } |
1064 | 1095 |
1065 | 1096 |
1066 Node* SimplifiedLowering::Untag(Node* node) { | 1097 Node* SimplifiedLowering::Untag(Node* node) { |
1067 // TODO(titzer): factor this out to a TaggingScheme abstraction. | 1098 // TODO(titzer): factor this out to a TaggingScheme abstraction. |
1068 Node* shift_amount = jsgraph()->Int32Constant(kSmiTagSize + kSmiShiftSize); | 1099 Node* shift_amount = jsgraph()->Int32Constant(kSmiTagSize + kSmiShiftSize); |
1069 return graph()->NewNode(machine()->WordSar(), node, shift_amount); | 1100 return graph()->NewNode(machine()->WordSar(), node, shift_amount); |
1070 } | 1101 } |
1071 | 1102 |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1477 | 1508 |
1478 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { | 1509 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { |
1479 node->set_op(machine()->IntLessThanOrEqual()); | 1510 node->set_op(machine()->IntLessThanOrEqual()); |
1480 node->ReplaceInput(0, StringComparison(node, true)); | 1511 node->ReplaceInput(0, StringComparison(node, true)); |
1481 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1512 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
1482 } | 1513 } |
1483 | 1514 |
1484 } // namespace compiler | 1515 } // namespace compiler |
1485 } // namespace internal | 1516 } // namespace internal |
1486 } // namespace v8 | 1517 } // namespace v8 |
OLD | NEW |