LCOV - code coverage report
Current view: top level - src/compiler - simplified-operator-reducer.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 69 83 83.1 %
Date: 2019-04-17 Functions: 4 13 30.8 %

          Line data    Source code
       1             : // Copyright 2014 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/compiler/simplified-operator-reducer.h"
       6             : 
       7             : #include "src/compiler/js-graph.h"
       8             : #include "src/compiler/machine-operator.h"
       9             : #include "src/compiler/node-matchers.h"
      10             : #include "src/compiler/operator-properties.h"
      11             : #include "src/compiler/simplified-operator.h"
      12             : #include "src/compiler/type-cache.h"
      13             : #include "src/conversions-inl.h"
      14             : 
      15             : namespace v8 {
      16             : namespace internal {
      17             : namespace compiler {
      18             : 
      19             : namespace {
      20             : 
      21       90583 : Decision DecideObjectIsSmi(Node* const input) {
      22             :   NumberMatcher m(input);
      23       90583 :   if (m.HasValue()) {
      24       15548 :     return IsSmiDouble(m.Value()) ? Decision::kTrue : Decision::kFalse;
      25             :   }
      26       75035 :   if (m.IsAllocate()) return Decision::kFalse;
      27       75035 :   if (m.IsChangeBitToTagged()) return Decision::kFalse;
      28       75033 :   if (m.IsChangeInt31ToTaggedSigned()) return Decision::kTrue;
      29       75031 :   if (m.IsHeapConstant()) return Decision::kFalse;
      30       74950 :   return Decision::kUnknown;
      31             : }
      32             : 
      33             : }  // namespace
      34             : 
      35      929001 : SimplifiedOperatorReducer::SimplifiedOperatorReducer(Editor* editor,
      36             :                                                      JSGraph* jsgraph,
      37             :                                                      JSHeapBroker* broker)
      38      929001 :     : AdvancedReducer(editor), jsgraph_(jsgraph), broker_(broker) {}
      39             : 
      40             : SimplifiedOperatorReducer::~SimplifiedOperatorReducer() = default;
      41             : 
      42             : 
      43    89281125 : Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
      44             :   DisallowHeapAccess no_heap_access;
      45    89281125 :   switch (node->opcode()) {
      46             :     case IrOpcode::kBooleanNot: {
      47             :       // TODO(neis): Provide HeapObjectRefMatcher?
      48             :       HeapObjectMatcher m(node->InputAt(0));
      49       13504 :       if (m.Is(factory()->true_value())) return ReplaceBoolean(false);
      50       13429 :       if (m.Is(factory()->false_value())) return ReplaceBoolean(true);
      51        9352 :       if (m.IsBooleanNot()) return Replace(m.InputAt(0));
      52             :       break;
      53             :     }
      54             :     case IrOpcode::kChangeBitToTagged: {
      55             :       Int32Matcher m(node->InputAt(0));
      56       10524 :       if (m.Is(0)) return Replace(jsgraph()->FalseConstant());
      57       10239 :       if (m.Is(1)) return Replace(jsgraph()->TrueConstant());
      58        9715 :       if (m.IsChangeTaggedToBit()) return Replace(m.InputAt(0));
      59             :       break;
      60             :     }
      61             :     case IrOpcode::kChangeTaggedToBit: {
      62             :       HeapObjectMatcher m(node->InputAt(0));
      63      164197 :       if (m.HasValue()) {
      64           4 :         return ReplaceInt32(m.Ref(broker()).BooleanValue());
      65             :       }
      66      164195 :       if (m.IsChangeBitToTagged()) return Replace(m.InputAt(0));
      67             :       break;
      68             :     }
      69             :     case IrOpcode::kChangeFloat64ToTagged: {
      70             :       Float64Matcher m(node->InputAt(0));
      71       71510 :       if (m.HasValue()) return ReplaceNumber(m.Value());
      72       69887 :       if (m.IsChangeTaggedToFloat64()) return Replace(m.node()->InputAt(0));
      73             :       break;
      74             :     }
      75             :     case IrOpcode::kChangeInt31ToTaggedSigned:
      76             :     case IrOpcode::kChangeInt32ToTagged: {
      77             :       Int32Matcher m(node->InputAt(0));
      78       91653 :       if (m.HasValue()) return ReplaceNumber(m.Value());
      79       89662 :       if (m.IsChangeTaggedToInt32() || m.IsChangeTaggedSignedToInt32()) {
      80             :         return Replace(m.InputAt(0));
      81             :       }
      82             :       break;
      83             :     }
      84             :     case IrOpcode::kChangeTaggedToFloat64:
      85             :     case IrOpcode::kTruncateTaggedToFloat64: {
      86             :       NumberMatcher m(node->InputAt(0));
      87       13431 :       if (m.HasValue()) return ReplaceFloat64(m.Value());
      88       13306 :       if (m.IsChangeFloat64ToTagged() || m.IsChangeFloat64ToTaggedPointer()) {
      89             :         return Replace(m.node()->InputAt(0));
      90             :       }
      91       13248 :       if (m.IsChangeInt31ToTaggedSigned() || m.IsChangeInt32ToTagged()) {
      92           1 :         return Change(node, machine()->ChangeInt32ToFloat64(), m.InputAt(0));
      93             :       }
      94       13247 :       if (m.IsChangeUint32ToTagged()) {
      95           1 :         return Change(node, machine()->ChangeUint32ToFloat64(), m.InputAt(0));
      96             :       }
      97             :       break;
      98             :     }
      99             :     case IrOpcode::kChangeTaggedSignedToInt32:
     100             :     case IrOpcode::kChangeTaggedToInt32: {
     101             :       NumberMatcher m(node->InputAt(0));
     102       98030 :       if (m.HasValue()) return ReplaceInt32(DoubleToInt32(m.Value()));
     103       97994 :       if (m.IsChangeFloat64ToTagged() || m.IsChangeFloat64ToTaggedPointer()) {
     104           2 :         return Change(node, machine()->ChangeFloat64ToInt32(), m.InputAt(0));
     105             :       }
     106       97992 :       if (m.IsChangeInt31ToTaggedSigned() || m.IsChangeInt32ToTagged()) {
     107             :         return Replace(m.InputAt(0));
     108             :       }
     109             :       break;
     110             :     }
     111             :     case IrOpcode::kChangeTaggedToUint32: {
     112             :       NumberMatcher m(node->InputAt(0));
     113         670 :       if (m.HasValue()) return ReplaceUint32(DoubleToUint32(m.Value()));
     114         633 :       if (m.IsChangeFloat64ToTagged() || m.IsChangeFloat64ToTaggedPointer()) {
     115           2 :         return Change(node, machine()->ChangeFloat64ToUint32(), m.InputAt(0));
     116             :       }
     117         631 :       if (m.IsChangeUint32ToTagged()) return Replace(m.InputAt(0));
     118             :       break;
     119             :     }
     120             :     case IrOpcode::kChangeUint32ToTagged: {
     121             :       Uint32Matcher m(node->InputAt(0));
     122         762 :       if (m.HasValue()) return ReplaceNumber(FastUI2D(m.Value()));
     123             :       break;
     124             :     }
     125             :     case IrOpcode::kTruncateTaggedToWord32: {
     126             :       NumberMatcher m(node->InputAt(0));
     127         948 :       if (m.HasValue()) return ReplaceInt32(DoubleToInt32(m.Value()));
     128         841 :       if (m.IsChangeInt31ToTaggedSigned() || m.IsChangeInt32ToTagged() ||
     129             :           m.IsChangeUint32ToTagged()) {
     130             :         return Replace(m.InputAt(0));
     131             :       }
     132         841 :       if (m.IsChangeFloat64ToTagged() || m.IsChangeFloat64ToTaggedPointer()) {
     133           2 :         return Change(node, machine()->TruncateFloat64ToWord32(), m.InputAt(0));
     134             :       }
     135             :       break;
     136             :     }
     137             :     case IrOpcode::kCheckedFloat64ToInt32: {
     138             :       Float64Matcher m(node->InputAt(0));
     139        5040 :       if (m.HasValue() && IsInt32Double(m.Value())) {
     140         100 :         Node* value = jsgraph()->Int32Constant(static_cast<int32_t>(m.Value()));
     141             :         ReplaceWithValue(node, value);
     142             :         return Replace(value);
     143             :       }
     144             :       break;
     145             :     }
     146             :     case IrOpcode::kCheckedTaggedToInt32:
     147             :     case IrOpcode::kCheckedTaggedSignedToInt32: {
     148             :       NodeMatcher m(node->InputAt(0));
     149      236102 :       if (m.IsConvertTaggedHoleToUndefined()) {
     150         111 :         node->ReplaceInput(0, m.InputAt(0));
     151             :         return Changed(node);
     152             :       }
     153             :       break;
     154             :     }
     155             :     case IrOpcode::kCheckIf: {
     156             :       HeapObjectMatcher m(node->InputAt(0));
     157       56806 :       if (m.Is(factory()->true_value())) {
     158         718 :         Node* const effect = NodeProperties::GetEffectInput(node);
     159             :         return Replace(effect);
     160             :       }
     161             :       break;
     162             :     }
     163             :     case IrOpcode::kCheckNumber: {
     164             :       NodeMatcher m(node->InputAt(0));
     165        2543 :       if (m.IsConvertTaggedHoleToUndefined()) {
     166           0 :         node->ReplaceInput(0, m.InputAt(0));
     167             :         return Changed(node);
     168             :       }
     169             :       break;
     170             :     }
     171             :     case IrOpcode::kCheckHeapObject: {
     172             :       Node* const input = node->InputAt(0);
     173       41666 :       if (DecideObjectIsSmi(input) == Decision::kFalse) {
     174             :         ReplaceWithValue(node, input);
     175             :         return Replace(input);
     176             :       }
     177             :       NodeMatcher m(input);
     178       41661 :       if (m.IsCheckHeapObject()) {
     179             :         ReplaceWithValue(node, input);
     180             :         return Replace(input);
     181             :       }
     182             :       break;
     183             :     }
     184             :     case IrOpcode::kCheckSmi: {
     185             :       Node* const input = node->InputAt(0);
     186       43023 :       if (DecideObjectIsSmi(input) == Decision::kTrue) {
     187             :         ReplaceWithValue(node, input);
     188             :         return Replace(input);
     189             :       }
     190             :       NodeMatcher m(input);
     191       27629 :       if (m.IsCheckSmi()) {
     192             :         ReplaceWithValue(node, input);
     193             :         return Replace(input);
     194       27628 :       } else if (m.IsConvertTaggedHoleToUndefined()) {
     195          21 :         node->ReplaceInput(0, m.InputAt(0));
     196             :         return Changed(node);
     197             :       }
     198             :       break;
     199             :     }
     200             :     case IrOpcode::kObjectIsSmi: {
     201             :       Node* const input = node->InputAt(0);
     202        5894 :       switch (DecideObjectIsSmi(input)) {
     203             :         case Decision::kTrue:
     204             :           return ReplaceBoolean(true);
     205             :         case Decision::kFalse:
     206             :           return ReplaceBoolean(false);
     207             :         case Decision::kUnknown:
     208             :           break;
     209             :       }
     210             :       break;
     211             :     }
     212             :     case IrOpcode::kNumberAbs: {
     213             :       NumberMatcher m(node->InputAt(0));
     214         492 :       if (m.HasValue()) return ReplaceNumber(std::fabs(m.Value()));
     215             :       break;
     216             :     }
     217             :     case IrOpcode::kReferenceEqual: {
     218      212190 :       HeapObjectBinopMatcher m(node);
     219      212406 :       if (m.left().node() == m.right().node()) return ReplaceBoolean(true);
     220      211974 :       break;
     221             :     }
     222             :     default:
     223             :       break;
     224             :   }
     225             :   return NoChange();
     226             : }
     227             : 
     228           0 : Reduction SimplifiedOperatorReducer::Change(Node* node, const Operator* op,
     229             :                                             Node* a) {
     230             :   DCHECK_EQ(node->InputCount(), OperatorProperties::GetTotalInputCount(op));
     231             :   DCHECK_LE(1, node->InputCount());
     232           8 :   node->ReplaceInput(0, a);
     233           8 :   NodeProperties::ChangeOp(node, op);
     234           0 :   return Changed(node);
     235             : }
     236             : 
     237           0 : Reduction SimplifiedOperatorReducer::ReplaceBoolean(bool value) {
     238           0 :   return Replace(jsgraph()->BooleanConstant(value));
     239             : }
     240             : 
     241           0 : Reduction SimplifiedOperatorReducer::ReplaceFloat64(double value) {
     242         125 :   return Replace(jsgraph()->Float64Constant(value));
     243             : }
     244             : 
     245             : 
     246           0 : Reduction SimplifiedOperatorReducer::ReplaceInt32(int32_t value) {
     247         182 :   return Replace(jsgraph()->Int32Constant(value));
     248             : }
     249             : 
     250             : 
     251           0 : Reduction SimplifiedOperatorReducer::ReplaceNumber(double value) {
     252        1873 :   return Replace(jsgraph()->Constant(value));
     253             : }
     254             : 
     255             : 
     256           0 : Reduction SimplifiedOperatorReducer::ReplaceNumber(int32_t value) {
     257        1991 :   return Replace(jsgraph()->Constant(value));
     258             : }
     259             : 
     260           0 : Factory* SimplifiedOperatorReducer::factory() const {
     261           0 :   return jsgraph()->isolate()->factory();
     262             : }
     263             : 
     264           0 : Graph* SimplifiedOperatorReducer::graph() const { return jsgraph()->graph(); }
     265             : 
     266           0 : MachineOperatorBuilder* SimplifiedOperatorReducer::machine() const {
     267           0 :   return jsgraph()->machine();
     268             : }
     269             : 
     270             : }  // namespace compiler
     271             : }  // namespace internal
     272      121996 : }  // namespace v8

Generated by: LCOV version 1.10