Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: src/compiler/node-matchers.h

Issue 704713003: [turbofan] Optimize add operations to use 'leal' instruction on x64 (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Final version Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/compiler/x64/instruction-selector-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_COMPILER_NODE_MATCHERS_H_ 5 #ifndef V8_COMPILER_NODE_MATCHERS_H_
6 #define V8_COMPILER_NODE_MATCHERS_H_ 6 #define V8_COMPILER_NODE_MATCHERS_H_
7 7
8 #include "src/compiler/generic-node.h"
9 #include "src/compiler/generic-node-inl.h"
8 #include "src/compiler/node.h" 10 #include "src/compiler/node.h"
9 #include "src/compiler/operator.h" 11 #include "src/compiler/operator.h"
10 #include "src/unique.h" 12 #include "src/unique.h"
11 13
12 namespace v8 { 14 namespace v8 {
13 namespace internal { 15 namespace internal {
14 namespace compiler { 16 namespace compiler {
15 17
16 // A pattern matcher for nodes. 18 // A pattern matcher for nodes.
17 struct NodeMatcher { 19 struct NodeMatcher {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 : public ValueMatcher<Unique<T>, IrOpcode::kHeapConstant> { 111 : public ValueMatcher<Unique<T>, IrOpcode::kHeapConstant> {
110 explicit HeapObjectMatcher(Node* node) 112 explicit HeapObjectMatcher(Node* node)
111 : ValueMatcher<Unique<T>, IrOpcode::kHeapConstant>(node) {} 113 : ValueMatcher<Unique<T>, IrOpcode::kHeapConstant>(node) {}
112 }; 114 };
113 115
114 116
115 // For shorter pattern matching code, this struct matches both the left and 117 // For shorter pattern matching code, this struct matches both the left and
116 // right hand sides of a binary operation and can put constants on the right 118 // right hand sides of a binary operation and can put constants on the right
117 // if they appear on the left hand side of a commutative operation. 119 // if they appear on the left hand side of a commutative operation.
118 template <typename Left, typename Right> 120 template <typename Left, typename Right>
119 struct BinopMatcher FINAL : public NodeMatcher { 121 struct BinopMatcher : public NodeMatcher {
120 explicit BinopMatcher(Node* node) 122 explicit BinopMatcher(Node* node)
121 : NodeMatcher(node), left_(InputAt(0)), right_(InputAt(1)) { 123 : NodeMatcher(node), left_(InputAt(0)), right_(InputAt(1)) {
122 if (HasProperty(Operator::kCommutative)) PutConstantOnRight(); 124 if (HasProperty(Operator::kCommutative)) PutConstantOnRight();
123 } 125 }
124 126
125 const Left& left() const { return left_; } 127 const Left& left() const { return left_; }
126 const Right& right() const { return right_; } 128 const Right& right() const { return right_; }
127 129
128 bool IsFoldable() const { return left().HasValue() && right().HasValue(); } 130 bool IsFoldable() const { return left().HasValue() && right().HasValue(); }
129 bool LeftEqualsRight() const { return left().node() == right().node(); } 131 bool LeftEqualsRight() const { return left().node() == right().node(); }
130 132
133 protected:
134 void SwapInputs() {
135 std::swap(left_, right_);
136 node()->ReplaceInput(0, left().node());
137 node()->ReplaceInput(1, right().node());
138 }
139
131 private: 140 private:
132 void PutConstantOnRight() { 141 void PutConstantOnRight() {
133 if (left().HasValue() && !right().HasValue()) { 142 if (left().HasValue() && !right().HasValue()) {
134 std::swap(left_, right_); 143 SwapInputs();
135 node()->ReplaceInput(0, left().node());
136 node()->ReplaceInput(1, right().node());
137 } 144 }
138 } 145 }
139 146
140 Left left_; 147 Left left_;
141 Right right_; 148 Right right_;
142 }; 149 };
143 150
144 typedef BinopMatcher<Int32Matcher, Int32Matcher> Int32BinopMatcher; 151 typedef BinopMatcher<Int32Matcher, Int32Matcher> Int32BinopMatcher;
145 typedef BinopMatcher<Uint32Matcher, Uint32Matcher> Uint32BinopMatcher; 152 typedef BinopMatcher<Uint32Matcher, Uint32Matcher> Uint32BinopMatcher;
146 typedef BinopMatcher<Int64Matcher, Int64Matcher> Int64BinopMatcher; 153 typedef BinopMatcher<Int64Matcher, Int64Matcher> Int64BinopMatcher;
147 typedef BinopMatcher<Uint64Matcher, Uint64Matcher> Uint64BinopMatcher; 154 typedef BinopMatcher<Uint64Matcher, Uint64Matcher> Uint64BinopMatcher;
148 typedef BinopMatcher<IntPtrMatcher, IntPtrMatcher> IntPtrBinopMatcher; 155 typedef BinopMatcher<IntPtrMatcher, IntPtrMatcher> IntPtrBinopMatcher;
149 typedef BinopMatcher<UintPtrMatcher, UintPtrMatcher> UintPtrBinopMatcher; 156 typedef BinopMatcher<UintPtrMatcher, UintPtrMatcher> UintPtrBinopMatcher;
150 typedef BinopMatcher<Float64Matcher, Float64Matcher> Float64BinopMatcher; 157 typedef BinopMatcher<Float64Matcher, Float64Matcher> Float64BinopMatcher;
151 typedef BinopMatcher<NumberMatcher, NumberMatcher> NumberBinopMatcher; 158 typedef BinopMatcher<NumberMatcher, NumberMatcher> NumberBinopMatcher;
152 159
160 struct Int32AddMatcher : public Int32BinopMatcher {
161 explicit Int32AddMatcher(Node* node)
162 : Int32BinopMatcher(node), scale_exponent_(-1) {
163 PutScaledInputOnLeft();
164 }
165
166 bool HasScaledInput() const { return scale_exponent_ != -1; }
167 Node* ScaledInput() const {
168 DCHECK(HasScaledInput());
169 return left().node()->InputAt(0);
170 }
171 int ScaleExponent() const {
172 DCHECK(HasScaledInput());
173 return scale_exponent_;
174 }
175
176 private:
177 int GetInputScaleExponent(Node* node) const {
178 if (node->opcode() == IrOpcode::kWord32Shl) {
179 Int32BinopMatcher m(node);
180 if (m.right().HasValue()) {
181 int32_t value = m.right().Value();
182 if (value >= 0 && value <= 3) {
183 return value;
184 }
185 }
186 } else if (node->opcode() == IrOpcode::kInt32Mul) {
187 Int32BinopMatcher m(node);
188 if (m.right().HasValue()) {
189 int32_t value = m.right().Value();
190 if (value == 1) {
191 return 0;
192 } else if (value == 2) {
193 return 1;
194 } else if (value == 4) {
195 return 2;
196 } else if (value == 8) {
197 return 3;
198 }
199 }
200 }
201 return -1;
202 }
203
204 void PutScaledInputOnLeft() {
205 scale_exponent_ = GetInputScaleExponent(right().node());
206 if (scale_exponent_ >= 0) {
207 int left_scale_exponent = GetInputScaleExponent(left().node());
208 if (left_scale_exponent == -1) {
209 SwapInputs();
210 } else {
211 scale_exponent_ = left_scale_exponent;
212 }
213 } else {
214 scale_exponent_ = GetInputScaleExponent(left().node());
215 if (scale_exponent_ == -1) {
216 if (right().opcode() == IrOpcode::kInt32Add &&
217 left().opcode() != IrOpcode::kInt32Add) {
218 SwapInputs();
219 }
220 }
221 }
222 }
223
224 int scale_exponent_;
225 };
226
227 struct ScaledWithOffsetMatcher {
228 explicit ScaledWithOffsetMatcher(Node* node)
229 : matches_(false),
230 scaled_(NULL),
231 scale_exponent_(0),
232 offset_(NULL),
233 constant_(NULL) {
234 if (node->opcode() != IrOpcode::kInt32Add) return;
235
236 // The Int32AddMatcher canonicalizes the order of constants and scale
237 // factors that are used as inputs, so instead of enumerating all possible
238 // patterns by brute force, checking for node clusters using the following
239 // templates in the following order suffices to find all of the interesting
240 // cases (S = scaled input, O = offset input, C = constant input):
241 // (S + (O + C))
242 // (S + (O + O))
243 // (S + C)
244 // (S + O)
245 // ((S + C) + O)
246 // ((S + O) + C)
247 // ((O + C) + O)
248 // ((O + O) + C)
249 // (O + C)
250 // (O + O)
251 Int32AddMatcher base_matcher(node);
252 Node* left = base_matcher.left().node();
253 Node* right = base_matcher.right().node();
254 if (base_matcher.HasScaledInput() && left->OwnedBy(node)) {
255 scaled_ = base_matcher.ScaledInput();
256 scale_exponent_ = base_matcher.ScaleExponent();
257 if (right->opcode() == IrOpcode::kInt32Add && right->OwnedBy(node)) {
258 Int32AddMatcher right_matcher(right);
259 if (right_matcher.right().HasValue()) {
260 // (S + (O + C))
261 offset_ = right_matcher.left().node();
262 constant_ = right_matcher.right().node();
263 } else {
264 // (S + (O + O))
265 offset_ = right;
266 }
267 } else if (base_matcher.right().HasValue()) {
268 // (S + C)
269 constant_ = right;
270 } else {
271 // (S + O)
272 offset_ = right;
273 }
274 } else {
275 if (left->opcode() == IrOpcode::kInt32Add && left->OwnedBy(node)) {
276 Int32AddMatcher left_matcher(left);
277 Node* left_left = left_matcher.left().node();
278 Node* left_right = left_matcher.right().node();
279 if (left_matcher.HasScaledInput() && left_left->OwnedBy(left)) {
280 scaled_ = left_matcher.ScaledInput();
281 scale_exponent_ = left_matcher.ScaleExponent();
282 if (left_matcher.right().HasValue()) {
283 // ((S + C) + O)
284 constant_ = left_right;
285 offset_ = right;
286 } else if (base_matcher.right().HasValue()) {
287 // ((S + O) + C)
288 offset_ = left_right;
289 constant_ = right;
290 } else {
291 // (O + O)
292 scaled_ = left;
293 offset_ = right;
294 }
295 } else {
296 if (left_matcher.right().HasValue()) {
297 // ((O + C) + O)
298 scaled_ = left_left;
299 constant_ = left_right;
300 offset_ = right;
301 } else if (base_matcher.right().HasValue()) {
302 // ((O + O) + C)
303 scaled_ = left_left;
304 offset_ = left_right;
305 constant_ = right;
306 } else {
307 // (O + O)
308 scaled_ = left;
309 offset_ = right;
310 }
311 }
312 } else {
313 if (base_matcher.right().HasValue()) {
314 // (O + C)
315 offset_ = left;
316 constant_ = right;
317 } else {
318 // (O + O)
319 offset_ = left;
320 scaled_ = right;
321 }
322 }
323 }
324 matches_ = true;
325 }
326
327 bool matches() const { return matches_; }
328 Node* scaled() const { return scaled_; }
329 int scale_exponent() const { return scale_exponent_; }
330 Node* offset() const { return offset_; }
331 Node* constant() const { return constant_; }
332
333 private:
334 bool matches_;
335
336 protected:
337 Node* scaled_;
338 int scale_exponent_;
339 Node* offset_;
340 Node* constant_;
341 };
342
153 } // namespace compiler 343 } // namespace compiler
154 } // namespace internal 344 } // namespace internal
155 } // namespace v8 345 } // namespace v8
156 346
157 #endif // V8_COMPILER_NODE_MATCHERS_H_ 347 #endif // V8_COMPILER_NODE_MATCHERS_H_
OLDNEW
« no previous file with comments | « no previous file | src/compiler/x64/instruction-selector-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698