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

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

Issue 774193003: [turbofan] Use "leal" in even more situations (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@765983002
Patch Set: Fix Windows Created 6 years 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
« no previous file with comments | « no previous file | src/compiler/x64/code-generator-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 <cmath> 8 #include <cmath>
9 9
10 #include "src/compiler/node.h" 10 #include "src/compiler/node.h"
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 typedef BinopMatcher<Int32Matcher, Int32Matcher> Int32BinopMatcher; 164 typedef BinopMatcher<Int32Matcher, Int32Matcher> Int32BinopMatcher;
165 typedef BinopMatcher<Uint32Matcher, Uint32Matcher> Uint32BinopMatcher; 165 typedef BinopMatcher<Uint32Matcher, Uint32Matcher> Uint32BinopMatcher;
166 typedef BinopMatcher<Int64Matcher, Int64Matcher> Int64BinopMatcher; 166 typedef BinopMatcher<Int64Matcher, Int64Matcher> Int64BinopMatcher;
167 typedef BinopMatcher<Uint64Matcher, Uint64Matcher> Uint64BinopMatcher; 167 typedef BinopMatcher<Uint64Matcher, Uint64Matcher> Uint64BinopMatcher;
168 typedef BinopMatcher<IntPtrMatcher, IntPtrMatcher> IntPtrBinopMatcher; 168 typedef BinopMatcher<IntPtrMatcher, IntPtrMatcher> IntPtrBinopMatcher;
169 typedef BinopMatcher<UintPtrMatcher, UintPtrMatcher> UintPtrBinopMatcher; 169 typedef BinopMatcher<UintPtrMatcher, UintPtrMatcher> UintPtrBinopMatcher;
170 typedef BinopMatcher<Float64Matcher, Float64Matcher> Float64BinopMatcher; 170 typedef BinopMatcher<Float64Matcher, Float64Matcher> Float64BinopMatcher;
171 typedef BinopMatcher<NumberMatcher, NumberMatcher> NumberBinopMatcher; 171 typedef BinopMatcher<NumberMatcher, NumberMatcher> NumberBinopMatcher;
172 172
173 173
174 template <class BinopMatcher, IrOpcode::Value kMulOpcode,
175 IrOpcode::Value kShiftOpcode>
176 struct ScaleMatcher {
177 explicit ScaleMatcher(Node* node, bool allow_power_of_two_plus_one = false)
178 : scale_(-1), power_of_two_plus_one_(false) {
179 if (node->InputCount() < 2) return;
180 BinopMatcher m(node);
181 if (node->opcode() == kShiftOpcode) {
182 if (m.right().HasValue()) {
183 typename BinopMatcher::RightMatcher::ValueType value =
184 m.right().Value();
185 if (value >= 0 && value <= 3) {
186 scale_ = static_cast<int>(value);
187 }
188 }
189 } else if (node->opcode() == kMulOpcode) {
190 if (m.right().HasValue()) {
191 typename BinopMatcher::RightMatcher::ValueType value =
192 m.right().Value();
193 if (value == 1) {
194 scale_ = 0;
195 } else if (value == 2) {
196 scale_ = 1;
197 } else if (value == 4) {
198 scale_ = 2;
199 } else if (value == 8) {
200 scale_ = 3;
201 } else if (allow_power_of_two_plus_one) {
202 if (value == 3) {
203 scale_ = 1;
204 power_of_two_plus_one_ = true;
205 } else if (value == 5) {
206 scale_ = 2;
207 power_of_two_plus_one_ = true;
208 } else if (value == 9) {
209 scale_ = 3;
210 power_of_two_plus_one_ = true;
211 }
212 }
213 }
214 }
215 }
216
217 bool matches() const { return scale_ != -1; }
218 int scale() const { return scale_; }
219 bool power_of_two_plus_one() const { return power_of_two_plus_one_; }
220
221 private:
222 int scale_;
223 bool power_of_two_plus_one_;
224 };
225
226 typedef ScaleMatcher<Int32BinopMatcher, IrOpcode::kInt32Mul,
227 IrOpcode::kWord32Shl> Int32ScaleMatcher;
228 typedef ScaleMatcher<Int64BinopMatcher, IrOpcode::kInt64Mul,
229 IrOpcode::kWord64Shl> Int64ScaleMatcher;
230
231
174 template <class BinopMatcher, IrOpcode::Value kAddOpcode, 232 template <class BinopMatcher, IrOpcode::Value kAddOpcode,
175 IrOpcode::Value kMulOpcode, IrOpcode::Value kShiftOpcode> 233 IrOpcode::Value kMulOpcode, IrOpcode::Value kShiftOpcode>
176 struct AddMatcher : public BinopMatcher { 234 struct AddMatcher : public BinopMatcher {
177 static const IrOpcode::Value kOpcode = kAddOpcode; 235 static const IrOpcode::Value kOpcode = kAddOpcode;
236 typedef ScaleMatcher<BinopMatcher, kMulOpcode, kShiftOpcode> Matcher;
178 237
179 explicit AddMatcher(Node* node) : BinopMatcher(node), scale_exponent_(-1) { 238 explicit AddMatcher(Node* node)
180 if (this->HasProperty(Operator::kCommutative)) PutScaledInputOnLeft(); 239 : BinopMatcher(node), scale_(-1), power_of_two_plus_one_(false) {
181 } 240 Matcher left_matcher(this->left().node(), true);
241 if (left_matcher.matches()) {
242 scale_ = left_matcher.scale();
243 power_of_two_plus_one_ = left_matcher.power_of_two_plus_one();
244 return;
245 }
182 246
183 bool HasScaledInput() const { return scale_exponent_ != -1; } 247 if (!this->HasProperty(Operator::kCommutative)) {
184 Node* ScaledInput() const { 248 return;
185 DCHECK(HasScaledInput()); 249 }
186 return this->left().node()->InputAt(0);
187 }
188 int ScaleExponent() const {
189 DCHECK(HasScaledInput());
190 return scale_exponent_;
191 }
192 250
193 private: 251 Matcher right_matcher(this->right().node(), true);
194 int GetInputScaleExponent(Node* node) const { 252 if (right_matcher.matches()) {
195 if (node->opcode() == kShiftOpcode) { 253 scale_ = right_matcher.scale();
196 BinopMatcher m(node); 254 power_of_two_plus_one_ = right_matcher.power_of_two_plus_one();
197 if (m.right().HasValue()) { 255 this->SwapInputs();
198 typename BinopMatcher::RightMatcher::ValueType value = 256 return;
199 m.right().Value();
200 if (value >= 0 && value <= 3) {
201 return static_cast<int>(value);
202 }
203 }
204 } else if (node->opcode() == kMulOpcode) {
205 BinopMatcher m(node);
206 if (m.right().HasValue()) {
207 typename BinopMatcher::RightMatcher::ValueType value =
208 m.right().Value();
209 if (value == 1) {
210 return 0;
211 } else if (value == 2) {
212 return 1;
213 } else if (value == 4) {
214 return 2;
215 } else if (value == 8) {
216 return 3;
217 }
218 }
219 } 257 }
220 return -1;
221 }
222 258
223 void PutScaledInputOnLeft() { 259 if (this->right().opcode() == kAddOpcode &&
224 scale_exponent_ = GetInputScaleExponent(this->right().node()); 260 this->left().opcode() != kAddOpcode) {
225 if (scale_exponent_ >= 0) { 261 this->SwapInputs();
226 int left_scale_exponent = GetInputScaleExponent(this->left().node());
227 if (left_scale_exponent == -1) {
228 this->SwapInputs();
229 } else {
230 scale_exponent_ = left_scale_exponent;
231 }
232 } else {
233 scale_exponent_ = GetInputScaleExponent(this->left().node());
234 if (scale_exponent_ == -1) {
235 if (this->right().opcode() == kAddOpcode &&
236 this->left().opcode() != kAddOpcode) {
237 this->SwapInputs();
238 }
239 }
240 } 262 }
241 } 263 }
242 264
243 int scale_exponent_; 265 bool HasIndexInput() const { return scale_ != -1; }
266 Node* IndexInput() const {
267 DCHECK(HasIndexInput());
268 return this->left().node()->InputAt(0);
269 }
270 int scale() const {
271 DCHECK(HasIndexInput());
272 return scale_;
273 }
274 bool power_of_two_plus_one() const { return power_of_two_plus_one_; }
275
276 private:
277 int scale_;
278 bool power_of_two_plus_one_;
244 }; 279 };
245 280
246 typedef AddMatcher<Int32BinopMatcher, IrOpcode::kInt32Add, IrOpcode::kInt32Mul, 281 typedef AddMatcher<Int32BinopMatcher, IrOpcode::kInt32Add, IrOpcode::kInt32Mul,
247 IrOpcode::kWord32Shl> Int32AddMatcher; 282 IrOpcode::kWord32Shl> Int32AddMatcher;
248 typedef AddMatcher<Int64BinopMatcher, IrOpcode::kInt64Add, IrOpcode::kInt64Mul, 283 typedef AddMatcher<Int64BinopMatcher, IrOpcode::kInt64Add, IrOpcode::kInt64Mul,
249 IrOpcode::kWord64Shl> Int64AddMatcher; 284 IrOpcode::kWord64Shl> Int64AddMatcher;
250 285
286
251 template <class AddMatcher> 287 template <class AddMatcher>
252 struct ScaledWithOffsetMatcher { 288 struct BaseWithIndexAndDisplacementMatcher {
253 explicit ScaledWithOffsetMatcher(Node* node) 289 explicit BaseWithIndexAndDisplacementMatcher(Node* node)
254 : matches_(false), 290 : matches_(false),
255 scaled_(NULL), 291 index_(NULL),
256 scale_exponent_(0), 292 scale_(0),
257 offset_(NULL), 293 base_(NULL),
258 constant_(NULL) { 294 displacement_(NULL) {
259 // The ScaledWithOffsetMatcher canonicalizes the order of constants and 295 // The BaseWithIndexAndDisplacementMatcher canonicalizes the order of
260 // scale factors that are used as inputs, so instead of enumerating all 296 // displacements and scale factors that are used as inputs, so instead of
261 // possible patterns by brute force, checking for node clusters using the 297 // enumerating all possible patterns by brute force, checking for node
262 // following templates in the following order suffices to find all of the 298 // clusters using the following templates in the following order suffices to
263 // interesting cases (S = scaled input, O = offset input, C = constant 299 // find all of the interesting cases (S = index * scale, B = base input, D =
264 // input): 300 // displacement input):
265 // (S + (O + C)) 301 // (S + (B + D))
266 // (S + (O + O)) 302 // (S + (B + B))
267 // (S + C) 303 // (S + D)
268 // (S + O) 304 // (S + B)
269 // ((S + C) + O) 305 // ((S + D) + B)
270 // ((S + O) + C) 306 // ((S + B) + D)
271 // ((O + C) + O) 307 // ((B + D) + B)
272 // ((O + O) + C) 308 // ((B + B) + D)
273 // (O + C) 309 // (B + D)
274 // (O + O) 310 // (B + B)
275 if (node->InputCount() < 2) return; 311 if (node->InputCount() < 2) return;
276 AddMatcher base_matcher(node); 312 AddMatcher m(node);
277 Node* left = base_matcher.left().node(); 313 Node* left = m.left().node();
278 Node* right = base_matcher.right().node(); 314 Node* right = m.right().node();
279 if (base_matcher.HasScaledInput() && left->OwnedBy(node)) { 315 Node* displacement = NULL;
280 scaled_ = base_matcher.ScaledInput(); 316 Node* base = NULL;
281 scale_exponent_ = base_matcher.ScaleExponent(); 317 Node* index = NULL;
318 Node* scale_expression = NULL;
319 bool power_of_two_plus_one = false;
320 int scale = 0;
321 if (m.HasIndexInput() && left->OwnedBy(node)) {
322 index = m.IndexInput();
323 scale = m.scale();
324 scale_expression = left;
325 power_of_two_plus_one = m.power_of_two_plus_one();
282 if (right->opcode() == AddMatcher::kOpcode && right->OwnedBy(node)) { 326 if (right->opcode() == AddMatcher::kOpcode && right->OwnedBy(node)) {
283 AddMatcher right_matcher(right); 327 AddMatcher right_matcher(right);
284 if (right_matcher.right().HasValue()) { 328 if (right_matcher.right().HasValue()) {
285 // (S + (O + C)) 329 // (S + (B + D))
286 offset_ = right_matcher.left().node(); 330 base = right_matcher.left().node();
287 constant_ = right_matcher.right().node(); 331 displacement = right_matcher.right().node();
288 } else { 332 } else {
289 // (S + (O + O)) 333 // (S + (B + B))
290 offset_ = right; 334 base = right;
291 } 335 }
292 } else if (base_matcher.right().HasValue()) { 336 } else if (m.right().HasValue()) {
293 // (S + C) 337 // (S + D)
294 constant_ = right; 338 displacement = right;
295 } else { 339 } else {
296 // (S + O) 340 // (S + B)
297 offset_ = right; 341 base = right;
298 } 342 }
299 } else { 343 } else {
300 if (left->opcode() == AddMatcher::kOpcode && left->OwnedBy(node)) { 344 if (left->opcode() == AddMatcher::kOpcode && left->OwnedBy(node)) {
301 AddMatcher left_matcher(left); 345 AddMatcher left_matcher(left);
302 Node* left_left = left_matcher.left().node(); 346 Node* left_left = left_matcher.left().node();
303 Node* left_right = left_matcher.right().node(); 347 Node* left_right = left_matcher.right().node();
304 if (left_matcher.HasScaledInput() && left_left->OwnedBy(left)) { 348 if (left_matcher.HasIndexInput() && left_left->OwnedBy(left)) {
305 if (left_matcher.right().HasValue()) { 349 if (left_matcher.right().HasValue()) {
306 // ((S + C) + O) 350 // ((S + D) + B)
307 scaled_ = left_matcher.ScaledInput(); 351 index = left_matcher.IndexInput();
308 scale_exponent_ = left_matcher.ScaleExponent(); 352 scale = left_matcher.scale();
309 constant_ = left_right; 353 scale_expression = left_left;
310 offset_ = right; 354 power_of_two_plus_one = left_matcher.power_of_two_plus_one();
311 } else if (base_matcher.right().HasValue()) { 355 displacement = left_right;
312 // ((S + O) + C) 356 base = right;
313 scaled_ = left_matcher.ScaledInput(); 357 } else if (m.right().HasValue()) {
314 scale_exponent_ = left_matcher.ScaleExponent(); 358 // ((S + B) + D)
315 offset_ = left_right; 359 index = left_matcher.IndexInput();
316 constant_ = right; 360 scale = left_matcher.scale();
361 scale_expression = left_left;
362 power_of_two_plus_one = left_matcher.power_of_two_plus_one();
363 base = left_right;
364 displacement = right;
317 } else { 365 } else {
318 // (O + O) 366 // (B + B)
319 scaled_ = left; 367 index = left;
320 offset_ = right; 368 base = right;
321 } 369 }
322 } else { 370 } else {
323 if (left_matcher.right().HasValue()) { 371 if (left_matcher.right().HasValue()) {
324 // ((O + C) + O) 372 // ((B + D) + B)
325 scaled_ = left_left; 373 index = left_left;
326 constant_ = left_right; 374 displacement = left_right;
327 offset_ = right; 375 base = right;
328 } else if (base_matcher.right().HasValue()) { 376 } else if (m.right().HasValue()) {
329 // ((O + O) + C) 377 // ((B + B) + D)
330 scaled_ = left_left; 378 index = left_left;
331 offset_ = left_right; 379 base = left_right;
332 constant_ = right; 380 displacement = right;
333 } else { 381 } else {
334 // (O + O) 382 // (B + B)
335 scaled_ = left; 383 index = left;
336 offset_ = right; 384 base = right;
337 } 385 }
338 } 386 }
339 } else { 387 } else {
340 if (base_matcher.right().HasValue()) { 388 if (m.right().HasValue()) {
341 // (O + C) 389 // (B + D)
342 offset_ = left; 390 base = left;
343 constant_ = right; 391 displacement = right;
344 } else { 392 } else {
345 // (O + O) 393 // (B + B)
346 offset_ = left; 394 base = left;
347 scaled_ = right; 395 index = right;
348 } 396 }
349 } 397 }
350 } 398 }
351 int64_t value = 0; 399 int64_t value = 0;
352 if (constant_ != NULL) { 400 if (displacement != NULL) {
353 switch (constant_->opcode()) { 401 switch (displacement->opcode()) {
354 case IrOpcode::kInt32Constant: { 402 case IrOpcode::kInt32Constant: {
355 value = OpParameter<int32_t>(constant_); 403 value = OpParameter<int32_t>(displacement);
356 break; 404 break;
357 } 405 }
358 case IrOpcode::kInt64Constant: { 406 case IrOpcode::kInt64Constant: {
359 value = OpParameter<int64_t>(constant_); 407 value = OpParameter<int64_t>(displacement);
360 break; 408 break;
361 } 409 }
362 default: 410 default:
363 UNREACHABLE(); 411 UNREACHABLE();
364 break; 412 break;
365 } 413 }
366 if (value == 0) { 414 if (value == 0) {
367 constant_ = NULL; 415 displacement = NULL;
368 } 416 }
369 } 417 }
418 if (power_of_two_plus_one) {
419 if (base != NULL) {
420 // If the scale requires explicitly using the index as the base, but a
421 // base is already part of the match, then the (1 << N + 1) scale factor
422 // can't be folded into the match and the entire index * scale
423 // calculation must be computed separately.
424 index = scale_expression;
425 scale = 0;
426 } else {
427 base = index;
428 }
429 }
430 base_ = base;
431 displacement_ = displacement;
432 index_ = index;
433 scale_ = scale;
370 matches_ = true; 434 matches_ = true;
371 } 435 }
372 436
373 bool matches() const { return matches_; } 437 bool matches() const { return matches_; }
374 Node* scaled() const { return scaled_; } 438 Node* index() const { return index_; }
375 int scale_exponent() const { return scale_exponent_; } 439 int scale() const { return scale_; }
376 Node* offset() const { return offset_; } 440 Node* base() const { return base_; }
377 Node* constant() const { return constant_; } 441 Node* displacement() const { return displacement_; }
378 442
379 private: 443 private:
380 bool matches_; 444 bool matches_;
381 445
382 protected: 446 protected:
383 Node* scaled_; 447 Node* index_;
384 int scale_exponent_; 448 int scale_;
385 Node* offset_; 449 Node* base_;
386 Node* constant_; 450 Node* displacement_;
387 }; 451 };
388 452
389 typedef ScaledWithOffsetMatcher<Int32AddMatcher> ScaledWithOffset32Matcher; 453 typedef BaseWithIndexAndDisplacementMatcher<Int32AddMatcher>
390 typedef ScaledWithOffsetMatcher<Int64AddMatcher> ScaledWithOffset64Matcher; 454 BaseWithIndexAndDisplacement32Matcher;
455 typedef BaseWithIndexAndDisplacementMatcher<Int64AddMatcher>
456 BaseWithIndexAndDisplacement64Matcher;
391 457
392 } // namespace compiler 458 } // namespace compiler
393 } // namespace internal 459 } // namespace internal
394 } // namespace v8 460 } // namespace v8
395 461
396 #endif // V8_COMPILER_NODE_MATCHERS_H_ 462 #endif // V8_COMPILER_NODE_MATCHERS_H_
OLDNEW
« no previous file with comments | « no previous file | src/compiler/x64/code-generator-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698