Commit 92e6bcf1 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Improve interplay of ControlReducer and CommonOperatorReducer.

This turns the CommonOperatorReducer into an AdvancedReducer and makes
it independent of JSGraph (which was used only because it was convienent),
and let's the CommonOperatorReducer run together with the ControlReducer.

The ControlReducer is still not able to run together with other reducers,
but we're getting closer. The plan is to split the ControlReducer into
two parts: The dead code elimination part and the common operator
reduction part. This separation will help to avoid tricky bugs in the
future and should make testing a *lot* easier.

R=jarin@chromium.org

Review URL: https://codereview.chromium.org/1192063002

Cr-Commit-Position: refs/heads/master@{#29105}
parent eb0e7437
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
#include <algorithm> #include <algorithm>
#include "src/compiler/common-operator.h" #include "src/compiler/common-operator.h"
#include "src/compiler/js-graph.h" #include "src/compiler/graph.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/node.h" #include "src/compiler/node.h"
#include "src/compiler/node-matchers.h" #include "src/compiler/node-matchers.h"
...@@ -32,43 +33,69 @@ Reduction CommonOperatorReducer::Reduce(Node* node) { ...@@ -32,43 +33,69 @@ Reduction CommonOperatorReducer::Reduce(Node* node) {
Reduction CommonOperatorReducer::ReduceEffectPhi(Node* node) { Reduction CommonOperatorReducer::ReduceEffectPhi(Node* node) {
DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode()); DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode());
int const input_count = node->InputCount(); int const input_count = node->InputCount() - 1;
if (input_count > 1) { DCHECK_LE(1, input_count);
Node* const replacement = node->InputAt(0); Node* const merge = node->InputAt(input_count);
for (int i = 1; i < input_count - 1; ++i) { DCHECK(IrOpcode::IsMergeOpcode(merge->opcode()));
if (node->InputAt(i) != replacement) return NoChange(); DCHECK_EQ(input_count, merge->InputCount());
Node* const effect = node->InputAt(0);
DCHECK_NE(node, effect);
for (int i = 1; i < input_count; ++i) {
Node* const input = node->InputAt(i);
if (input == node) {
// Ignore redundant inputs.
DCHECK_EQ(IrOpcode::kLoop, merge->opcode());
continue;
} }
return Replace(replacement); if (input != effect) return NoChange();
} }
return NoChange(); // We might now be able to further reduce the {merge} node.
Revisit(merge);
return Replace(effect);
} }
Reduction CommonOperatorReducer::ReducePhi(Node* node) { Reduction CommonOperatorReducer::ReducePhi(Node* node) {
DCHECK_EQ(IrOpcode::kPhi, node->opcode()); DCHECK_EQ(IrOpcode::kPhi, node->opcode());
int const input_count = node->InputCount(); int const input_count = node->InputCount() - 1;
if (input_count == 3) { DCHECK_LE(1, input_count);
Node* vtrue = NodeProperties::GetValueInput(node, 0); Node* const merge = node->InputAt(input_count);
Node* vfalse = NodeProperties::GetValueInput(node, 1); DCHECK(IrOpcode::IsMergeOpcode(merge->opcode()));
Node* merge = NodeProperties::GetControlInput(node); DCHECK_EQ(input_count, merge->InputCount());
DiamondMatcher matcher(merge); if (input_count == 2) {
if (matcher.Matched()) { Node* vtrue = node->InputAt(0);
if (matcher.IfTrue() == merge->InputAt(1)) std::swap(vtrue, vfalse); Node* vfalse = node->InputAt(1);
Node* cond = matcher.Branch()->InputAt(0); Node* if_true = merge->InputAt(0);
Node* if_false = merge->InputAt(1);
if (if_true->opcode() != IrOpcode::kIfTrue) {
std::swap(if_true, if_false);
std::swap(vtrue, vfalse);
}
if (if_true->opcode() == IrOpcode::kIfTrue &&
if_false->opcode() == IrOpcode::kIfFalse &&
if_true->InputAt(0) == if_false->InputAt(0)) {
Node* const branch = if_true->InputAt(0);
Node* const cond = branch->InputAt(0);
if (cond->opcode() == IrOpcode::kFloat32LessThan) { if (cond->opcode() == IrOpcode::kFloat32LessThan) {
Float32BinopMatcher mcond(cond); Float32BinopMatcher mcond(cond);
if (mcond.left().Is(0.0) && mcond.right().Equals(vtrue) && if (mcond.left().Is(0.0) && mcond.right().Equals(vtrue) &&
vfalse->opcode() == IrOpcode::kFloat32Sub) { vfalse->opcode() == IrOpcode::kFloat32Sub) {
Float32BinopMatcher mvfalse(vfalse); Float32BinopMatcher mvfalse(vfalse);
if (mvfalse.left().IsZero() && mvfalse.right().Equals(vtrue)) { if (mvfalse.left().IsZero() && mvfalse.right().Equals(vtrue)) {
// We might now be able to further reduce the {merge} node.
Revisit(merge);
return Change(node, machine()->Float32Abs(), vtrue); return Change(node, machine()->Float32Abs(), vtrue);
} }
} }
if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) && if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) &&
machine()->HasFloat32Min()) { machine()->HasFloat32Min()) {
// We might now be able to further reduce the {merge} node.
Revisit(merge);
return Change(node, machine()->Float32Min(), vtrue, vfalse); return Change(node, machine()->Float32Min(), vtrue, vfalse);
} else if (mcond.left().Equals(vfalse) && mcond.right().Equals(vtrue) && } else if (mcond.left().Equals(vfalse) && mcond.right().Equals(vtrue) &&
machine()->HasFloat32Max()) { machine()->HasFloat32Max()) {
// We might now be able to further reduce the {merge} node.
Revisit(merge);
return Change(node, machine()->Float32Max(), vtrue, vfalse); return Change(node, machine()->Float32Max(), vtrue, vfalse);
} }
} else if (cond->opcode() == IrOpcode::kFloat64LessThan) { } else if (cond->opcode() == IrOpcode::kFloat64LessThan) {
...@@ -77,35 +104,47 @@ Reduction CommonOperatorReducer::ReducePhi(Node* node) { ...@@ -77,35 +104,47 @@ Reduction CommonOperatorReducer::ReducePhi(Node* node) {
vfalse->opcode() == IrOpcode::kFloat64Sub) { vfalse->opcode() == IrOpcode::kFloat64Sub) {
Float64BinopMatcher mvfalse(vfalse); Float64BinopMatcher mvfalse(vfalse);
if (mvfalse.left().IsZero() && mvfalse.right().Equals(vtrue)) { if (mvfalse.left().IsZero() && mvfalse.right().Equals(vtrue)) {
// We might now be able to further reduce the {merge} node.
Revisit(merge);
return Change(node, machine()->Float64Abs(), vtrue); return Change(node, machine()->Float64Abs(), vtrue);
} }
} }
if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) && if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) &&
machine()->HasFloat64Min()) { machine()->HasFloat64Min()) {
// We might now be able to further reduce the {merge} node.
Revisit(merge);
return Change(node, machine()->Float64Min(), vtrue, vfalse); return Change(node, machine()->Float64Min(), vtrue, vfalse);
} else if (mcond.left().Equals(vfalse) && mcond.right().Equals(vtrue) && } else if (mcond.left().Equals(vfalse) && mcond.right().Equals(vtrue) &&
machine()->HasFloat64Max()) { machine()->HasFloat64Max()) {
// We might now be able to further reduce the {merge} node.
Revisit(merge);
return Change(node, machine()->Float64Max(), vtrue, vfalse); return Change(node, machine()->Float64Max(), vtrue, vfalse);
} }
} }
} }
} }
if (input_count > 1) { Node* const value = node->InputAt(0);
Node* const replacement = node->InputAt(0); DCHECK_NE(node, value);
for (int i = 1; i < input_count - 1; ++i) { for (int i = 1; i < input_count; ++i) {
if (node->InputAt(i) != replacement) return NoChange(); Node* const input = node->InputAt(i);
if (input == node) {
// Ignore redundant inputs.
DCHECK_EQ(IrOpcode::kLoop, merge->opcode());
continue;
} }
return Replace(replacement); if (input != value) return NoChange();
} }
return NoChange(); // We might now be able to further reduce the {merge} node.
Revisit(merge);
return Replace(value);
} }
Reduction CommonOperatorReducer::ReduceSelect(Node* node) { Reduction CommonOperatorReducer::ReduceSelect(Node* node) {
DCHECK_EQ(IrOpcode::kSelect, node->opcode()); DCHECK_EQ(IrOpcode::kSelect, node->opcode());
Node* cond = NodeProperties::GetValueInput(node, 0); Node* const cond = node->InputAt(0);
Node* vtrue = NodeProperties::GetValueInput(node, 1); Node* const vtrue = node->InputAt(1);
Node* vfalse = NodeProperties::GetValueInput(node, 2); Node* const vfalse = node->InputAt(2);
if (vtrue == vfalse) return Replace(vtrue); if (vtrue == vfalse) return Replace(vtrue);
switch (cond->opcode()) { switch (cond->opcode()) {
case IrOpcode::kHeapConstant: { case IrOpcode::kHeapConstant: {
...@@ -173,19 +212,6 @@ Reduction CommonOperatorReducer::Change(Node* node, Operator const* op, Node* a, ...@@ -173,19 +212,6 @@ Reduction CommonOperatorReducer::Change(Node* node, Operator const* op, Node* a,
return Changed(node); return Changed(node);
} }
CommonOperatorBuilder* CommonOperatorReducer::common() const {
return jsgraph()->common();
}
Graph* CommonOperatorReducer::graph() const { return jsgraph()->graph(); }
MachineOperatorBuilder* CommonOperatorReducer::machine() const {
return jsgraph()->machine();
}
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -14,15 +14,20 @@ namespace compiler { ...@@ -14,15 +14,20 @@ namespace compiler {
// Forward declarations. // Forward declarations.
class CommonOperatorBuilder; class CommonOperatorBuilder;
class Graph; class Graph;
class JSGraph;
class MachineOperatorBuilder; class MachineOperatorBuilder;
class Operator; class Operator;
// Performs strength reduction on nodes that have common operators. // Performs strength reduction on nodes that have common operators.
class CommonOperatorReducer final : public Reducer { class CommonOperatorReducer final : public AdvancedReducer {
public: public:
explicit CommonOperatorReducer(JSGraph* jsgraph) : jsgraph_(jsgraph) {} CommonOperatorReducer(Editor* editor, Graph* graph,
CommonOperatorBuilder* common,
MachineOperatorBuilder* machine)
: AdvancedReducer(editor),
graph_(graph),
common_(common),
machine_(machine) {}
~CommonOperatorReducer() final {} ~CommonOperatorReducer() final {}
Reduction Reduce(Node* node) final; Reduction Reduce(Node* node) final;
...@@ -35,12 +40,13 @@ class CommonOperatorReducer final : public Reducer { ...@@ -35,12 +40,13 @@ class CommonOperatorReducer final : public Reducer {
Reduction Change(Node* node, Operator const* op, Node* a); Reduction Change(Node* node, Operator const* op, Node* a);
Reduction Change(Node* node, Operator const* op, Node* a, Node* b); Reduction Change(Node* node, Operator const* op, Node* a, Node* b);
CommonOperatorBuilder* common() const; Graph* graph() const { return graph_; }
Graph* graph() const; CommonOperatorBuilder* common() const { return common_; }
JSGraph* jsgraph() const { return jsgraph_; } MachineOperatorBuilder* machine() const { return machine_; }
MachineOperatorBuilder* machine() const;
JSGraph* const jsgraph_; Graph* const graph_;
CommonOperatorBuilder* const common_;
MachineOperatorBuilder* const machine_;
}; };
} // namespace compiler } // namespace compiler
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "src/compiler/common-operator.h" #include "src/compiler/common-operator.h"
#include "src/compiler/common-operator-reducer.h"
#include "src/compiler/control-reducer.h" #include "src/compiler/control-reducer.h"
#include "src/compiler/graph.h" #include "src/compiler/graph.h"
#include "src/compiler/graph-reducer.h" #include "src/compiler/graph-reducer.h"
...@@ -69,13 +70,6 @@ class ControlReducerImpl final : public AdvancedReducer { ...@@ -69,13 +70,6 @@ class ControlReducerImpl final : public AdvancedReducer {
case IrOpcode::kMerge: case IrOpcode::kMerge:
result = ReduceMerge(node); result = ReduceMerge(node);
break; break;
case IrOpcode::kSelect:
result = ReduceSelect(node);
break;
case IrOpcode::kPhi:
case IrOpcode::kEffectPhi:
result = ReducePhi(node);
break;
case IrOpcode::kEnd: case IrOpcode::kEnd:
result = ReduceEnd(node); result = ReduceEnd(node);
break; break;
...@@ -104,38 +98,6 @@ class ControlReducerImpl final : public AdvancedReducer { ...@@ -104,38 +98,6 @@ class ControlReducerImpl final : public AdvancedReducer {
return kUnknown; return kUnknown;
} }
// Reduce redundant selects.
Node* ReduceSelect(Node* const node) {
Node* const tvalue = node->InputAt(1);
Node* const fvalue = node->InputAt(2);
if (tvalue == fvalue) return tvalue;
Decision result = DecideCondition(node->InputAt(0));
if (result == kTrue) return tvalue;
if (result == kFalse) return fvalue;
return node;
}
// Reduce redundant phis.
Node* ReducePhi(Node* node) {
int n = node->InputCount();
if (n <= 1) return dead(); // No non-control inputs.
if (n == 2) return node->InputAt(0); // Only one non-control input.
Node* replacement = NULL;
auto const inputs = node->inputs();
for (auto it = inputs.begin(); n > 1; --n, ++it) {
Node* input = *it;
// Ignore dead inputs.
if (input->opcode() == IrOpcode::kDeadControl) continue;
// Non-redundant input.
if (input != node && input != replacement) {
if (replacement != NULL) return node;
replacement = input;
}
}
return replacement == NULL ? dead() : replacement;
}
// Reduce branches. // Reduce branches.
Node* ReduceBranch(Node* branch) { Node* ReduceBranch(Node* branch) {
if (DecideCondition(branch->InputAt(0)) != kUnknown) { if (DecideCondition(branch->InputAt(0)) != kUnknown) {
...@@ -312,9 +274,12 @@ class ControlReducerImpl final : public AdvancedReducer { ...@@ -312,9 +274,12 @@ class ControlReducerImpl final : public AdvancedReducer {
void ControlReducer::ReduceGraph(Zone* zone, JSGraph* jsgraph, void ControlReducer::ReduceGraph(Zone* zone, JSGraph* jsgraph,
int max_phis_for_select) { int max_phis_for_select) {
GraphReducer graph_reducer(zone, jsgraph->graph()); GraphReducer graph_reducer(zone, jsgraph->graph());
CommonOperatorReducer common(&graph_reducer, jsgraph->graph(),
jsgraph->common(), jsgraph->machine());
ControlReducerImpl impl(&graph_reducer, zone, jsgraph); ControlReducerImpl impl(&graph_reducer, zone, jsgraph);
impl.max_phis_for_select_ = max_phis_for_select; impl.max_phis_for_select_ = max_phis_for_select;
graph_reducer.AddReducer(&impl); graph_reducer.AddReducer(&impl);
graph_reducer.AddReducer(&common);
graph_reducer.ReduceGraph(); graph_reducer.ReduceGraph();
} }
...@@ -344,14 +309,6 @@ Node* ControlReducer::ReduceMerge(JSGraph* jsgraph, Node* node, ...@@ -344,14 +309,6 @@ Node* ControlReducer::ReduceMerge(JSGraph* jsgraph, Node* node,
} }
Node* ControlReducer::ReducePhiForTesting(JSGraph* jsgraph, Node* node) {
Zone zone;
DummyEditor editor;
ControlReducerImpl impl(&editor, &zone, jsgraph);
return impl.ReducePhi(node);
}
Node* ControlReducer::ReduceIfNodeForTesting(JSGraph* jsgraph, Node* node) { Node* ControlReducer::ReduceIfNodeForTesting(JSGraph* jsgraph, Node* node) {
Zone zone; Zone zone;
DummyEditor editor; DummyEditor editor;
......
...@@ -30,7 +30,6 @@ class ControlReducer { ...@@ -30,7 +30,6 @@ class ControlReducer {
int max_phis_for_select = 0); int max_phis_for_select = 0);
// Testing interface. // Testing interface.
static Node* ReducePhiForTesting(JSGraph* graph, Node* node);
static Node* ReduceIfNodeForTesting(JSGraph* graph, Node* node); static Node* ReduceIfNodeForTesting(JSGraph* graph, Node* node);
}; };
} }
......
...@@ -575,7 +575,8 @@ struct TypedLoweringPhase { ...@@ -575,7 +575,8 @@ struct TypedLoweringPhase {
data->info()->is_deoptimization_enabled() data->info()->is_deoptimization_enabled()
? JSIntrinsicLowering::kDeoptimizationEnabled ? JSIntrinsicLowering::kDeoptimizationEnabled
: JSIntrinsicLowering::kDeoptimizationDisabled); : JSIntrinsicLowering::kDeoptimizationDisabled);
CommonOperatorReducer common_reducer(data->jsgraph()); CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
data->common(), data->machine());
AddReducer(data, &graph_reducer, &builtin_reducer); AddReducer(data, &graph_reducer, &builtin_reducer);
AddReducer(data, &graph_reducer, &typed_lowering); AddReducer(data, &graph_reducer, &typed_lowering);
AddReducer(data, &graph_reducer, &intrinsic_lowering); AddReducer(data, &graph_reducer, &intrinsic_lowering);
...@@ -593,10 +594,11 @@ struct SimplifiedLoweringPhase { ...@@ -593,10 +594,11 @@ struct SimplifiedLoweringPhase {
SimplifiedLowering lowering(data->jsgraph(), temp_zone, SimplifiedLowering lowering(data->jsgraph(), temp_zone,
data->source_positions()); data->source_positions());
lowering.LowerAllNodes(); lowering.LowerAllNodes();
JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
ValueNumberingReducer vn_reducer(temp_zone); ValueNumberingReducer vn_reducer(temp_zone);
MachineOperatorReducer machine_reducer(data->jsgraph()); MachineOperatorReducer machine_reducer(data->jsgraph());
CommonOperatorReducer common_reducer(data->jsgraph()); CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
JSGraphReducer graph_reducer(data->jsgraph(), temp_zone); data->common(), data->machine());
AddReducer(data, &graph_reducer, &vn_reducer); AddReducer(data, &graph_reducer, &vn_reducer);
AddReducer(data, &graph_reducer, &machine_reducer); AddReducer(data, &graph_reducer, &machine_reducer);
AddReducer(data, &graph_reducer, &common_reducer); AddReducer(data, &graph_reducer, &common_reducer);
...@@ -620,11 +622,12 @@ struct ChangeLoweringPhase { ...@@ -620,11 +622,12 @@ struct ChangeLoweringPhase {
static const char* phase_name() { return "change lowering"; } static const char* phase_name() { return "change lowering"; }
void Run(PipelineData* data, Zone* temp_zone) { void Run(PipelineData* data, Zone* temp_zone) {
JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
ValueNumberingReducer vn_reducer(temp_zone); ValueNumberingReducer vn_reducer(temp_zone);
ChangeLowering lowering(data->jsgraph()); ChangeLowering lowering(data->jsgraph());
MachineOperatorReducer machine_reducer(data->jsgraph()); MachineOperatorReducer machine_reducer(data->jsgraph());
CommonOperatorReducer common_reducer(data->jsgraph()); CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
JSGraphReducer graph_reducer(data->jsgraph(), temp_zone); data->common(), data->machine());
AddReducer(data, &graph_reducer, &vn_reducer); AddReducer(data, &graph_reducer, &vn_reducer);
AddReducer(data, &graph_reducer, &lowering); AddReducer(data, &graph_reducer, &lowering);
AddReducer(data, &graph_reducer, &machine_reducer); AddReducer(data, &graph_reducer, &machine_reducer);
......
...@@ -143,29 +143,6 @@ class ControlReducerTester : HandleAndZoneScope { ...@@ -143,29 +143,6 @@ class ControlReducerTester : HandleAndZoneScope {
void ReduceGraph() { ControlReducer::ReduceGraph(main_zone(), &jsgraph); } void ReduceGraph() { ControlReducer::ReduceGraph(main_zone(), &jsgraph); }
// Checks one-step reduction of a phi.
void ReducePhi(Node* expect, Node* phi) {
Node* result = ControlReducer::ReducePhiForTesting(&jsgraph, phi);
CHECK_EQ(expect, result);
ReducePhiIterative(expect, phi); // iterative should give the same result.
}
// Checks one-step reduction of a phi.
void ReducePhiNonIterative(Node* expect, Node* phi) {
Node* result = ControlReducer::ReducePhiForTesting(&jsgraph, phi);
CHECK_EQ(expect, result);
}
void ReducePhiIterative(Node* expect, Node* phi) {
p0->ReplaceInput(0, start); // hack: parameters may be trimmed.
Node* ret = graph.NewNode(common.Return(), phi, start, start);
Node* end = graph.NewNode(common.End(1), ret);
graph.SetEnd(end);
ControlReducer::ReduceGraph(main_zone(), &jsgraph);
CheckInputs(end, ret);
CheckInputs(ret, expect, start, start);
}
void ReduceMerge(Node* expect, Node* merge) { void ReduceMerge(Node* expect, Node* merge) {
Node* result = ControlReducer::ReduceMerge(&jsgraph, merge); Node* result = ControlReducer::ReduceMerge(&jsgraph, merge);
CHECK_EQ(expect, result); CHECK_EQ(expect, result);
...@@ -313,271 +290,6 @@ struct DeadChecker { ...@@ -313,271 +290,6 @@ struct DeadChecker {
}; };
TEST(CReducePhi1) {
ControlReducerTester R;
R.ReducePhi(R.leaf[0], R.Phi(R.leaf[0]));
R.ReducePhi(R.leaf[1], R.Phi(R.leaf[1]));
R.ReducePhi(R.leaf[2], R.Phi(R.leaf[2]));
R.ReducePhi(R.leaf[3], R.Phi(R.leaf[3]));
}
TEST(CReducePhi1_dead) {
ControlReducerTester R;
R.ReducePhi(R.leaf[0], R.Phi(R.leaf[0], R.dead));
R.ReducePhi(R.leaf[1], R.Phi(R.leaf[1], R.dead));
R.ReducePhi(R.leaf[2], R.Phi(R.leaf[2], R.dead));
R.ReducePhi(R.leaf[3], R.Phi(R.leaf[3], R.dead));
R.ReducePhi(R.leaf[0], R.Phi(R.dead, R.leaf[0]));
R.ReducePhi(R.leaf[1], R.Phi(R.dead, R.leaf[1]));
R.ReducePhi(R.leaf[2], R.Phi(R.dead, R.leaf[2]));
R.ReducePhi(R.leaf[3], R.Phi(R.dead, R.leaf[3]));
}
TEST(CReducePhi1_dead2) {
ControlReducerTester R;
R.ReducePhi(R.leaf[0], R.Phi(R.leaf[0], R.dead, R.dead));
R.ReducePhi(R.leaf[0], R.Phi(R.dead, R.leaf[0], R.dead));
R.ReducePhi(R.leaf[0], R.Phi(R.dead, R.dead, R.leaf[0]));
}
TEST(CReducePhi2a) {
ControlReducerTester R;
for (size_t i = 0; i < kNumLeafs; i++) {
Node* a = R.leaf[i];
R.ReducePhi(a, R.Phi(a, a));
}
}
TEST(CReducePhi2b) {
ControlReducerTester R;
for (size_t i = 0; i < kNumLeafs; i++) {
Node* a = R.leaf[i];
R.ReducePhi(a, R.Phi(R.self, a));
R.ReducePhi(a, R.Phi(a, R.self));
}
}
TEST(CReducePhi2c) {
ControlReducerTester R;
for (size_t i = 1; i < kNumLeafs; i++) {
Node* a = R.leaf[i], *b = R.leaf[0];
Node* phi1 = R.Phi(b, a);
R.ReducePhi(phi1, phi1);
Node* phi2 = R.Phi(a, b);
R.ReducePhi(phi2, phi2);
}
}
TEST(CReducePhi2_dead) {
ControlReducerTester R;
for (size_t i = 0; i < kNumLeafs; i++) {
Node* a = R.leaf[i];
R.ReducePhi(a, R.Phi(a, a, R.dead));
R.ReducePhi(a, R.Phi(a, R.dead, a));
R.ReducePhi(a, R.Phi(R.dead, a, a));
}
for (size_t i = 0; i < kNumLeafs; i++) {
Node* a = R.leaf[i];
R.ReducePhi(a, R.Phi(R.self, a));
R.ReducePhi(a, R.Phi(a, R.self));
R.ReducePhi(a, R.Phi(R.self, a, R.dead));
R.ReducePhi(a, R.Phi(a, R.self, R.dead));
}
for (size_t i = 1; i < kNumLeafs; i++) {
Node* a = R.leaf[i], *b = R.leaf[0];
Node* phi1 = R.Phi(b, a, R.dead);
R.ReducePhiNonIterative(phi1, phi1);
Node* phi2 = R.Phi(a, b, R.dead);
R.ReducePhiNonIterative(phi2, phi2);
}
}
TEST(CReducePhi3) {
ControlReducerTester R;
for (size_t i = 0; i < kNumLeafs; i++) {
Node* a = R.leaf[i];
R.ReducePhi(a, R.Phi(a, a, a));
}
for (size_t i = 0; i < kNumLeafs; i++) {
Node* a = R.leaf[i];
R.ReducePhi(a, R.Phi(R.self, a, a));
R.ReducePhi(a, R.Phi(a, R.self, a));
R.ReducePhi(a, R.Phi(a, a, R.self));
}
for (size_t i = 1; i < kNumLeafs; i++) {
Node* a = R.leaf[i], *b = R.leaf[0];
Node* phi1 = R.Phi(b, a, a);
R.ReducePhi(phi1, phi1);
Node* phi2 = R.Phi(a, b, a);
R.ReducePhi(phi2, phi2);
Node* phi3 = R.Phi(a, a, b);
R.ReducePhi(phi3, phi3);
}
}
TEST(CReducePhi4) {
ControlReducerTester R;
for (size_t i = 0; i < kNumLeafs; i++) {
Node* a = R.leaf[i];
R.ReducePhi(a, R.Phi(a, a, a, a));
}
for (size_t i = 0; i < kNumLeafs; i++) {
Node* a = R.leaf[i];
R.ReducePhi(a, R.Phi(R.self, a, a, a));
R.ReducePhi(a, R.Phi(a, R.self, a, a));
R.ReducePhi(a, R.Phi(a, a, R.self, a));
R.ReducePhi(a, R.Phi(a, a, a, R.self));
R.ReducePhi(a, R.Phi(R.self, R.self, a, a));
R.ReducePhi(a, R.Phi(a, R.self, R.self, a));
R.ReducePhi(a, R.Phi(a, a, R.self, R.self));
R.ReducePhi(a, R.Phi(R.self, a, a, R.self));
}
for (size_t i = 1; i < kNumLeafs; i++) {
Node* a = R.leaf[i], *b = R.leaf[0];
Node* phi1 = R.Phi(b, a, a, a);
R.ReducePhi(phi1, phi1);
Node* phi2 = R.Phi(a, b, a, a);
R.ReducePhi(phi2, phi2);
Node* phi3 = R.Phi(a, a, b, a);
R.ReducePhi(phi3, phi3);
Node* phi4 = R.Phi(a, a, a, b);
R.ReducePhi(phi4, phi4);
}
}
TEST(CReducePhi_iterative1) {
ControlReducerTester R;
R.ReducePhiIterative(R.leaf[0], R.Phi(R.leaf[0], R.Phi(R.leaf[0])));
R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0]), R.leaf[0]));
}
TEST(CReducePhi_iterative2) {
ControlReducerTester R;
R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0]), R.Phi(R.leaf[0])));
}
TEST(CReducePhi_iterative3) {
ControlReducerTester R;
R.ReducePhiIterative(R.leaf[0],
R.Phi(R.leaf[0], R.Phi(R.leaf[0], R.leaf[0])));
R.ReducePhiIterative(R.leaf[0],
R.Phi(R.Phi(R.leaf[0], R.leaf[0]), R.leaf[0]));
}
TEST(CReducePhi_iterative4) {
ControlReducerTester R;
R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0], R.leaf[0]),
R.Phi(R.leaf[0], R.leaf[0])));
Node* p1 = R.Phi(R.leaf[0], R.leaf[0]);
R.ReducePhiIterative(R.leaf[0], R.Phi(p1, p1));
Node* p2 = R.Phi(R.leaf[0], R.leaf[0], R.leaf[0]);
R.ReducePhiIterative(R.leaf[0], R.Phi(p2, p2, p2));
Node* p3 = R.Phi(R.leaf[0], R.leaf[0], R.leaf[0]);
R.ReducePhiIterative(R.leaf[0], R.Phi(p3, p3, R.leaf[0]));
}
TEST(CReducePhi_iterative_self1) {
ControlReducerTester R;
R.ReducePhiIterative(R.leaf[0], R.Phi(R.leaf[0], R.Phi(R.leaf[0], R.self)));
R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0], R.self), R.leaf[0]));
}
TEST(CReducePhi_iterative_self2) {
ControlReducerTester R;
R.ReducePhiIterative(
R.leaf[0], R.Phi(R.Phi(R.leaf[0], R.self), R.Phi(R.leaf[0], R.self)));
R.ReducePhiIterative(
R.leaf[0], R.Phi(R.Phi(R.self, R.leaf[0]), R.Phi(R.self, R.leaf[0])));
Node* p1 = R.Phi(R.leaf[0], R.self);
R.ReducePhiIterative(R.leaf[0], R.Phi(p1, p1));
Node* p2 = R.Phi(R.self, R.leaf[0]);
R.ReducePhiIterative(R.leaf[0], R.Phi(p2, p2));
}
TEST(EReducePhi1) {
ControlReducerTester R;
R.ReducePhi(R.leaf[0], R.EffectPhi(R.leaf[0]));
R.ReducePhi(R.leaf[1], R.EffectPhi(R.leaf[1]));
R.ReducePhi(R.leaf[2], R.EffectPhi(R.leaf[2]));
R.ReducePhi(R.leaf[3], R.EffectPhi(R.leaf[3]));
}
TEST(EReducePhi1_dead) {
ControlReducerTester R;
R.ReducePhi(R.leaf[0], R.EffectPhi(R.leaf[0], R.dead));
R.ReducePhi(R.leaf[1], R.EffectPhi(R.leaf[1], R.dead));
R.ReducePhi(R.leaf[2], R.EffectPhi(R.leaf[2], R.dead));
R.ReducePhi(R.leaf[3], R.EffectPhi(R.leaf[3], R.dead));
R.ReducePhi(R.leaf[0], R.EffectPhi(R.dead, R.leaf[0]));
R.ReducePhi(R.leaf[1], R.EffectPhi(R.dead, R.leaf[1]));
R.ReducePhi(R.leaf[2], R.EffectPhi(R.dead, R.leaf[2]));
R.ReducePhi(R.leaf[3], R.EffectPhi(R.dead, R.leaf[3]));
}
TEST(EReducePhi1_dead2) {
ControlReducerTester R;
R.ReducePhi(R.leaf[0], R.EffectPhi(R.leaf[0], R.dead, R.dead));
R.ReducePhi(R.leaf[0], R.EffectPhi(R.dead, R.leaf[0], R.dead));
R.ReducePhi(R.leaf[0], R.EffectPhi(R.dead, R.dead, R.leaf[0]));
}
TEST(CMergeReduce_simple1) { TEST(CMergeReduce_simple1) {
ControlReducerTester R; ControlReducerTester R;
...@@ -982,17 +694,6 @@ TEST(CChainedDiamondsReduce_phi1) { ...@@ -982,17 +694,6 @@ TEST(CChainedDiamondsReduce_phi1) {
} }
TEST(CChainedDiamondsReduce_phi2) {
ControlReducerTester R;
Diamond d1(R, R.p0, R.jsgraph.TrueConstant(),
R.jsgraph.TrueConstant()); // redundant phi.
Diamond d2(R, d1.phi);
d2.chain(d1);
R.ReduceMergeIterative(d1.merge, d2.merge);
}
TEST(CNestedDiamondsReduce_true_true_false) { TEST(CNestedDiamondsReduce_true_true_false) {
ControlReducerTester R; ControlReducerTester R;
Diamond d1(R, R.jsgraph.TrueConstant()); Diamond d1(R, R.jsgraph.TrueConstant());
......
...@@ -4,14 +4,16 @@ ...@@ -4,14 +4,16 @@
#include "src/compiler/common-operator.h" #include "src/compiler/common-operator.h"
#include "src/compiler/common-operator-reducer.h" #include "src/compiler/common-operator-reducer.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/js-operator.h" #include "src/compiler/js-operator.h"
#include "src/compiler/machine-operator.h" #include "src/compiler/machine-operator.h"
#include "src/compiler/machine-type.h" #include "src/compiler/machine-type.h"
#include "src/compiler/operator.h" #include "src/compiler/operator.h"
#include "test/unittests/compiler/graph-reducer-unittest.h"
#include "test/unittests/compiler/graph-unittest.h" #include "test/unittests/compiler/graph-unittest.h"
#include "test/unittests/compiler/node-test-utils.h" #include "test/unittests/compiler/node-test-utils.h"
using testing::StrictMock;
namespace v8 { namespace v8 {
namespace internal { namespace internal {
namespace compiler { namespace compiler {
...@@ -23,15 +25,21 @@ class CommonOperatorReducerTest : public GraphTest { ...@@ -23,15 +25,21 @@ class CommonOperatorReducerTest : public GraphTest {
~CommonOperatorReducerTest() override {} ~CommonOperatorReducerTest() override {}
protected: protected:
Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags = Reduction Reduce(
MachineOperatorBuilder::kNoFlags) { AdvancedReducer::Editor* editor, Node* node,
MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags) {
JSOperatorBuilder javascript(zone()); JSOperatorBuilder javascript(zone());
MachineOperatorBuilder machine(zone(), kMachPtr, flags); MachineOperatorBuilder machine(zone(), kMachPtr, flags);
JSGraph jsgraph(isolate(), graph(), common(), &javascript, &machine); CommonOperatorReducer reducer(editor, graph(), common(), &machine);
CommonOperatorReducer reducer(&jsgraph);
return reducer.Reduce(node); return reducer.Reduce(node);
} }
Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags =
MachineOperatorBuilder::kNoFlags) {
StrictMock<MockAdvancedReducerEditor> editor;
return Reduce(&editor, node, flags);
}
MachineOperatorBuilder* machine() { return &machine_; } MachineOperatorBuilder* machine() { return &machine_; }
private: private:
...@@ -61,29 +69,52 @@ const Operator kOp0(0, Operator::kNoProperties, "Op0", 0, 0, 0, 1, 1, 0); ...@@ -61,29 +69,52 @@ const Operator kOp0(0, Operator::kNoProperties, "Op0", 0, 0, 0, 1, 1, 0);
// EffectPhi // EffectPhi
TEST_F(CommonOperatorReducerTest, RedundantEffectPhi) { TEST_F(CommonOperatorReducerTest, EffectPhiWithMerge) {
const int kMaxInputs = 64; const int kMaxInputs = 64;
Node* inputs[kMaxInputs]; Node* inputs[kMaxInputs];
Node* const input = graph()->NewNode(&kOp0); Node* const input = graph()->NewNode(&kOp0);
TRACED_FORRANGE(int, input_count, 2, kMaxInputs - 1) { TRACED_FORRANGE(int, input_count, 2, kMaxInputs - 1) {
int const value_input_count = input_count - 1; int const value_input_count = input_count - 1;
for (int i = 0; i < value_input_count; ++i) {
inputs[i] = graph()->start();
}
Node* const merge = graph()->NewNode(common()->Merge(value_input_count),
value_input_count, inputs);
for (int i = 0; i < value_input_count; ++i) { for (int i = 0; i < value_input_count; ++i) {
inputs[i] = input; inputs[i] = input;
} }
inputs[value_input_count] = graph()->start(); inputs[value_input_count] = merge;
Reduction r = Reduce(graph()->NewNode( StrictMock<MockAdvancedReducerEditor> editor;
common()->EffectPhi(value_input_count), input_count, inputs)); EXPECT_CALL(editor, Revisit(merge));
Reduction r =
Reduce(&editor, graph()->NewNode(common()->EffectPhi(value_input_count),
input_count, inputs));
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
EXPECT_EQ(input, r.replacement()); EXPECT_EQ(input, r.replacement());
} }
} }
TEST_F(CommonOperatorReducerTest, EffectPhiWithLoop) {
Node* const e0 = graph()->NewNode(&kOp0);
Node* const loop =
graph()->NewNode(common()->Loop(2), graph()->start(), graph()->start());
loop->ReplaceInput(1, loop);
Node* const ephi = graph()->NewNode(common()->EffectPhi(2), e0, e0, loop);
ephi->ReplaceInput(1, ephi);
StrictMock<MockAdvancedReducerEditor> editor;
EXPECT_CALL(editor, Revisit(loop));
Reduction const r = Reduce(&editor, ephi);
ASSERT_TRUE(r.Changed());
EXPECT_EQ(e0, r.replacement());
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Phi // Phi
TEST_F(CommonOperatorReducerTest, RedundantPhi) { TEST_F(CommonOperatorReducerTest, PhiWithMerge) {
const int kMaxInputs = 64; const int kMaxInputs = 64;
Node* inputs[kMaxInputs]; Node* inputs[kMaxInputs];
Node* const input = graph()->NewNode(&kOp0); Node* const input = graph()->NewNode(&kOp0);
...@@ -93,14 +124,17 @@ TEST_F(CommonOperatorReducerTest, RedundantPhi) { ...@@ -93,14 +124,17 @@ TEST_F(CommonOperatorReducerTest, RedundantPhi) {
for (int i = 0; i < value_input_count; ++i) { for (int i = 0; i < value_input_count; ++i) {
inputs[i] = graph()->start(); inputs[i] = graph()->start();
} }
Node* merge = graph()->NewNode(common()->Merge(value_input_count), Node* const merge = graph()->NewNode(common()->Merge(value_input_count),
value_input_count, inputs); value_input_count, inputs);
for (int i = 0; i < value_input_count; ++i) { for (int i = 0; i < value_input_count; ++i) {
inputs[i] = input; inputs[i] = input;
} }
inputs[value_input_count] = merge; inputs[value_input_count] = merge;
Reduction r = Reduce(graph()->NewNode( StrictMock<MockAdvancedReducerEditor> editor;
common()->Phi(type, value_input_count), input_count, inputs)); EXPECT_CALL(editor, Revisit(merge));
Reduction r = Reduce(
&editor, graph()->NewNode(common()->Phi(type, value_input_count),
input_count, inputs));
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
EXPECT_EQ(input, r.replacement()); EXPECT_EQ(input, r.replacement());
} }
...@@ -108,6 +142,22 @@ TEST_F(CommonOperatorReducerTest, RedundantPhi) { ...@@ -108,6 +142,22 @@ TEST_F(CommonOperatorReducerTest, RedundantPhi) {
} }
TEST_F(CommonOperatorReducerTest, PhiWithLoop) {
Node* const p0 = Parameter(0);
Node* const loop =
graph()->NewNode(common()->Loop(2), graph()->start(), graph()->start());
loop->ReplaceInput(1, loop);
Node* const phi =
graph()->NewNode(common()->Phi(kMachAnyTagged, 2), p0, p0, loop);
phi->ReplaceInput(1, phi);
StrictMock<MockAdvancedReducerEditor> editor;
EXPECT_CALL(editor, Revisit(loop));
Reduction const r = Reduce(&editor, phi);
ASSERT_TRUE(r.Changed());
EXPECT_EQ(p0, r.replacement());
}
TEST_F(CommonOperatorReducerTest, PhiToFloat32Abs) { TEST_F(CommonOperatorReducerTest, PhiToFloat32Abs) {
Node* p0 = Parameter(0); Node* p0 = Parameter(0);
Node* c0 = Float32Constant(0.0); Node* c0 = Float32Constant(0.0);
...@@ -120,7 +170,9 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat32Abs) { ...@@ -120,7 +170,9 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat32Abs) {
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
Node* phi = Node* phi =
graph()->NewNode(common()->Phi(kMachFloat32, 2), vtrue, vfalse, merge); graph()->NewNode(common()->Phi(kMachFloat32, 2), vtrue, vfalse, merge);
Reduction r = Reduce(phi); StrictMock<MockAdvancedReducerEditor> editor;
EXPECT_CALL(editor, Revisit(merge));
Reduction r = Reduce(&editor, phi);
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFloat32Abs(p0)); EXPECT_THAT(r.replacement(), IsFloat32Abs(p0));
} }
...@@ -138,7 +190,9 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat64Abs) { ...@@ -138,7 +190,9 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat64Abs) {
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
Node* phi = Node* phi =
graph()->NewNode(common()->Phi(kMachFloat64, 2), vtrue, vfalse, merge); graph()->NewNode(common()->Phi(kMachFloat64, 2), vtrue, vfalse, merge);
Reduction r = Reduce(phi); StrictMock<MockAdvancedReducerEditor> editor;
EXPECT_CALL(editor, Revisit(merge));
Reduction r = Reduce(&editor, phi);
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFloat64Abs(p0)); EXPECT_THAT(r.replacement(), IsFloat64Abs(p0));
} }
...@@ -153,7 +207,9 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat32Max) { ...@@ -153,7 +207,9 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat32Max) {
Node* if_false = graph()->NewNode(common()->IfFalse(), branch); Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
Node* phi = graph()->NewNode(common()->Phi(kMachFloat32, 2), p1, p0, merge); Node* phi = graph()->NewNode(common()->Phi(kMachFloat32, 2), p1, p0, merge);
Reduction r = Reduce(phi, MachineOperatorBuilder::kFloat32Max); StrictMock<MockAdvancedReducerEditor> editor;
EXPECT_CALL(editor, Revisit(merge));
Reduction r = Reduce(&editor, phi, MachineOperatorBuilder::kFloat32Max);
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFloat32Max(p1, p0)); EXPECT_THAT(r.replacement(), IsFloat32Max(p1, p0));
} }
...@@ -168,7 +224,9 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat64Max) { ...@@ -168,7 +224,9 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat64Max) {
Node* if_false = graph()->NewNode(common()->IfFalse(), branch); Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
Node* phi = graph()->NewNode(common()->Phi(kMachFloat64, 2), p1, p0, merge); Node* phi = graph()->NewNode(common()->Phi(kMachFloat64, 2), p1, p0, merge);
Reduction r = Reduce(phi, MachineOperatorBuilder::kFloat64Max); StrictMock<MockAdvancedReducerEditor> editor;
EXPECT_CALL(editor, Revisit(merge));
Reduction r = Reduce(&editor, phi, MachineOperatorBuilder::kFloat64Max);
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFloat64Max(p1, p0)); EXPECT_THAT(r.replacement(), IsFloat64Max(p1, p0));
} }
...@@ -183,7 +241,9 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat32Min) { ...@@ -183,7 +241,9 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat32Min) {
Node* if_false = graph()->NewNode(common()->IfFalse(), branch); Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
Node* phi = graph()->NewNode(common()->Phi(kMachFloat32, 2), p0, p1, merge); Node* phi = graph()->NewNode(common()->Phi(kMachFloat32, 2), p0, p1, merge);
Reduction r = Reduce(phi, MachineOperatorBuilder::kFloat32Min); StrictMock<MockAdvancedReducerEditor> editor;
EXPECT_CALL(editor, Revisit(merge));
Reduction r = Reduce(&editor, phi, MachineOperatorBuilder::kFloat32Min);
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFloat32Min(p0, p1)); EXPECT_THAT(r.replacement(), IsFloat32Min(p0, p1));
} }
...@@ -198,7 +258,9 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat64Min) { ...@@ -198,7 +258,9 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat64Min) {
Node* if_false = graph()->NewNode(common()->IfFalse(), branch); Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
Node* phi = graph()->NewNode(common()->Phi(kMachFloat64, 2), p0, p1, merge); Node* phi = graph()->NewNode(common()->Phi(kMachFloat64, 2), p0, p1, merge);
Reduction r = Reduce(phi, MachineOperatorBuilder::kFloat64Min); StrictMock<MockAdvancedReducerEditor> editor;
EXPECT_CALL(editor, Revisit(merge));
Reduction r = Reduce(&editor, phi, MachineOperatorBuilder::kFloat64Min);
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFloat64Min(p0, p1)); EXPECT_THAT(r.replacement(), IsFloat64Min(p0, p1));
} }
...@@ -208,7 +270,7 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat64Min) { ...@@ -208,7 +270,7 @@ TEST_F(CommonOperatorReducerTest, PhiToFloat64Min) {
// Select // Select
TEST_F(CommonOperatorReducerTest, RedundantSelect) { TEST_F(CommonOperatorReducerTest, SelectWithSameThenAndElse) {
Node* const input = graph()->NewNode(&kOp0); Node* const input = graph()->NewNode(&kOp0);
TRACED_FOREACH(BranchHint, hint, kBranchHints) { TRACED_FOREACH(BranchHint, hint, kBranchHints) {
TRACED_FOREACH(MachineType, type, kMachineTypes) { TRACED_FOREACH(MachineType, type, kMachineTypes) {
......
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