Index: src/compiler/simplified-lowering.cc |
diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc |
index bb5761469d144acc64748ec3224e650f44dac5a5..5f9a406b649dec5a6b0336cffcf7bc29dde16212 100644 |
--- a/src/compiler/simplified-lowering.cc |
+++ b/src/compiler/simplified-lowering.cc |
@@ -77,6 +77,9 @@ class RepresentationSelector { |
memset(info_, 0, sizeof(NodeInfo) * count_); |
Factory* f = zone->isolate()->factory(); |
+ safe_bit_range_ = |
+ Type::Union(Type::Boolean(), |
+ Type::Range(f->NewNumber(0), f->NewNumber(1), zone), zone); |
safe_int_additive_range_ = |
Type::Range(f->NewNumber(-std::pow(2.0, 52.0)), |
f->NewNumber(std::pow(2.0, 52.0)), zone); |
@@ -320,7 +323,7 @@ class RepresentationSelector { |
} else { |
return kRepFloat64; |
} |
- } else if (upper->Is(Type::Boolean())) { |
+ } else if (IsSafeBitOperand(node)) { |
// multiple uses => pick kRepBit. |
return kRepBit; |
} else if (upper->Is(Type::Number())) { |
@@ -414,6 +417,11 @@ class RepresentationSelector { |
return BothInputsAre(node, Type::Signed32()) && !CanObserveNonInt32(use); |
} |
+ bool IsSafeBitOperand(Node* node) { |
+ Type* type = NodeProperties::GetBounds(node).upper; |
+ return type->Is(safe_bit_range_); |
+ } |
+ |
bool IsSafeIntAdditiveOperand(Node* node) { |
Type* type = NodeProperties::GetBounds(node).upper; |
// TODO(jarin): Unfortunately, bitset types are not subtypes of larger |
@@ -521,6 +529,28 @@ class RepresentationSelector { |
//------------------------------------------------------------------ |
// Simplified operators. |
//------------------------------------------------------------------ |
+ case IrOpcode::kAnyToBoolean: { |
+ if (IsSafeBitOperand(node->InputAt(0))) { |
+ VisitUnop(node, kRepBit, kRepBit); |
+ if (lower()) DeferReplacement(node, node->InputAt(0)); |
+ } else { |
+ VisitUnop(node, kMachAnyTagged, kTypeBool | kRepTagged); |
+ if (lower()) { |
+ // AnyToBoolean(x) => Call(ToBooleanStub, x, no-context) |
+ Operator::Properties properties = node->op()->properties(); |
+ Callable callable = CodeFactory::ToBoolean( |
+ jsgraph_->isolate(), ToBooleanStub::RESULT_AS_ODDBALL); |
+ CallDescriptor::Flags flags = CallDescriptor::kPatchableCallSite; |
+ CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
+ callable.descriptor(), 0, flags, properties, jsgraph_->zone()); |
+ node->set_op(jsgraph_->common()->Call(desc)); |
+ node->InsertInput(jsgraph_->zone(), 0, |
+ jsgraph_->HeapConstant(callable.code())); |
+ node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); |
+ } |
+ } |
+ break; |
+ } |
case IrOpcode::kBooleanNot: { |
if (lower()) { |
MachineTypeUnion input = GetInfo(node->InputAt(0))->output; |
@@ -1034,6 +1064,7 @@ class RepresentationSelector { |
Phase phase_; // current phase of algorithm |
RepresentationChanger* changer_; // for inserting representation changes |
ZoneQueue<Node*> queue_; // queue for traversing the graph |
+ Type* safe_bit_range_; |
Type* safe_int_additive_range_; |
NodeInfo* GetInfo(Node* node) { |
@@ -1058,7 +1089,7 @@ void SimplifiedLowering::LowerAllNodes() { |
SimplifiedOperatorBuilder simplified(graph()->zone()); |
RepresentationChanger changer(jsgraph(), &simplified, |
graph()->zone()->isolate()); |
- RepresentationSelector selector(jsgraph(), zone(), &changer); |
+ RepresentationSelector selector(jsgraph(), zone_, &changer); |
selector.Run(this); |
} |