Commit 95d80867 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Introduce TruncateTaggedPointerToBit operator.

Oftentimes we can avoid the Smi check for ToBoolean truncations, since
we already know that the input is always going to be a HeapObject. So
introduce a dedicated TruncateTaggedPointerToBit operator, which uses
the fact that the input is known to be a HeapObject.

BUG=v8:5267
R=jarin@chromium.org

Review-Url: https://codereview.chromium.org/2738483002
Cr-Commit-Position: refs/heads/master@{#43629}
parent f3d0bda8
......@@ -639,6 +639,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kTruncateTaggedToBit:
result = LowerTruncateTaggedToBit(node);
break;
case IrOpcode::kTruncateTaggedPointerToBit:
result = LowerTruncateTaggedPointerToBit(node);
break;
case IrOpcode::kTruncateTaggedToFloat64:
result = LowerTruncateTaggedToFloat64(node);
break;
......@@ -983,6 +986,53 @@ Node* EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node) {
return done.PhiAt(0);
}
Node* EffectControlLinearizer::LowerTruncateTaggedPointerToBit(Node* node) {
Node* value = node->InputAt(0);
auto if_heapnumber = __ MakeDeferredLabel<1>();
auto done = __ MakeLabel<5>(MachineRepresentation::kBit);
Node* zero = __ Int32Constant(0);
Node* fzero = __ Float64Constant(0.0);
// Check if {value} is false.
__ GotoIf(__ WordEqual(value, __ FalseConstant()), &done, zero);
// Check if {value} is the empty string.
__ GotoIf(__ WordEqual(value, __ EmptyStringConstant()), &done, zero);
// Load the map of {value}.
Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
// Check if the {value} is undetectable and immediately return false.
Node* value_map_bitfield =
__ LoadField(AccessBuilder::ForMapBitField(), value_map);
__ GotoUnless(
__ Word32Equal(__ Word32And(value_map_bitfield,
__ Int32Constant(1 << Map::kIsUndetectable)),
zero),
&done, zero);
// Check if {value} is a HeapNumber.
__ GotoIf(__ WordEqual(value_map, __ HeapNumberMapConstant()),
&if_heapnumber);
// All other values that reach here are true.
__ Goto(&done, __ Int32Constant(1));
__ Bind(&if_heapnumber);
{
// For HeapNumber {value}, just check that its value is not 0.0, -0.0 or
// NaN.
Node* value_value =
__ LoadField(AccessBuilder::ForHeapNumberValue(), value);
__ Goto(&done, __ Float64LessThan(fzero, __ Float64Abs(value_value)));
}
__ Bind(&done);
return done.PhiAt(0);
}
Node* EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node) {
Node* value = node->InputAt(0);
......
......@@ -77,6 +77,7 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer {
Node* LowerCheckedTaggedToTaggedPointer(Node* node, Node* frame_state);
Node* LowerChangeTaggedToFloat64(Node* node);
Node* LowerTruncateTaggedToBit(Node* node);
Node* LowerTruncateTaggedPointerToBit(Node* node);
Node* LowerTruncateTaggedToFloat64(Node* node);
Node* LowerTruncateTaggedToWord32(Node* node);
Node* LowerCheckedTruncateTaggedToWord32(Node* node, Node* frame_state);
......
......@@ -201,7 +201,8 @@
V(ChangeBitToTagged) \
V(TruncateTaggedToWord32) \
V(TruncateTaggedToFloat64) \
V(TruncateTaggedToBit)
V(TruncateTaggedToBit) \
V(TruncateTaggedPointerToBit)
#define SIMPLIFIED_CHECKED_OP_LIST(V) \
V(CheckedInt32Add) \
......
......@@ -725,7 +725,14 @@ Node* RepresentationChanger::GetBitRepresentationFor(
// true is the only trueish Oddball.
op = simplified()->ChangeTaggedToBit();
} else {
if (output_rep == MachineRepresentation::kTagged &&
output_type->Maybe(Type::SignedSmall())) {
op = simplified()->TruncateTaggedToBit();
} else {
// The {output_type} either doesn't include the Smi range,
// or the {output_rep} is known to be TaggedPointer.
op = simplified()->TruncateTaggedPointerToBit();
}
}
} else if (output_rep == MachineRepresentation::kTaggedSigned) {
node = jsgraph()->graph()->NewNode(machine()->WordEqual(), node,
......
......@@ -472,6 +472,7 @@ UnicodeEncoding UnicodeEncodingOf(const Operator* op) {
V(ChangeTaggedToBit, Operator::kNoProperties, 1, 0) \
V(ChangeBitToTagged, Operator::kNoProperties, 1, 0) \
V(TruncateTaggedToBit, Operator::kNoProperties, 1, 0) \
V(TruncateTaggedPointerToBit, Operator::kNoProperties, 1, 0) \
V(TruncateTaggedToWord32, Operator::kNoProperties, 1, 0) \
V(TruncateTaggedToFloat64, Operator::kNoProperties, 1, 0) \
V(ObjectIsDetectableCallable, Operator::kNoProperties, 1, 0) \
......
......@@ -378,6 +378,7 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
const Operator* TruncateTaggedToWord32();
const Operator* TruncateTaggedToFloat64();
const Operator* TruncateTaggedToBit();
const Operator* TruncateTaggedPointerToBit();
const Operator* CheckIf();
const Operator* CheckBounds();
......
......@@ -1111,6 +1111,7 @@ void Verifier::Visitor::Check(Node* node) {
break;
}
case IrOpcode::kTruncateTaggedToBit:
case IrOpcode::kTruncateTaggedPointerToBit:
break;
case IrOpcode::kCheckBounds:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment