V8 Project
node-matchers.h
Go to the documentation of this file.
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"
10 
11 namespace v8 {
12 namespace internal {
13 namespace compiler {
14 
15 // A pattern matcher for nodes.
16 struct 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; }
31 #undef DEFINE_IS_OPCODE
32 
33  private:
34  Node* node_;
35 };
36 
37 
38 // A pattern matcher for abitrary value constants.
39 template <typename T, IrOpcode::Value kOpcode>
40 struct 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:
64  bool has_value_;
65 };
66 
67 
68 // A pattern matcher for integer constants.
69 template <typename T, IrOpcode::Value kOpcode>
70 struct 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 
79 typedef IntMatcher<int32_t, IrOpcode::kInt32Constant> Int32Matcher;
80 typedef IntMatcher<uint32_t, IrOpcode::kInt32Constant> Uint32Matcher;
81 typedef IntMatcher<int64_t, IrOpcode::kInt64Constant> Int64Matcher;
82 typedef IntMatcher<uint64_t, IrOpcode::kInt64Constant> Uint64Matcher;
83 
84 
85 // A pattern matcher for floating point constants.
86 template <typename T, IrOpcode::Value kOpcode>
87 struct 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 
93 typedef FloatMatcher<float, IrOpcode::kFloat32Constant> Float32Matcher;
94 typedef FloatMatcher<double, IrOpcode::kFloat64Constant> Float64Matcher;
95 typedef FloatMatcher<double, IrOpcode::kNumberConstant> NumberMatcher;
96 
97 
98 // A pattern matcher for heap object constants.
99 template <typename T>
100 struct 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.
110 template <typename Left, typename Right>
111 struct 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:
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 
136 typedef BinopMatcher<Int32Matcher, Int32Matcher> Int32BinopMatcher;
137 typedef BinopMatcher<Uint32Matcher, Uint32Matcher> Uint32BinopMatcher;
138 typedef BinopMatcher<Int64Matcher, Int64Matcher> Int64BinopMatcher;
139 typedef BinopMatcher<Uint64Matcher, Uint64Matcher> Uint64BinopMatcher;
140 typedef BinopMatcher<Float64Matcher, Float64Matcher> Float64BinopMatcher;
141 
142 
143 // Fairly intel-specify node matcher used for matching scale factors in
144 // addressing modes.
145 // Matches nodes of form [x * N] for N in {1,2,4,8}
147  public:
148  explicit ScaleFactorMatcher(Node* node)
149  : NodeMatcher(node), left_(NULL), power_(0) {
150  Match();
151  }
152 
153  bool Matches() { return left_ != NULL; }
154  int Power() {
155  DCHECK(Matches());
156  return power_;
157  }
158  Node* Left() {
159  DCHECK(Matches());
160  return left_;
161  }
162 
163  private:
164  void Match() {
165  if (opcode() != IrOpcode::kInt32Mul) return;
166  Int32BinopMatcher m(node());
167  if (!m.right().HasValue()) return;
168  int32_t value = m.right().Value();
169  switch (value) {
170  case 8:
171  power_++; // Fall through.
172  case 4:
173  power_++; // Fall through.
174  case 2:
175  power_++; // Fall through.
176  case 1:
177  break;
178  default:
179  return;
180  }
181  left_ = m.left().node();
182  }
183 
184  Node* left_;
185  int power_;
186 };
187 
188 
189 // Fairly intel-specify node matcher used for matching index and displacement
190 // operands in addressing modes.
191 // Matches nodes of form:
192 // [x * N]
193 // [x * N + K]
194 // [x + K]
195 // [x] -- fallback case
196 // for N in {1,2,4,8} and K int32_t
198  public:
201  Match();
202  }
203 
204  Node* index_node() { return index_node_; }
205  int displacement() { return displacement_; }
206  int power() { return power_; }
207 
208  private:
209  void Match() {
210  if (opcode() == IrOpcode::kInt32Add) {
211  // Assume reduction has put constant on the right.
212  Int32BinopMatcher m(node());
213  if (m.right().HasValue()) {
214  displacement_ = m.right().Value();
215  index_node_ = m.left().node();
216  }
217  }
218  // Test scale factor.
219  ScaleFactorMatcher scale_matcher(index_node_);
220  if (scale_matcher.Matches()) {
221  index_node_ = scale_matcher.Left();
222  power_ = scale_matcher.Power();
223  }
224  }
225 
226  Node* index_node_;
228  int power_;
229 };
230 
231 
232 } // namespace compiler
233 } // namespace internal
234 } // namespace v8
235 
236 #endif // V8_COMPILER_NODE_MATCHERS_H_
The superclass of all JavaScript values and objects.
Definition: v8.h:1440
Source to read snapshot and builtins files from.
Definition: lithium-arm.h:372
const Right & right() const
const Left & left() const
bool HasProperty(Property property) const
Definition: operator.h:74
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
Definition: logging.h:205
int int32_t
Definition: unicode.cc:24
FloatMatcher< float, IrOpcode::kFloat32Constant > Float32Matcher
Definition: node-matchers.h:93
IntMatcher< int64_t, IrOpcode::kInt64Constant > Int64Matcher
Definition: node-matchers.h:81
BinopMatcher< Uint64Matcher, Uint64Matcher > Uint64BinopMatcher
BinopMatcher< Uint32Matcher, Uint32Matcher > Uint32BinopMatcher
BinopMatcher< Int32Matcher, Int32Matcher > Int32BinopMatcher
FloatMatcher< double, IrOpcode::kFloat64Constant > Float64Matcher
Definition: node-matchers.h:94
BinopMatcher< Float64Matcher, Float64Matcher > Float64BinopMatcher
BinopMatcher< Int64Matcher, Int64Matcher > Int64BinopMatcher
IntMatcher< uint64_t, IrOpcode::kInt64Constant > Uint64Matcher
Definition: node-matchers.h:82
IntMatcher< int32_t, IrOpcode::kInt32Constant > Int32Matcher
Definition: node-matchers.h:79
IntMatcher< uint32_t, IrOpcode::kInt32Constant > Uint32Matcher
Definition: node-matchers.h:80
FloatMatcher< double, IrOpcode::kNumberConstant > NumberMatcher
Definition: node-matchers.h:95
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
#define DEFINE_IS_OPCODE(Opcode)
Definition: node-matchers.h:28
#define ALL_OP_LIST(V)
Definition: opcodes.h:233
Node * InputAt(int index) const
Definition: node-matchers.h:26
const Operator * op() const
Definition: node-matchers.h:20
bool HasProperty(Operator::Property property) const
Definition: node-matchers.h:23
IrOpcode::Value opcode() const
Definition: node-matchers.h:21
bool IsInRange(const T &low, const T &high) const
Definition: node-matchers.h:58
bool Is(const T &value) const
Definition: node-matchers.h:54
#define T(name, string, precedence)
Definition: token.cc:25