[compiler] Avoid code duplication in LowerTruncateTagged*ToBit.

This refactors EffectControlLinearizer's LowerTruncateTaggedToBit and
LowerTruncateTaggedPointerToBit such that they share the common code.
This common code will grow further when supporting bigints in a future
CL.

R=jarin@chromium.org

Bug: 
Change-Id: I881d705de327243121b73e12fb93f2cd96f315f2
Reviewed-on: https://chromium-review.googlesource.com/771391
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49403}
This commit is contained in:
Georg Neis 2017-11-16 09:52:43 +01:00 committed by Commit Bot
parent 22e4c4613b
commit 4f799a4029
2 changed files with 22 additions and 53 deletions

View File

@ -1062,44 +1062,40 @@ Node* EffectControlLinearizer::LowerChangeTaggedToBit(Node* node) {
return __ WordEqual(value, __ TrueConstant());
}
Node* EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node) {
void EffectControlLinearizer::TruncateTaggedPointerToBit(
Node* node, GraphAssemblerLabel<1>* done) {
Node* value = node->InputAt(0);
auto if_smi = __ MakeDeferredLabel();
auto if_heapnumber = __ MakeDeferredLabel();
auto done = __ MakeLabel(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 a Smi.
Node* check_smi = ObjectIsSmi(value);
__ GotoIf(check_smi, &if_smi);
__ GotoIf(__ WordEqual(value, __ FalseConstant()), done, zero);
// Check if {value} is the empty string.
__ GotoIf(__ WordEqual(value, __ EmptyStringConstant()), &done, zero);
__ 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.
// This includes undefined and null.
Node* value_map_bitfield =
__ LoadField(AccessBuilder::ForMapBitField(), value_map);
__ GotoIfNot(
__ Word32Equal(__ Word32And(value_map_bitfield,
__ Int32Constant(1 << Map::kIsUndetectable)),
zero),
&done, 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));
__ Goto(done, __ Int32Constant(1));
__ Bind(&if_heapnumber);
{
@ -1107,14 +1103,24 @@ Node* EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node) {
// NaN.
Node* value_value =
__ LoadField(AccessBuilder::ForHeapNumberValue(), value);
__ Goto(&done, __ Float64LessThan(fzero, __ Float64Abs(value_value)));
__ Goto(done, __ Float64LessThan(fzero, __ Float64Abs(value_value)));
}
}
Node* EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node) {
auto done = __ MakeLabel(MachineRepresentation::kBit);
auto if_smi = __ MakeDeferredLabel();
Node* value = node->InputAt(0);
__ GotoIf(ObjectIsSmi(value), &if_smi);
TruncateTaggedPointerToBit(node, &done);
__ Bind(&if_smi);
{
// If {value} is a Smi, then we only need to check that it's not zero.
__ Goto(&done,
__ Word32Equal(__ WordEqual(value, __ IntPtrConstant(0)), zero));
__ Goto(&done, __ Word32Equal(__ WordEqual(value, __ IntPtrConstant(0)),
__ Int32Constant(0)));
}
__ Bind(&done);
@ -1122,47 +1128,9 @@ Node* EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node) {
}
Node* EffectControlLinearizer::LowerTruncateTaggedPointerToBit(Node* node) {
Node* value = node->InputAt(0);
auto if_heapnumber = __ MakeDeferredLabel();
auto done = __ MakeLabel(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);
__ GotoIfNot(
__ 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)));
}
TruncateTaggedPointerToBit(node, &done);
__ Bind(&done);
return done.PhiAt(0);

View File

@ -79,6 +79,7 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer {
Node* LowerCheckedTaggedToTaggedSigned(Node* node, Node* frame_state);
Node* LowerCheckedTaggedToTaggedPointer(Node* node, Node* frame_state);
Node* LowerChangeTaggedToFloat64(Node* node);
void TruncateTaggedPointerToBit(Node* node, GraphAssemblerLabel<1>* done);
Node* LowerTruncateTaggedToBit(Node* node);
Node* LowerTruncateTaggedPointerToBit(Node* node);
Node* LowerTruncateTaggedToFloat64(Node* node);