LCOV - code coverage report
Current view: top level - src/compiler - simplified-operator-reducer.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 82 88 93.2 %
Date: 2017-04-26 Functions: 4 15 26.7 %

          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       59918 : Decision DecideObjectIsSmi(Node* const input) {
      22             :   NumberMatcher m(input);
      23       59918 :   if (m.HasValue()) {
      24        5834 :     return IsSmiDouble(m.Value()) ? Decision::kTrue : Decision::kFalse;
      25             :   }
      26       54084 :   if (m.IsAllocate()) return Decision::kFalse;
      27       54084 :   if (m.IsChangeBitToTagged()) return Decision::kFalse;
      28       54082 :   if (m.IsChangeInt31ToTaggedSigned()) return Decision::kTrue;
      29       54082 :   if (m.IsHeapConstant()) return Decision::kFalse;
      30       54070 :   return Decision::kUnknown;
      31             : }
      32             : 
      33             : }  // namespace
      34             : 
      35      791484 : SimplifiedOperatorReducer::SimplifiedOperatorReducer(Editor* editor,
      36             :                                                      JSGraph* jsgraph)
      37      791484 :     : AdvancedReducer(editor), jsgraph_(jsgraph) {}
      38             : 
      39     1582956 : SimplifiedOperatorReducer::~SimplifiedOperatorReducer() {}
      40             : 
      41             : 
      42    80701190 : Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
      43    80700835 :   switch (node->opcode()) {
      44             :     case IrOpcode::kBooleanNot: {
      45             :       HeapObjectMatcher m(node->InputAt(0));
      46       35677 :       if (m.Is(factory()->true_value())) return ReplaceBoolean(false);
      47       25709 :       if (m.Is(factory()->false_value())) return ReplaceBoolean(true);
      48       18415 :       if (m.IsBooleanNot()) return Replace(m.InputAt(0));
      49       16191 :       break;
      50             :     }
      51             :     case IrOpcode::kChangeBitToTagged: {
      52             :       Int32Matcher m(node->InputAt(0));
      53       18492 :       if (m.Is(0)) return Replace(jsgraph()->FalseConstant());
      54       18396 :       if (m.Is(1)) return Replace(jsgraph()->TrueConstant());
      55       18128 :       if (m.IsChangeTaggedToBit()) return Replace(m.InputAt(0));
      56             :       break;
      57             :     }
      58             :     case IrOpcode::kChangeTaggedToBit: {
      59             :       HeapObjectMatcher m(node->InputAt(0));
      60      235874 :       if (m.HasValue()) return ReplaceInt32(m.Value()->BooleanValue());
      61      235870 :       if (m.IsChangeBitToTagged()) return Replace(m.InputAt(0));
      62             :       break;
      63             :     }
      64             :     case IrOpcode::kChangeFloat64ToTagged: {
      65             :       Float64Matcher m(node->InputAt(0));
      66       79963 :       if (m.HasValue()) return ReplaceNumber(m.Value());
      67       75878 :       if (m.IsChangeTaggedToFloat64()) return Replace(m.node()->InputAt(0));
      68             :       break;
      69             :     }
      70             :     case IrOpcode::kChangeInt31ToTaggedSigned:
      71             :     case IrOpcode::kChangeInt32ToTagged: {
      72             :       Int32Matcher m(node->InputAt(0));
      73       69986 :       if (m.HasValue()) return ReplaceNumber(m.Value());
      74       64369 :       if (m.IsChangeTaggedToInt32() || m.IsChangeTaggedSignedToInt32()) {
      75             :         return Replace(m.InputAt(0));
      76             :       }
      77             :       break;
      78             :     }
      79             :     case IrOpcode::kChangeTaggedToFloat64:
      80             :     case IrOpcode::kTruncateTaggedToFloat64: {
      81             :       NumberMatcher m(node->InputAt(0));
      82       65618 :       if (m.HasValue()) return ReplaceFloat64(m.Value());
      83       43133 :       if (m.IsChangeFloat64ToTagged() || m.IsChangeFloat64ToTaggedPointer()) {
      84             :         return Replace(m.node()->InputAt(0));
      85             :       }
      86       43101 :       if (m.IsChangeInt31ToTaggedSigned() || m.IsChangeInt32ToTagged()) {
      87           1 :         return Change(node, machine()->ChangeInt32ToFloat64(), m.InputAt(0));
      88             :       }
      89       43100 :       if (m.IsChangeUint32ToTagged()) {
      90           1 :         return Change(node, machine()->ChangeUint32ToFloat64(), m.InputAt(0));
      91             :       }
      92             :       break;
      93             :     }
      94             :     case IrOpcode::kChangeTaggedSignedToInt32:
      95             :     case IrOpcode::kChangeTaggedToInt32: {
      96             :       NumberMatcher m(node->InputAt(0));
      97      129040 :       if (m.HasValue()) return ReplaceInt32(DoubleToInt32(m.Value()));
      98      127372 :       if (m.IsChangeFloat64ToTagged() || m.IsChangeFloat64ToTaggedPointer()) {
      99           2 :         return Change(node, machine()->ChangeFloat64ToInt32(), m.InputAt(0));
     100             :       }
     101      127370 :       if (m.IsChangeInt31ToTaggedSigned() || m.IsChangeInt32ToTagged()) {
     102             :         return Replace(m.InputAt(0));
     103             :       }
     104             :       break;
     105             :     }
     106             :     case IrOpcode::kChangeTaggedToUint32: {
     107             :       NumberMatcher m(node->InputAt(0));
     108         529 :       if (m.HasValue()) return ReplaceUint32(DoubleToUint32(m.Value()));
     109         495 :       if (m.IsChangeFloat64ToTagged() || m.IsChangeFloat64ToTaggedPointer()) {
     110           2 :         return Change(node, machine()->ChangeFloat64ToUint32(), m.InputAt(0));
     111             :       }
     112         493 :       if (m.IsChangeUint32ToTagged()) return Replace(m.InputAt(0));
     113             :       break;
     114             :     }
     115             :     case IrOpcode::kChangeUint32ToTagged: {
     116             :       Uint32Matcher m(node->InputAt(0));
     117        1296 :       if (m.HasValue()) return ReplaceNumber(FastUI2D(m.Value()));
     118             :       break;
     119             :     }
     120             :     case IrOpcode::kTruncateTaggedToWord32: {
     121             :       NumberMatcher m(node->InputAt(0));
     122        2232 :       if (m.HasValue()) return ReplaceInt32(DoubleToInt32(m.Value()));
     123        2124 :       if (m.IsChangeInt31ToTaggedSigned() || m.IsChangeInt32ToTagged() ||
     124             :           m.IsChangeUint32ToTagged()) {
     125             :         return Replace(m.InputAt(0));
     126             :       }
     127        2124 :       if (m.IsChangeFloat64ToTagged() || m.IsChangeFloat64ToTaggedPointer()) {
     128           2 :         return Change(node, machine()->TruncateFloat64ToWord32(), m.InputAt(0));
     129             :       }
     130             :       break;
     131             :     }
     132             :     case IrOpcode::kCheckedFloat64ToInt32: {
     133             :       Float64Matcher m(node->InputAt(0));
     134       15350 :       if (m.HasValue() && IsInt32Double(m.Value())) {
     135         212 :         Node* value = jsgraph()->Int32Constant(static_cast<int32_t>(m.Value()));
     136        5788 :         ReplaceWithValue(node, value);
     137             :         return Replace(value);
     138             :       }
     139             :       break;
     140             :     }
     141             :     case IrOpcode::kCheckedTaggedToInt32:
     142             :     case IrOpcode::kCheckedTaggedSignedToInt32: {
     143             :       NodeMatcher m(node->InputAt(0));
     144      249229 :       if (m.IsConvertTaggedHoleToUndefined()) {
     145          76 :         node->ReplaceInput(0, m.InputAt(0));
     146             :         return Changed(node);
     147             :       }
     148             :       break;
     149             :     }
     150             :     case IrOpcode::kCheckIf: {
     151             :       HeapObjectMatcher m(node->InputAt(0));
     152       97701 :       if (m.Is(factory()->true_value())) {
     153         859 :         Node* const effect = NodeProperties::GetEffectInput(node);
     154         859 :         return Replace(effect);
     155             :       }
     156       96842 :       break;
     157             :     }
     158             :     case IrOpcode::kCheckNumber: {
     159             :       NodeMatcher m(node->InputAt(0));
     160        1432 :       if (m.IsConvertTaggedHoleToUndefined()) {
     161           0 :         node->ReplaceInput(0, m.InputAt(0));
     162             :         return Changed(node);
     163             :       }
     164             :       break;
     165             :     }
     166             :     case IrOpcode::kCheckHeapObject: {
     167             :       Node* const input = node->InputAt(0);
     168       29576 :       if (DecideObjectIsSmi(input) == Decision::kFalse) {
     169             :         ReplaceWithValue(node, input);
     170             :         return Replace(input);
     171             :       }
     172             :       NodeMatcher m(input);
     173       29571 :       if (m.IsCheckHeapObject()) {
     174             :         ReplaceWithValue(node, input);
     175             :         return Replace(input);
     176             :       }
     177             :       break;
     178             :     }
     179             :     case IrOpcode::kCheckSmi: {
     180             :       Node* const input = node->InputAt(0);
     181       16550 :       if (DecideObjectIsSmi(input) == Decision::kTrue) {
     182             :         ReplaceWithValue(node, input);
     183             :         return Replace(input);
     184             :       }
     185             :       NodeMatcher m(input);
     186       10875 :       if (m.IsCheckSmi()) {
     187             :         ReplaceWithValue(node, input);
     188             :         return Replace(input);
     189       10874 :       } else if (m.IsConvertTaggedHoleToUndefined()) {
     190          50 :         node->ReplaceInput(0, m.InputAt(0));
     191             :         return Changed(node);
     192             :       }
     193             :       break;
     194             :     }
     195             :     case IrOpcode::kObjectIsSmi: {
     196             :       Node* const input = node->InputAt(0);
     197       13792 :       switch (DecideObjectIsSmi(input)) {
     198             :         case Decision::kTrue:
     199             :           return ReplaceBoolean(true);
     200             :         case Decision::kFalse:
     201             :           return ReplaceBoolean(false);
     202             :         case Decision::kUnknown:
     203             :           break;
     204             :       }
     205             :       break;
     206             :     }
     207             :     case IrOpcode::kNumberAbs: {
     208             :       NumberMatcher m(node->InputAt(0));
     209         250 :       if (m.HasValue()) return ReplaceNumber(std::fabs(m.Value()));
     210             :       break;
     211             :     }
     212             :     case IrOpcode::kReferenceEqual: {
     213      220220 :       HeapObjectBinopMatcher m(node);
     214      220493 :       if (m.left().node() == m.right().node()) return ReplaceBoolean(true);
     215      219947 :       break;
     216             :     }
     217             :     default:
     218             :       break;
     219             :   }
     220             :   return NoChange();
     221             : }
     222             : 
     223           0 : Reduction SimplifiedOperatorReducer::Change(Node* node, const Operator* op,
     224             :                                             Node* a) {
     225             :   DCHECK_EQ(node->InputCount(), OperatorProperties::GetTotalInputCount(op));
     226             :   DCHECK_LE(1, node->InputCount());
     227           8 :   node->ReplaceInput(0, a);
     228           8 :   NodeProperties::ChangeOp(node, op);
     229           0 :   return Changed(node);
     230             : }
     231             : 
     232        7909 : Reduction SimplifiedOperatorReducer::ReplaceBoolean(bool value) {
     233        7909 :   return Replace(jsgraph()->BooleanConstant(value));
     234             : }
     235             : 
     236       22485 : Reduction SimplifiedOperatorReducer::ReplaceFloat64(double value) {
     237       22485 :   return Replace(jsgraph()->Float64Constant(value));
     238             : }
     239             : 
     240             : 
     241        1812 : Reduction SimplifiedOperatorReducer::ReplaceInt32(int32_t value) {
     242        1812 :   return Replace(jsgraph()->Int32Constant(value));
     243             : }
     244             : 
     245             : 
     246        4700 : Reduction SimplifiedOperatorReducer::ReplaceNumber(double value) {
     247        4700 :   return Replace(jsgraph()->Constant(value));
     248             : }
     249             : 
     250             : 
     251        5617 : Reduction SimplifiedOperatorReducer::ReplaceNumber(int32_t value) {
     252        5617 :   return Replace(jsgraph()->Constant(value));
     253             : }
     254             : 
     255           0 : Factory* SimplifiedOperatorReducer::factory() const {
     256           0 :   return isolate()->factory();
     257             : }
     258             : 
     259           0 : Graph* SimplifiedOperatorReducer::graph() const { return jsgraph()->graph(); }
     260             : 
     261      149344 : Isolate* SimplifiedOperatorReducer::isolate() const {
     262      149344 :   return jsgraph()->isolate();
     263             : }
     264             : 
     265           8 : MachineOperatorBuilder* SimplifiedOperatorReducer::machine() const {
     266           8 :   return jsgraph()->machine();
     267             : }
     268             : 
     269             : }  // namespace compiler
     270             : }  // namespace internal
     271             : }  // namespace v8

Generated by: LCOV version 1.10