Index: src/compiler/common-operator-reducer.cc |
diff --git a/src/compiler/common-operator-reducer.cc b/src/compiler/common-operator-reducer.cc |
index c3cbcdefc7be70234035d507228c593cd049a638..b07383d21c5ed7b554273d24f98d933ab8808d98 100644 |
--- a/src/compiler/common-operator-reducer.cc |
+++ b/src/compiler/common-operator-reducer.cc |
@@ -4,8 +4,12 @@ |
#include "src/compiler/common-operator-reducer.h" |
+#include <algorithm> |
+ |
#include "src/compiler/common-operator.h" |
+#include "src/compiler/js-graph.h" |
#include "src/compiler/node.h" |
+#include "src/compiler/node-matchers.h" |
namespace v8 { |
namespace internal { |
@@ -14,29 +18,119 @@ namespace compiler { |
Reduction CommonOperatorReducer::Reduce(Node* node) { |
switch (node->opcode()) { |
case IrOpcode::kEffectPhi: |
- case IrOpcode::kPhi: { |
- int const input_count = node->InputCount(); |
- if (input_count > 1) { |
- Node* const replacement = node->InputAt(0); |
- for (int i = 1; i < input_count - 1; ++i) { |
- if (node->InputAt(i) != replacement) return NoChange(); |
- } |
- return Replace(replacement); |
- } |
+ return ReduceEffectPhi(node); |
+ case IrOpcode::kPhi: |
+ return ReducePhi(node); |
+ case IrOpcode::kSelect: |
+ return ReduceSelect(node); |
+ default: |
break; |
+ } |
+ return NoChange(); |
+} |
+ |
+ |
+Reduction CommonOperatorReducer::ReduceEffectPhi(Node* node) { |
+ DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode()); |
+ int const input_count = node->InputCount(); |
+ if (input_count > 1) { |
+ Node* const replacement = node->InputAt(0); |
+ for (int i = 1; i < input_count - 1; ++i) { |
+ if (node->InputAt(i) != replacement) return NoChange(); |
} |
- case IrOpcode::kSelect: { |
- if (node->InputAt(1) == node->InputAt(2)) { |
- return Replace(node->InputAt(1)); |
+ return Replace(replacement); |
+ } |
+ return NoChange(); |
+} |
+ |
+ |
+Reduction CommonOperatorReducer::ReducePhi(Node* node) { |
+ DCHECK_EQ(IrOpcode::kPhi, node->opcode()); |
+ int const input_count = node->InputCount(); |
+ if (input_count == 3) { |
+ Node* vtrue = NodeProperties::GetValueInput(node, 0); |
+ Node* vfalse = NodeProperties::GetValueInput(node, 1); |
+ Node* merge = NodeProperties::GetControlInput(node); |
+ Node* if_true = NodeProperties::GetControlInput(merge, 0); |
+ Node* if_false = NodeProperties::GetControlInput(merge, 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* branch = if_true->InputAt(0); |
+ Node* cond = branch->InputAt(0); |
+ if (cond->opcode() == IrOpcode::kFloat64LessThan) { |
+ if (cond->InputAt(0) == vtrue && cond->InputAt(1) == vfalse && |
+ machine()->HasFloat64Min()) { |
+ node->set_op(machine()->Float64Min()); |
+ node->ReplaceInput(0, vtrue); |
+ node->ReplaceInput(1, vfalse); |
+ node->TrimInputCount(2); |
+ return Changed(node); |
+ } else if (cond->InputAt(0) == vfalse && cond->InputAt(1) == vtrue && |
+ machine()->HasFloat64Max()) { |
+ node->set_op(machine()->Float64Max()); |
+ node->ReplaceInput(0, vtrue); |
+ node->ReplaceInput(1, vfalse); |
+ node->TrimInputCount(2); |
+ return Changed(node); |
+ } |
} |
- break; |
} |
- default: |
- break; |
+ } |
+ if (input_count > 1) { |
+ Node* const replacement = node->InputAt(0); |
+ for (int i = 1; i < input_count - 1; ++i) { |
+ if (node->InputAt(i) != replacement) return NoChange(); |
+ } |
+ return Replace(replacement); |
+ } |
+ return NoChange(); |
+} |
+ |
+ |
+Reduction CommonOperatorReducer::ReduceSelect(Node* node) { |
+ DCHECK_EQ(IrOpcode::kSelect, node->opcode()); |
+ Node* cond = NodeProperties::GetValueInput(node, 0); |
+ Node* vtrue = NodeProperties::GetValueInput(node, 1); |
+ Node* vfalse = NodeProperties::GetValueInput(node, 2); |
+ if (vtrue == vfalse) return Replace(vtrue); |
+ if (cond->opcode() == IrOpcode::kFloat64LessThan) { |
+ if (cond->InputAt(0) == vtrue && cond->InputAt(1) == vfalse && |
+ machine()->HasFloat64Min()) { |
+ node->set_op(machine()->Float64Min()); |
+ node->ReplaceInput(0, vtrue); |
+ node->ReplaceInput(1, vfalse); |
+ node->TrimInputCount(2); |
+ return Changed(node); |
+ } else if (cond->InputAt(0) == vfalse && cond->InputAt(1) == vtrue && |
+ machine()->HasFloat64Max()) { |
+ node->set_op(machine()->Float64Max()); |
+ node->ReplaceInput(0, vtrue); |
+ node->ReplaceInput(1, vfalse); |
+ node->TrimInputCount(2); |
+ return Changed(node); |
+ } |
} |
return NoChange(); |
} |
+ |
+CommonOperatorBuilder* CommonOperatorReducer::common() const { |
+ return jsgraph()->common(); |
+} |
+ |
+ |
+Graph* CommonOperatorReducer::graph() const { return jsgraph()->graph(); } |
+ |
+ |
+MachineOperatorBuilder* CommonOperatorReducer::machine() const { |
+ return jsgraph()->machine(); |
+} |
+ |
} // namespace compiler |
} // namespace internal |
} // namespace v8 |