Commit 52a66bf1 authored by bmeurer's avatar bmeurer Committed by Commit bot

Revert of [turbofan] Introduce TruncateTaggedToBit operator for ToBoolean...

Revert of [turbofan] Introduce TruncateTaggedToBit operator for ToBoolean truncation. (patchset #2 id:20001 of https://codereview.chromium.org/2167593002/ )

Reason for revert:
Breaks arm64 gc stress:
https://build.chromium.org/p/client.v8.ports/builders/V8%20Linux%20-%20arm64%20-%20sim%20-%20gc%20stress/builds/1605

Original issue's description:
> [turbofan] Introduce TruncateTaggedToBit operator for ToBoolean truncation.
>
> Add a dedicated simplified operator to inline the general case for the
> ToBoolean conversion. In a follow up CL we will also use the ToBoolean
> hints gathered by the baseline compiler.
>
> Committed: https://crrev.com/8c50b51ab3d21efcd2f6900d83962159f21e1590
> Cr-Commit-Position: refs/heads/master@{#37882}

TBR=jarin@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true

Review-Url: https://codereview.chromium.org/2170433002
Cr-Commit-Position: refs/heads/master@{#37899}
parent 90015a1f
......@@ -265,6 +265,7 @@ void TryCloneBranch(Node* node, BasicBlock* block, Graph* graph,
Node* phi_false = graph->NewNode(phi->op(), input_count + 1, inputs);
if (phi->UseCount() == 0) {
DCHECK_EQ(phi->opcode(), IrOpcode::kEffectPhi);
DCHECK_EQ(input_count, block->SuccessorCount());
} else {
for (Edge edge : phi->use_edges()) {
Node* control = NodeProperties::GetControlInput(edge.from());
......@@ -615,9 +616,6 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kChangeTaggedToFloat64:
state = LowerChangeTaggedToFloat64(node, *effect, *control);
break;
case IrOpcode::kTruncateTaggedToBit:
state = LowerTruncateTaggedToBit(node, *effect, *control);
break;
case IrOpcode::kTruncateTaggedToFloat64:
state = LowerTruncateTaggedToFloat64(node, *effect, *control);
break;
......@@ -895,157 +893,6 @@ EffectControlLinearizer::LowerChangeTaggedToBit(Node* node, Node* effect,
return ValueEffectControl(value, effect, control);
}
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node, Node* effect,
Node* control) {
Node* value = node->InputAt(0);
Node* one = jsgraph()->Int32Constant(1);
Node* zero = jsgraph()->Int32Constant(0);
Node* fzero = jsgraph()->Float64Constant(0.0);
// Collect effect/control/value triples.
int count = 0;
Node* values[7];
Node* effects[7];
Node* controls[6];
// Check if {value} is a Smi.
Node* check_smi = ObjectIsSmi(value);
Node* branch_smi = graph()->NewNode(common()->Branch(BranchHint::kFalse),
check_smi, control);
// If {value} is a Smi, then we only need to check that it's not zero.
Node* if_smi = graph()->NewNode(common()->IfTrue(), branch_smi);
Node* esmi = effect;
{
controls[count] = if_smi;
effects[count] = esmi;
values[count] =
graph()->NewNode(machine()->Word32Equal(),
graph()->NewNode(machine()->WordEqual(), value,
jsgraph()->ZeroConstant()),
zero);
count++;
}
control = graph()->NewNode(common()->IfFalse(), branch_smi);
// Load the map instance type of {value}.
Node* value_map = effect = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control);
Node* value_instance_type = effect = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
effect, control);
// Check if {value} is an Oddball.
Node* check_oddball =
graph()->NewNode(machine()->Word32Equal(), value_instance_type,
jsgraph()->Int32Constant(ODDBALL_TYPE));
Node* branch_oddball = graph()->NewNode(common()->Branch(BranchHint::kTrue),
check_oddball, control);
// The only Oddball {value} that is trueish is true itself.
Node* if_oddball = graph()->NewNode(common()->IfTrue(), branch_oddball);
Node* eoddball = effect;
{
controls[count] = if_oddball;
effects[count] = eoddball;
values[count] = graph()->NewNode(machine()->WordEqual(), value,
jsgraph()->TrueConstant());
count++;
}
control = graph()->NewNode(common()->IfFalse(), branch_oddball);
// Check if {value} is a String.
Node* check_string =
graph()->NewNode(machine()->Int32LessThan(), value_instance_type,
jsgraph()->Int32Constant(FIRST_NONSTRING_TYPE));
Node* branch_string =
graph()->NewNode(common()->Branch(), check_string, control);
// For String {value}, we need to check that the length is not zero.
Node* if_string = graph()->NewNode(common()->IfTrue(), branch_string);
Node* estring = effect;
{
// Load the {value} length.
Node* value_length = estring = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForStringLength()), value,
estring, if_string);
controls[count] = if_string;
effects[count] = estring;
values[count] =
graph()->NewNode(machine()->Word32Equal(),
graph()->NewNode(machine()->WordEqual(), value_length,
jsgraph()->ZeroConstant()),
zero);
count++;
}
control = graph()->NewNode(common()->IfFalse(), branch_string);
// Check if {value} is a HeapNumber.
Node* check_heapnumber =
graph()->NewNode(machine()->Word32Equal(), value_instance_type,
jsgraph()->Int32Constant(HEAP_NUMBER_TYPE));
Node* branch_heapnumber =
graph()->NewNode(common()->Branch(), check_heapnumber, control);
// For HeapNumber {value}, just check that its value is not 0.0, -0.0 or NaN.
Node* if_heapnumber = graph()->NewNode(common()->IfTrue(), branch_heapnumber);
Node* eheapnumber = effect;
{
// Load the raw value of {value}.
Node* value_value = eheapnumber = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
eheapnumber, if_heapnumber);
// Check if {value} is either less than 0.0 or greater than 0.0.
Node* check =
graph()->NewNode(machine()->Float64LessThan(), fzero, value_value);
Node* branch = graph()->NewNode(common()->Branch(), check, if_heapnumber);
controls[count] = graph()->NewNode(common()->IfTrue(), branch);
effects[count] = eheapnumber;
values[count] = one;
count++;
controls[count] = graph()->NewNode(common()->IfFalse(), branch);
effects[count] = eheapnumber;
values[count] =
graph()->NewNode(machine()->Float64LessThan(), value_value, fzero);
count++;
}
control = graph()->NewNode(common()->IfFalse(), branch_heapnumber);
// The {value} is either a JSReceiver, a Symbol or some Simd128Value. In
// those cases we can just the undetectable bit on the map, which will only
// be set for certain JSReceivers, i.e. document.all.
{
// Load the {value} map bit field.
Node* value_map_bitfield = effect = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map,
effect, control);
controls[count] = control;
effects[count] = effect;
values[count] = graph()->NewNode(
machine()->Word32Equal(),
graph()->NewNode(machine()->Word32And(), value_map_bitfield,
jsgraph()->Int32Constant(1 << Map::kIsUndetectable)),
zero);
count++;
}
// Merge the different controls.
control = graph()->NewNode(common()->Merge(count), count, controls);
effects[count] = control;
effect = graph()->NewNode(common()->EffectPhi(count), count + 1, effects);
values[count] = control;
value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, count),
count + 1, values);
return ValueEffectControl(value, effect, control);
}
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node, Node* effect,
Node* control) {
......
......@@ -95,8 +95,6 @@ class EffectControlLinearizer {
Node* effect, Node* control);
ValueEffectControl LowerChangeTaggedToFloat64(Node* node, Node* effect,
Node* control);
ValueEffectControl LowerTruncateTaggedToBit(Node* node, Node* effect,
Node* control);
ValueEffectControl LowerTruncateTaggedToFloat64(Node* node, Node* effect,
Node* control);
ValueEffectControl LowerTruncateTaggedToWord32(Node* node, Node* effect,
......
......@@ -178,8 +178,7 @@
V(ChangeTaggedToBit) \
V(ChangeBitToTagged) \
V(TruncateTaggedToWord32) \
V(TruncateTaggedToFloat64) \
V(TruncateTaggedToBit)
V(TruncateTaggedToFloat64)
#define SIMPLIFIED_CHECKED_OP_LIST(V) \
V(CheckedInt32Add) \
......
......@@ -487,30 +487,18 @@ Node* RepresentationChanger::GetBitRepresentationFor(
switch (node->opcode()) {
case IrOpcode::kHeapConstant: {
Handle<HeapObject> value = OpParameter<Handle<HeapObject>>(node);
return jsgraph()->Int32Constant(value->BooleanValue() ? 1 : 0);
DCHECK(value.is_identical_to(factory()->true_value()) ||
value.is_identical_to(factory()->false_value()));
return jsgraph()->Int32Constant(
value.is_identical_to(factory()->true_value()) ? 1 : 0);
}
default:
break;
}
// Select the correct X -> Bit operator.
const Operator* op;
if (IsWord(output_rep)) {
return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
jsgraph()->Int32Constant(0));
} else if (output_rep == MachineRepresentation::kFloat32) {
node = jsgraph()->graph()->NewNode(machine()->Float32Abs(), node);
return jsgraph()->graph()->NewNode(machine()->Float32LessThan(),
jsgraph()->Float32Constant(0.0), node);
} else if (output_rep == MachineRepresentation::kFloat64) {
node = jsgraph()->graph()->NewNode(machine()->Float64Abs(), node);
return jsgraph()->graph()->NewNode(machine()->Float64LessThan(),
jsgraph()->Float64Constant(0.0), node);
} else if (output_rep == MachineRepresentation::kTagged) {
if (output_type->Is(Type::Boolean())) {
op = simplified()->ChangeTaggedToBit();
} else {
op = simplified()->TruncateTaggedToBit();
}
if (output_rep == MachineRepresentation::kTagged) {
op = simplified()->ChangeTaggedToBit();
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kBit);
......
......@@ -28,9 +28,6 @@ class Truncation final {
}
// Queries.
bool TruncatesToBool() const {
return LessGeneral(kind_, TruncationKind::kBool);
}
bool TruncatesToWord32() const {
return LessGeneral(kind_, TruncationKind::kWord32);
}
......
......@@ -1218,18 +1218,6 @@ class RepresentationSelector {
//------------------------------------------------------------------
// JavaScript operators.
//------------------------------------------------------------------
case IrOpcode::kJSToBoolean: {
if (truncation.TruncatesToBool()) {
ProcessInput(node, 0, UseInfo::Bool());
ProcessInput(node, 1, UseInfo::None());
SetOutput(node, MachineRepresentation::kBit);
if (lower()) DeferReplacement(node, node->InputAt(0));
} else {
VisitInputs(node);
SetOutput(node, MachineRepresentation::kTagged);
}
return;
}
case IrOpcode::kJSToNumber: {
VisitInputs(node);
// TODO(bmeurer): Optimize somewhat based on input type?
......
......@@ -344,7 +344,6 @@ CompareOperationHints::Hint CompareOperationHintOf(const Operator* op) {
V(ChangeBitToTagged, Operator::kNoProperties, 1) \
V(TruncateTaggedToWord32, Operator::kNoProperties, 1) \
V(TruncateTaggedToFloat64, Operator::kNoProperties, 1) \
V(TruncateTaggedToBit, Operator::kNoProperties, 1) \
V(ObjectIsCallable, Operator::kNoProperties, 1) \
V(ObjectIsNumber, Operator::kNoProperties, 1) \
V(ObjectIsReceiver, Operator::kNoProperties, 1) \
......
......@@ -267,7 +267,6 @@ class SimplifiedOperatorBuilder final : public ZoneObject {
const Operator* ChangeBitToTagged();
const Operator* TruncateTaggedToWord32();
const Operator* TruncateTaggedToFloat64();
const Operator* TruncateTaggedToBit();
const Operator* CheckIf();
const Operator* CheckBounds();
......
......@@ -946,8 +946,6 @@ void Verifier::Visitor::Check(Node* node) {
// CheckUpperIs(node, to));
break;
}
case IrOpcode::kTruncateTaggedToBit:
break;
case IrOpcode::kCheckBounds:
CheckValueInputIs(node, 0, Type::Any());
......
......@@ -644,7 +644,23 @@ TEST(Nops) {
TEST(TypeErrors) {
RepresentationChangerTester r;
// Wordish cannot be implicitly converted to/from comparison conditions.
r.CheckTypeError(MachineRepresentation::kWord8, Type::None(),
MachineRepresentation::kBit);
r.CheckTypeError(MachineRepresentation::kWord16, Type::None(),
MachineRepresentation::kBit);
r.CheckTypeError(MachineRepresentation::kWord32, Type::None(),
MachineRepresentation::kBit);
r.CheckTypeError(MachineRepresentation::kWord64, Type::None(),
MachineRepresentation::kBit);
// Floats cannot be implicitly converted to/from comparison conditions.
r.CheckTypeError(MachineRepresentation::kFloat64, Type::None(),
MachineRepresentation::kBit);
// Floats cannot be implicitly converted to/from comparison conditions.
r.CheckTypeError(MachineRepresentation::kFloat32, Type::None(),
MachineRepresentation::kBit);
r.CheckTypeError(MachineRepresentation::kBit, Type::None(),
MachineRepresentation::kFloat32);
r.CheckTypeError(MachineRepresentation::kBit, Type::Boolean(),
......
......@@ -64,8 +64,6 @@ const PureOperator kPureOperators[] = {
PURE(ChangeTaggedToBit, Operator::kNoProperties, 1),
PURE(ChangeBitToTagged, Operator::kNoProperties, 1),
PURE(TruncateTaggedToWord32, Operator::kNoProperties, 1),
PURE(TruncateTaggedToFloat64, Operator::kNoProperties, 1),
PURE(TruncateTaggedToBit, Operator::kNoProperties, 1),
PURE(ObjectIsNumber, Operator::kNoProperties, 1),
PURE(ObjectIsReceiver, Operator::kNoProperties, 1),
PURE(ObjectIsSmi, Operator::kNoProperties, 1)
......
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