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#ifndef V8_COMPILER_NODE_MATCHERS_H_ 6#define V8_COMPILER_NODE_MATCHERS_H_ 7 8#include "src/compiler/node.h" 9#include "src/compiler/operator.h" 10 11namespace v8 { 12namespace internal { 13namespace compiler { 14 15// A pattern matcher for nodes. 16struct NodeMatcher { 17 explicit NodeMatcher(Node* node) : node_(node) {} 18 19 Node* node() const { return node_; } 20 const Operator* op() const { return node()->op(); } 21 IrOpcode::Value opcode() const { return node()->opcode(); } 22 23 bool HasProperty(Operator::Property property) const { 24 return op()->HasProperty(property); 25 } 26 Node* InputAt(int index) const { return node()->InputAt(index); } 27 28#define DEFINE_IS_OPCODE(Opcode) \ 29 bool Is##Opcode() const { return opcode() == IrOpcode::k##Opcode; } 30 ALL_OP_LIST(DEFINE_IS_OPCODE) 31#undef DEFINE_IS_OPCODE 32 33 private: 34 Node* node_; 35}; 36 37 38// A pattern matcher for abitrary value constants. 39template <typename T, IrOpcode::Value kOpcode> 40struct ValueMatcher : public NodeMatcher { 41 explicit ValueMatcher(Node* node) 42 : NodeMatcher(node), value_(), has_value_(opcode() == kOpcode) { 43 if (has_value_) { 44 value_ = OpParameter<T>(node); 45 } 46 } 47 48 bool HasValue() const { return has_value_; } 49 const T& Value() const { 50 DCHECK(HasValue()); 51 return value_; 52 } 53 54 bool Is(const T& value) const { 55 return this->HasValue() && this->Value() == value; 56 } 57 58 bool IsInRange(const T& low, const T& high) const { 59 return this->HasValue() && low <= this->Value() && this->Value() <= high; 60 } 61 62 private: 63 T value_; 64 bool has_value_; 65}; 66 67 68// A pattern matcher for integer constants. 69template <typename T, IrOpcode::Value kOpcode> 70struct IntMatcher FINAL : public ValueMatcher<T, kOpcode> { 71 explicit IntMatcher(Node* node) : ValueMatcher<T, kOpcode>(node) {} 72 73 bool IsPowerOf2() const { 74 return this->HasValue() && this->Value() > 0 && 75 (this->Value() & (this->Value() - 1)) == 0; 76 } 77}; 78 79typedef IntMatcher<int32_t, IrOpcode::kInt32Constant> Int32Matcher; 80typedef IntMatcher<uint32_t, IrOpcode::kInt32Constant> Uint32Matcher; 81typedef IntMatcher<int64_t, IrOpcode::kInt64Constant> Int64Matcher; 82typedef IntMatcher<uint64_t, IrOpcode::kInt64Constant> Uint64Matcher; 83 84 85// A pattern matcher for floating point constants. 86template <typename T, IrOpcode::Value kOpcode> 87struct FloatMatcher FINAL : public ValueMatcher<T, kOpcode> { 88 explicit FloatMatcher(Node* node) : ValueMatcher<T, kOpcode>(node) {} 89 90 bool IsNaN() const { return this->HasValue() && std::isnan(this->Value()); } 91}; 92 93typedef FloatMatcher<float, IrOpcode::kFloat32Constant> Float32Matcher; 94typedef FloatMatcher<double, IrOpcode::kFloat64Constant> Float64Matcher; 95typedef FloatMatcher<double, IrOpcode::kNumberConstant> NumberMatcher; 96 97 98// A pattern matcher for heap object constants. 99template <typename T> 100struct HeapObjectMatcher FINAL 101 : public ValueMatcher<Unique<T>, IrOpcode::kHeapConstant> { 102 explicit HeapObjectMatcher(Node* node) 103 : ValueMatcher<Unique<T>, IrOpcode::kHeapConstant>(node) {} 104}; 105 106 107// For shorter pattern matching code, this struct matches both the left and 108// right hand sides of a binary operation and can put constants on the right 109// if they appear on the left hand side of a commutative operation. 110template <typename Left, typename Right> 111struct BinopMatcher FINAL : public NodeMatcher { 112 explicit BinopMatcher(Node* node) 113 : NodeMatcher(node), left_(InputAt(0)), right_(InputAt(1)) { 114 if (HasProperty(Operator::kCommutative)) PutConstantOnRight(); 115 } 116 117 const Left& left() const { return left_; } 118 const Right& right() const { return right_; } 119 120 bool IsFoldable() const { return left().HasValue() && right().HasValue(); } 121 bool LeftEqualsRight() const { return left().node() == right().node(); } 122 123 private: 124 void PutConstantOnRight() { 125 if (left().HasValue() && !right().HasValue()) { 126 std::swap(left_, right_); 127 node()->ReplaceInput(0, left().node()); 128 node()->ReplaceInput(1, right().node()); 129 } 130 } 131 132 Left left_; 133 Right right_; 134}; 135 136typedef BinopMatcher<Int32Matcher, Int32Matcher> Int32BinopMatcher; 137typedef BinopMatcher<Uint32Matcher, Uint32Matcher> Uint32BinopMatcher; 138typedef BinopMatcher<Int64Matcher, Int64Matcher> Int64BinopMatcher; 139typedef BinopMatcher<Uint64Matcher, Uint64Matcher> Uint64BinopMatcher; 140typedef BinopMatcher<Float64Matcher, Float64Matcher> Float64BinopMatcher; 141 142} // namespace compiler 143} // namespace internal 144} // namespace v8 145 146#endif // V8_COMPILER_NODE_MATCHERS_H_ 147