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