Home | History | Annotate | Download | only in compiler
      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/conversions-inl.h"
     12 
     13 namespace v8 {
     14 namespace internal {
     15 namespace compiler {
     16 
     17 SimplifiedOperatorReducer::SimplifiedOperatorReducer(JSGraph* jsgraph)
     18     : jsgraph_(jsgraph) {}
     19 
     20 
     21 SimplifiedOperatorReducer::~SimplifiedOperatorReducer() {}
     22 
     23 
     24 Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
     25   switch (node->opcode()) {
     26     case IrOpcode::kBooleanNot: {
     27       HeapObjectMatcher m(node->InputAt(0));
     28       if (m.HasValue()) {
     29         return Replace(jsgraph()->BooleanConstant(!m.Value()->BooleanValue()));
     30       }
     31       if (m.IsBooleanNot()) return Replace(m.InputAt(0));
     32       break;
     33     }
     34     case IrOpcode::kChangeBitToBool: {
     35       Int32Matcher m(node->InputAt(0));
     36       if (m.Is(0)) return Replace(jsgraph()->FalseConstant());
     37       if (m.Is(1)) return Replace(jsgraph()->TrueConstant());
     38       if (m.IsChangeBoolToBit()) return Replace(m.InputAt(0));
     39       break;
     40     }
     41     case IrOpcode::kChangeBoolToBit: {
     42       HeapObjectMatcher m(node->InputAt(0));
     43       if (m.HasValue()) return ReplaceInt32(m.Value()->BooleanValue());
     44       if (m.IsChangeBitToBool()) return Replace(m.InputAt(0));
     45       break;
     46     }
     47     case IrOpcode::kChangeFloat64ToTagged: {
     48       Float64Matcher m(node->InputAt(0));
     49       if (m.HasValue()) return ReplaceNumber(m.Value());
     50       break;
     51     }
     52     case IrOpcode::kChangeInt32ToTagged: {
     53       Int32Matcher m(node->InputAt(0));
     54       if (m.HasValue()) return ReplaceNumber(m.Value());
     55       break;
     56     }
     57     case IrOpcode::kChangeTaggedToFloat64: {
     58       NumberMatcher m(node->InputAt(0));
     59       if (m.HasValue()) return ReplaceFloat64(m.Value());
     60       if (m.IsChangeFloat64ToTagged()) return Replace(m.node()->InputAt(0));
     61       if (m.IsChangeInt32ToTagged()) {
     62         return Change(node, machine()->ChangeInt32ToFloat64(), m.InputAt(0));
     63       }
     64       if (m.IsChangeUint32ToTagged()) {
     65         return Change(node, machine()->ChangeUint32ToFloat64(), m.InputAt(0));
     66       }
     67       break;
     68     }
     69     case IrOpcode::kChangeTaggedToInt32: {
     70       NumberMatcher m(node->InputAt(0));
     71       if (m.HasValue()) return ReplaceInt32(DoubleToInt32(m.Value()));
     72       if (m.IsChangeFloat64ToTagged()) {
     73         return Change(node, machine()->ChangeFloat64ToInt32(), m.InputAt(0));
     74       }
     75       if (m.IsChangeInt32ToTagged()) return Replace(m.InputAt(0));
     76       break;
     77     }
     78     case IrOpcode::kChangeTaggedToUint32: {
     79       NumberMatcher m(node->InputAt(0));
     80       if (m.HasValue()) return ReplaceUint32(DoubleToUint32(m.Value()));
     81       if (m.IsChangeFloat64ToTagged()) {
     82         return Change(node, machine()->ChangeFloat64ToUint32(), m.InputAt(0));
     83       }
     84       if (m.IsChangeUint32ToTagged()) return Replace(m.InputAt(0));
     85       break;
     86     }
     87     case IrOpcode::kChangeUint32ToTagged: {
     88       Uint32Matcher m(node->InputAt(0));
     89       if (m.HasValue()) return ReplaceNumber(FastUI2D(m.Value()));
     90       break;
     91     }
     92     case IrOpcode::kReferenceEqual:
     93       return ReduceReferenceEqual(node);
     94     default:
     95       break;
     96   }
     97   return NoChange();
     98 }
     99 
    100 
    101 Reduction SimplifiedOperatorReducer::ReduceReferenceEqual(Node* node) {
    102   DCHECK_EQ(IrOpcode::kReferenceEqual, node->opcode());
    103   Node* const left = NodeProperties::GetValueInput(node, 0);
    104   Node* const right = NodeProperties::GetValueInput(node, 1);
    105   HeapObjectMatcher match_left(left);
    106   HeapObjectMatcher match_right(right);
    107   if (match_left.HasValue() && match_right.HasValue()) {
    108     if (match_left.Value().is_identical_to(match_right.Value())) {
    109       return Replace(jsgraph()->TrueConstant());
    110     } else {
    111       return Replace(jsgraph()->FalseConstant());
    112     }
    113   }
    114   return NoChange();
    115 }
    116 
    117 
    118 Reduction SimplifiedOperatorReducer::Change(Node* node, const Operator* op,
    119                                             Node* a) {
    120   DCHECK_EQ(node->InputCount(), OperatorProperties::GetTotalInputCount(op));
    121   DCHECK_LE(1, node->InputCount());
    122   node->ReplaceInput(0, a);
    123   NodeProperties::ChangeOp(node, op);
    124   return Changed(node);
    125 }
    126 
    127 
    128 Reduction SimplifiedOperatorReducer::ReplaceFloat64(double value) {
    129   return Replace(jsgraph()->Float64Constant(value));
    130 }
    131 
    132 
    133 Reduction SimplifiedOperatorReducer::ReplaceInt32(int32_t value) {
    134   return Replace(jsgraph()->Int32Constant(value));
    135 }
    136 
    137 
    138 Reduction SimplifiedOperatorReducer::ReplaceNumber(double value) {
    139   return Replace(jsgraph()->Constant(value));
    140 }
    141 
    142 
    143 Reduction SimplifiedOperatorReducer::ReplaceNumber(int32_t value) {
    144   return Replace(jsgraph()->Constant(value));
    145 }
    146 
    147 
    148 Graph* SimplifiedOperatorReducer::graph() const { return jsgraph()->graph(); }
    149 
    150 
    151 MachineOperatorBuilder* SimplifiedOperatorReducer::machine() const {
    152   return jsgraph()->machine();
    153 }
    154 
    155 }  // namespace compiler
    156 }  // namespace internal
    157 }  // namespace v8
    158