Chromium Code Reviews| Index: src/compiler/redundancy-elimination.cc |
| diff --git a/src/compiler/redundancy-elimination.cc b/src/compiler/redundancy-elimination.cc |
| index 4c50b19fa52dc8e5bc48b527ed4c23afb3bafbe0..d9cfa92481aba6b553f32274692ddc4e4a5b59b2 100644 |
| --- a/src/compiler/redundancy-elimination.cc |
| +++ b/src/compiler/redundancy-elimination.cc |
| @@ -34,6 +34,16 @@ Reduction RedundancyElimination::Reduce(Node* node) { |
| case IrOpcode::kCheckedTaggedToInt32: |
| case IrOpcode::kCheckedUint32ToInt32: |
| return ReduceCheckNode(node); |
| + case IrOpcode::kSpeculativeNumberAdd: |
| + case IrOpcode::kSpeculativeNumberSubtract: |
| + case IrOpcode::kSpeculativeNumberMultiply: |
| + case IrOpcode::kSpeculativeNumberModulus: |
| + case IrOpcode::kSpeculativeNumberDivide: |
| + case IrOpcode::kSpeculativeNumberShiftLeft: |
| + case IrOpcode::kSpeculativeNumberEqual: |
| + case IrOpcode::kSpeculativeNumberLessThan: |
| + case IrOpcode::kSpeculativeNumberLessThanOrEqual: |
| + return ReduceSpeculativeNode(node); |
| case IrOpcode::kEffectPhi: |
| return ReduceEffectPhi(node); |
| case IrOpcode::kDead: |
| @@ -119,11 +129,22 @@ bool IsCompatibleCheck(Node const* a, Node const* b) { |
| return true; |
| } |
| +bool IsCompatibleSpeculative(Node const* a, Node const* b) { |
| + if (a->opcode() != b->opcode()) return false; |
| + DCHECK_EQ(a->InputCount(), b->InputCount()); |
| + for (int i = a->op()->ValueInputCount(); --i >= 0;) { |
| + if (a->InputAt(i) != b->InputAt(i)) return false; |
| + } |
| + return true; |
| +} |
| + |
| } // namespace |
| -Node* RedundancyElimination::EffectPathChecks::LookupCheck(Node* node) const { |
| +template <typename Predicate> |
|
Jarin
2016/07/26 09:39:21
Do we really need to have templates for this? How
|
| +Node* RedundancyElimination::EffectPathChecks::LookupCheck( |
| + Node* node, Predicate predicate) const { |
| for (Check const* check = head_; check != nullptr; check = check->next) { |
| - if (IsCompatibleCheck(check->node, node)) { |
| + if (predicate(check->node, node)) { |
| DCHECK(!check->node->IsDead()); |
| return check->node; |
| } |
| @@ -152,7 +173,7 @@ Reduction RedundancyElimination::ReduceCheckNode(Node* node) { |
| // because we will have to recompute anyway once we compute the predecessor. |
| if (checks == nullptr) return NoChange(); |
| // See if we have another check that dominates us. |
| - if (Node* check = checks->LookupCheck(node)) { |
| + if (Node* check = checks->LookupCheck(node, IsCompatibleCheck)) { |
| ReplaceWithValue(node, check); |
| return Replace(check); |
| } |
| @@ -160,6 +181,21 @@ Reduction RedundancyElimination::ReduceCheckNode(Node* node) { |
| return UpdateChecks(node, checks->AddCheck(zone(), node)); |
| } |
| +Reduction RedundancyElimination::ReduceSpeculativeNode(Node* node) { |
| + Node* const effect = NodeProperties::GetEffectInput(node); |
| + EffectPathChecks const* checks = node_checks_.Get(effect); |
| + // If we do not know anything about the predecessor, do not propagate just yet |
| + // because we will have to recompute anyway once we compute the predecessor. |
| + if (checks == nullptr) return NoChange(); |
| + // See if we have another speculative {node} that dominates us. |
| + if (Node* check = checks->LookupCheck(node, IsCompatibleSpeculative)) { |
| + ReplaceWithValue(node, check); |
| + return Replace(check); |
| + } |
| + // Learn from this speculative {node}. |
| + return UpdateChecks(node, checks->AddCheck(zone(), node)); |
| +} |
| + |
| Reduction RedundancyElimination::ReduceEffectPhi(Node* node) { |
| Node* const control = NodeProperties::GetControlInput(node); |
| if (control->opcode() == IrOpcode::kLoop) { |