Commit c30b854a authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Some strength reduction on Smi/HeapObject checks.

Let the SimplifiedOperatorReducer perform some strength reduction for
certain CheckTaggedSigned and CheckTaggedPointer inputs (reusing the
existing logic for ObjectIsSmi).

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

Review-Url: https://codereview.chromium.org/2080703006
Cr-Commit-Position: refs/heads/master@{#37167}
parent ef925a27
......@@ -19,8 +19,6 @@ namespace compiler {
namespace {
enum class Decision { kUnknown, kTrue, kFalse };
Decision DecideCondition(Node* const cond) {
switch (cond->opcode()) {
case IrOpcode::kInt32Constant: {
......
......@@ -898,7 +898,7 @@ struct TypedLoweringPhase {
data->info()->is_deoptimization_enabled()
? JSIntrinsicLowering::kDeoptimizationEnabled
: JSIntrinsicLowering::kDeoptimizationDisabled);
SimplifiedOperatorReducer simple_reducer(data->jsgraph());
SimplifiedOperatorReducer simple_reducer(&graph_reducer, data->jsgraph());
CheckpointElimination checkpoint_elimination(&graph_reducer);
CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
data->common(), data->machine());
......@@ -972,7 +972,7 @@ struct EarlyOptimizationPhase {
JSGenericLowering generic_lowering(data->jsgraph());
DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
data->common());
SimplifiedOperatorReducer simple_reducer(data->jsgraph());
SimplifiedOperatorReducer simple_reducer(&graph_reducer, data->jsgraph());
ValueNumberingReducer value_numbering(temp_zone);
MachineOperatorReducer machine_reducer(data->jsgraph());
CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
......
......@@ -16,8 +16,27 @@ namespace v8 {
namespace internal {
namespace compiler {
SimplifiedOperatorReducer::SimplifiedOperatorReducer(JSGraph* jsgraph)
: jsgraph_(jsgraph), type_cache_(TypeCache::Get()) {}
namespace {
Decision DecideObjectIsSmi(Node* const input) {
NumberMatcher m(input);
if (m.HasValue()) {
return IsSmiDouble(m.Value()) ? Decision::kTrue : Decision::kFalse;
}
if (m.IsAllocate()) return Decision::kFalse;
if (m.IsChangeBitToTagged()) return Decision::kFalse;
if (m.IsChangeInt31ToTaggedSigned()) return Decision::kTrue;
if (m.IsHeapConstant()) return Decision::kFalse;
return Decision::kUnknown;
}
} // namespace
SimplifiedOperatorReducer::SimplifiedOperatorReducer(Editor* editor,
JSGraph* jsgraph)
: AdvancedReducer(editor),
jsgraph_(jsgraph),
type_cache_(TypeCache::Get()) {}
SimplifiedOperatorReducer::~SimplifiedOperatorReducer() {}
......@@ -110,12 +129,32 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
}
break;
}
case IrOpcode::kCheckTaggedPointer: {
Node* const input = node->InputAt(0);
if (DecideObjectIsSmi(input) == Decision::kFalse) {
ReplaceWithValue(node, input);
return Replace(input);
}
break;
}
case IrOpcode::kCheckTaggedSigned: {
Node* const input = node->InputAt(0);
if (DecideObjectIsSmi(input) == Decision::kTrue) {
ReplaceWithValue(node, input);
return Replace(input);
}
break;
}
case IrOpcode::kObjectIsSmi: {
NumberMatcher m(node->InputAt(0));
if (m.HasValue()) return ReplaceBoolean(IsSmiDouble(m.Value()));
if (m.IsChangeBitToTagged()) return ReplaceBoolean(false);
if (m.IsChangeInt31ToTaggedSigned()) return ReplaceBoolean(true);
if (m.IsHeapConstant()) return ReplaceBoolean(false);
Node* const input = node->InputAt(0);
switch (DecideObjectIsSmi(input)) {
case Decision::kTrue:
return ReplaceBoolean(true);
case Decision::kFalse:
return ReplaceBoolean(false);
case Decision::kUnknown:
break;
}
break;
}
case IrOpcode::kNumberCeil:
......
......@@ -20,10 +20,9 @@ class JSGraph;
class MachineOperatorBuilder;
class SimplifiedOperatorBuilder;
class SimplifiedOperatorReducer final : public Reducer {
class SimplifiedOperatorReducer final : public AdvancedReducer {
public:
explicit SimplifiedOperatorReducer(JSGraph* jsgraph);
SimplifiedOperatorReducer(Editor* editor, JSGraph* jsgraph);
~SimplifiedOperatorReducer() final;
Reduction Reduce(Node* node) final;
......
......@@ -460,6 +460,26 @@ enum AllocationAlignment {
kSimd128Unaligned
};
// Possible outcomes for decisions.
enum class Decision : uint8_t { kUnknown, kTrue, kFalse };
inline size_t hash_value(Decision decision) {
return static_cast<uint8_t>(decision);
}
inline std::ostream& operator<<(std::ostream& os, Decision decision) {
switch (decision) {
case Decision::kUnknown:
return os << "Unknown";
case Decision::kTrue:
return os << "True";
case Decision::kFalse:
return os << "False";
}
UNREACHABLE();
return os;
}
// Supported write barrier modes.
enum WriteBarrierKind : uint8_t {
kNoWriteBarrier,
......
......@@ -32,7 +32,8 @@ class SimplifiedOperatorReducerTest : public TypedGraphTest {
JSOperatorBuilder javascript(zone());
JSGraph jsgraph(isolate(), graph(), common(), &javascript, simplified(),
&machine);
SimplifiedOperatorReducer reducer(&jsgraph);
GraphReducer graph_reducer(zone(), graph());
SimplifiedOperatorReducer reducer(&graph_reducer, &jsgraph);
return reducer.Reduce(node);
}
......@@ -343,7 +344,62 @@ TEST_F(SimplifiedOperatorReducerTest, TruncateTaggedToWord32WithConstant) {
}
// -----------------------------------------------------------------------------
// TruncateTaggedToWord32
// CheckTaggedPointer
TEST_F(SimplifiedOperatorReducerTest, CheckTaggedPointerWithChangeBitToTagged) {
Node* param0 = Parameter(0);
Node* effect = graph()->start();
Node* control = graph()->start();
Node* value = graph()->NewNode(simplified()->ChangeBitToTagged(), param0);
Reduction reduction = Reduce(graph()->NewNode(
simplified()->CheckTaggedPointer(), value, effect, control));
ASSERT_TRUE(reduction.Changed());
EXPECT_EQ(value, reduction.replacement());
}
TEST_F(SimplifiedOperatorReducerTest, CheckTaggedPointerWithHeapConstant) {
Node* effect = graph()->start();
Node* control = graph()->start();
Handle<HeapObject> kHeapObjects[] = {
factory()->empty_string(), factory()->null_value(),
factory()->species_symbol(), factory()->undefined_value()};
TRACED_FOREACH(Handle<HeapObject>, object, kHeapObjects) {
Node* value = HeapConstant(object);
Reduction reduction = Reduce(graph()->NewNode(
simplified()->CheckTaggedPointer(), value, effect, control));
ASSERT_TRUE(reduction.Changed());
EXPECT_EQ(value, reduction.replacement());
}
}
// -----------------------------------------------------------------------------
// CheckTaggedSigned
TEST_F(SimplifiedOperatorReducerTest,
CheckTaggedSignedWithChangeInt31ToTaggedSigned) {
Node* param0 = Parameter(0);
Node* effect = graph()->start();
Node* control = graph()->start();
Node* value =
graph()->NewNode(simplified()->ChangeInt31ToTaggedSigned(), param0);
Reduction reduction = Reduce(graph()->NewNode(
simplified()->CheckTaggedSigned(), value, effect, control));
ASSERT_TRUE(reduction.Changed());
EXPECT_EQ(value, reduction.replacement());
}
TEST_F(SimplifiedOperatorReducerTest, CheckTaggedSignedWithNumberConstant) {
Node* effect = graph()->start();
Node* control = graph()->start();
Node* value = NumberConstant(1.0);
Reduction reduction = Reduce(graph()->NewNode(
simplified()->CheckTaggedSigned(), value, effect, control));
ASSERT_TRUE(reduction.Changed());
EXPECT_EQ(value, reduction.replacement());
}
// -----------------------------------------------------------------------------
// ObjectIsSmi
TEST_F(SimplifiedOperatorReducerTest, ObjectIsSmiWithChangeBitToTagged) {
Node* param0 = Parameter(0);
......
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