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

Side by Side Diff: src/compiler/machine-operator-reducer.cc

Issue 683793003: [turbofan] fold constants in compares (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebase 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
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 #include "src/compiler/machine-operator-reducer.h" 5 #include "src/compiler/machine-operator-reducer.h"
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/base/division-by-constant.h" 8 #include "src/base/division-by-constant.h"
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/compiler/generic-node-inl.h" 10 #include "src/compiler/generic-node-inl.h"
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 } 235 }
236 case IrOpcode::kWord32Ror: { 236 case IrOpcode::kWord32Ror: {
237 Int32BinopMatcher m(node); 237 Int32BinopMatcher m(node);
238 if (m.right().Is(0)) return Replace(m.left().node()); // x ror 0 => x 238 if (m.right().Is(0)) return Replace(m.left().node()); // x ror 0 => x
239 if (m.IsFoldable()) { // K ror K => K 239 if (m.IsFoldable()) { // K ror K => K
240 return ReplaceInt32( 240 return ReplaceInt32(
241 base::bits::RotateRight32(m.left().Value(), m.right().Value())); 241 base::bits::RotateRight32(m.left().Value(), m.right().Value()));
242 } 242 }
243 break; 243 break;
244 } 244 }
245 case IrOpcode::kWord32Equal: { 245 case IrOpcode::kWord32Equal:
246 Int32BinopMatcher m(node); 246 return ReduceWord32Equal(node);
247 if (m.IsFoldable()) { // K == K => K 247 case IrOpcode::kWord64Equal:
248 return ReplaceBool(m.left().Value() == m.right().Value()); 248 return ReduceWord64Equal(node);
249 }
250 if (m.left().IsInt32Sub() && m.right().Is(0)) { // x - y == 0 => x == y
251 Int32BinopMatcher msub(m.left().node());
252 node->ReplaceInput(0, msub.left().node());
253 node->ReplaceInput(1, msub.right().node());
254 return Changed(node);
255 }
256 // TODO(turbofan): fold HeapConstant, ExternalReference, pointer compares
257 if (m.LeftEqualsRight()) return ReplaceBool(true); // x == x => true
258 break;
259 }
260 case IrOpcode::kWord64Equal: {
261 Int64BinopMatcher m(node);
262 if (m.IsFoldable()) { // K == K => K
263 return ReplaceBool(m.left().Value() == m.right().Value());
264 }
265 if (m.left().IsInt64Sub() && m.right().Is(0)) { // x - y == 0 => x == y
266 Int64BinopMatcher msub(m.left().node());
267 node->ReplaceInput(0, msub.left().node());
268 node->ReplaceInput(1, msub.right().node());
269 return Changed(node);
270 }
271 // TODO(turbofan): fold HeapConstant, ExternalReference, pointer compares
272 if (m.LeftEqualsRight()) return ReplaceBool(true); // x == x => true
273 break;
274 }
275 case IrOpcode::kInt32Add: { 249 case IrOpcode::kInt32Add: {
276 Int32BinopMatcher m(node); 250 Int32BinopMatcher m(node);
277 if (m.right().Is(0)) return Replace(m.left().node()); // x + 0 => x 251 if (m.right().Is(0)) return Replace(m.left().node()); // x + 0 => x
278 if (m.IsFoldable()) { // K + K => K 252 if (m.IsFoldable()) { // K + K => K
279 return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) + 253 return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) +
280 static_cast<uint32_t>(m.right().Value())); 254 static_cast<uint32_t>(m.right().Value()));
281 } 255 }
282 break; 256 break;
283 } 257 }
284 case IrOpcode::kInt32Sub: { 258 case IrOpcode::kInt32Sub: {
(...skipping 27 matching lines...) Expand all
312 break; 286 break;
313 } 287 }
314 case IrOpcode::kInt32Div: 288 case IrOpcode::kInt32Div:
315 return ReduceInt32Div(node); 289 return ReduceInt32Div(node);
316 case IrOpcode::kUint32Div: 290 case IrOpcode::kUint32Div:
317 return ReduceUint32Div(node); 291 return ReduceUint32Div(node);
318 case IrOpcode::kInt32Mod: 292 case IrOpcode::kInt32Mod:
319 return ReduceInt32Mod(node); 293 return ReduceInt32Mod(node);
320 case IrOpcode::kUint32Mod: 294 case IrOpcode::kUint32Mod:
321 return ReduceUint32Mod(node); 295 return ReduceUint32Mod(node);
322 case IrOpcode::kInt32LessThan: { 296 case IrOpcode::kInt32LessThan:
323 Int32BinopMatcher m(node); 297 return ReduceInt32LessThan(node);
324 if (m.IsFoldable()) { // K < K => K 298 case IrOpcode::kInt32LessThanOrEqual:
325 return ReplaceBool(m.left().Value() < m.right().Value()); 299 return ReduceInt32LessThanOrEqual(node);
326 } 300 case IrOpcode::kUint32LessThan:
327 if (m.left().IsInt32Sub() && m.right().Is(0)) { // x - y < 0 => x < y 301 return ReduceUint32LessThan(node);
328 Int32BinopMatcher msub(m.left().node()); 302 case IrOpcode::kUint32LessThanOrEqual:
329 node->ReplaceInput(0, msub.left().node()); 303 return ReduceUint32LessThanOrEqual(node);
330 node->ReplaceInput(1, msub.right().node());
331 return Changed(node);
332 }
333 if (m.left().Is(0) && m.right().IsInt32Sub()) { // 0 < x - y => y < x
334 Int32BinopMatcher msub(m.right().node());
335 node->ReplaceInput(0, msub.right().node());
336 node->ReplaceInput(1, msub.left().node());
337 return Changed(node);
338 }
339 if (m.LeftEqualsRight()) return ReplaceBool(false); // x < x => false
340 break;
341 }
342 case IrOpcode::kInt32LessThanOrEqual: {
343 Int32BinopMatcher m(node);
344 if (m.IsFoldable()) { // K <= K => K
345 return ReplaceBool(m.left().Value() <= m.right().Value());
346 }
347 if (m.left().IsInt32Sub() && m.right().Is(0)) { // x - y <= 0 => x <= y
348 Int32BinopMatcher msub(m.left().node());
349 node->ReplaceInput(0, msub.left().node());
350 node->ReplaceInput(1, msub.right().node());
351 return Changed(node);
352 }
353 if (m.left().Is(0) && m.right().IsInt32Sub()) { // 0 <= x - y => y <= x
354 Int32BinopMatcher msub(m.right().node());
355 node->ReplaceInput(0, msub.right().node());
356 node->ReplaceInput(1, msub.left().node());
357 return Changed(node);
358 }
359 if (m.LeftEqualsRight()) return ReplaceBool(true); // x <= x => true
360 break;
361 }
362 case IrOpcode::kUint32LessThan: {
363 Uint32BinopMatcher m(node);
364 if (m.left().Is(kMaxUInt32)) return ReplaceBool(false); // M < x => false
365 if (m.right().Is(0)) return ReplaceBool(false); // x < 0 => false
366 if (m.IsFoldable()) { // K < K => K
367 return ReplaceBool(m.left().Value() < m.right().Value());
368 }
369 if (m.LeftEqualsRight()) return ReplaceBool(false); // x < x => false
370 if (m.left().IsWord32Sar() && m.right().HasValue()) {
371 Int32BinopMatcher mleft(m.left().node());
372 if (mleft.right().HasValue()) {
373 // (x >> K) < C => x < (C << K) | (2^K - 1)
374 // when C < (M >> K)
375 const uint32_t c = m.right().Value();
376 const uint32_t k = mleft.right().Value() & 0x1f;
377 if (c < static_cast<uint32_t>(kMaxInt >> k)) {
378 node->ReplaceInput(0, mleft.left().node());
379 node->ReplaceInput(1, Uint32Constant((c << k) | ((1 << k) - 1)));
380 return Changed(node);
381 }
382 }
383 }
384 break;
385 }
386 case IrOpcode::kUint32LessThanOrEqual: {
387 Uint32BinopMatcher m(node);
388 if (m.left().Is(0)) return ReplaceBool(true); // 0 <= x => true
389 if (m.right().Is(kMaxUInt32)) return ReplaceBool(true); // x <= M => true
390 if (m.IsFoldable()) { // K <= K => K
391 return ReplaceBool(m.left().Value() <= m.right().Value());
392 }
393 if (m.LeftEqualsRight()) return ReplaceBool(true); // x <= x => true
394 break;
395 }
396 case IrOpcode::kFloat64Add: { 304 case IrOpcode::kFloat64Add: {
397 Float64BinopMatcher m(node); 305 Float64BinopMatcher m(node);
398 if (m.right().IsNaN()) { // x + NaN => NaN 306 if (m.right().IsNaN()) { // x + NaN => NaN
399 return Replace(m.right().node()); 307 return Replace(m.right().node());
400 } 308 }
401 if (m.IsFoldable()) { // K + K => K 309 if (m.IsFoldable()) { // K + K => K
402 return ReplaceFloat64(m.left().Value() + m.right().Value()); 310 return ReplaceFloat64(m.left().Value() + m.right().Value());
403 } 311 }
404 break; 312 break;
405 } 313 }
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 } 439 }
532 break; 440 break;
533 } 441 }
534 default: 442 default:
535 break; 443 break;
536 } 444 }
537 return NoChange(); 445 return NoChange();
538 } 446 }
539 447
540 448
449 static bool MatchBinopConstant(Node** left, int32_t* right) {
450 Int32BinopMatcher m(*left);
451 if (!m.right().HasValue()) return false;
452 *right = m.right().Value();
453 *left = m.left().node();
454 return true;
455 }
456
457
458 Reduction MachineOperatorReducer::ReduceCompare32(Node* compare) {
459 Int32BinopMatcher m(compare);
460 bool is_left_constant = false;
461 Node* node = NULL;
462 int32_t value = 0;
463 if (m.left().HasValue()) {
464 value = m.left().Value();
465 node = m.right().node();
466 is_left_constant = true;
467 } else if (m.right().HasValue()) {
468 value = m.right().Value();
469 node = m.left().node();
470 is_left_constant = false;
471 } else {
472 // No constant to fold.
473 return NoChange();
474 }
475 bool done;
476 do {
477 done = true;
478 int32_t temp = 0;
479 switch (node->opcode()) {
480 case IrOpcode::kInt32Add:
481 if (MatchBinopConstant(&node, &temp)) {
482 value -= temp;
483 done = false;
484 }
485 break;
486 case IrOpcode::kInt32Sub:
487 if (MatchBinopConstant(&node, &temp)) {
488 value += temp;
489 done = false;
490 }
491 break;
492 default:
493 break;
494 }
495 } while (!done);
496 // No change occured.
497 if (node == m.right().node() || node == m.left().node()) {
498 return NoChange();
499 }
500 int node_input = 0;
501 int const_input = 1;
502 if (is_left_constant) {
503 std::swap(node_input, const_input);
504 }
505 compare->ReplaceInput(node_input, node);
506 compare->ReplaceInput(const_input, Int32Constant(value));
507 return Changed(compare);
508 }
509
510
511 Reduction MachineOperatorReducer::ReduceWord32Equal(Node* node) {
512 Int32BinopMatcher m(node);
513 if (m.IsFoldable()) { // K == K => K
514 return ReplaceBool(m.left().Value() == m.right().Value());
515 }
516 if (m.left().IsInt32Sub() && m.right().Is(0)) { // x - y == 0 => x == y
517 Int32BinopMatcher msub(m.left().node());
518 node->ReplaceInput(0, msub.left().node());
519 node->ReplaceInput(1, msub.right().node());
520 return Changed(node);
521 }
522 // TODO(turbofan): fold HeapConstant, ExternalReference, pointer compares
523 if (m.LeftEqualsRight()) return ReplaceBool(true); // x == x => true
524 return ReduceCompare32(node);
525 }
526
527
528 Reduction MachineOperatorReducer::ReduceWord64Equal(Node* node) {
529 Int64BinopMatcher m(node);
530 if (m.IsFoldable()) { // K == K => K
531 return ReplaceBool(m.left().Value() == m.right().Value());
532 }
533 if (m.left().IsInt64Sub() && m.right().Is(0)) { // x - y == 0 => x == y
534 Int64BinopMatcher msub(m.left().node());
535 node->ReplaceInput(0, msub.left().node());
536 node->ReplaceInput(1, msub.right().node());
537 return Changed(node);
538 }
539 // TODO(turbofan): fold HeapConstant, ExternalReference, pointer compares
540 if (m.LeftEqualsRight()) return ReplaceBool(true); // x == x => true
541 // TODO(turbofan): add ReduceComputableCompare64?
542 return NoChange();
543 }
544
545
546 Reduction MachineOperatorReducer::ReduceInt32LessThan(Node* node) {
547 Int32BinopMatcher m(node);
548 if (m.IsFoldable()) { // K < K => K
549 return ReplaceBool(m.left().Value() < m.right().Value());
550 }
551 if (m.left().IsInt32Sub() && m.right().Is(0)) { // x - y < 0 => x < y
552 Int32BinopMatcher msub(m.left().node());
553 node->ReplaceInput(0, msub.left().node());
554 node->ReplaceInput(1, msub.right().node());
555 return Changed(node);
556 }
557 if (m.left().Is(0) && m.right().IsInt32Sub()) { // 0 < x - y => y < x
558 Int32BinopMatcher msub(m.right().node());
559 node->ReplaceInput(0, msub.right().node());
560 node->ReplaceInput(1, msub.left().node());
561 return Changed(node);
562 }
563 if (m.LeftEqualsRight()) return ReplaceBool(false); // x < x => false
564 return ReduceCompare32(node);
565 }
566
567
568 Reduction MachineOperatorReducer::ReduceInt32LessThanOrEqual(Node* node) {
569 Int32BinopMatcher m(node);
570 if (m.IsFoldable()) { // K <= K => K
571 return ReplaceBool(m.left().Value() <= m.right().Value());
572 }
573 if (m.left().IsInt32Sub() && m.right().Is(0)) { // x - y <= 0 => x <= y
574 Int32BinopMatcher msub(m.left().node());
575 node->ReplaceInput(0, msub.left().node());
576 node->ReplaceInput(1, msub.right().node());
577 return Changed(node);
578 }
579 if (m.left().Is(0) && m.right().IsInt32Sub()) { // 0 <= x - y => y <= x
580 Int32BinopMatcher msub(m.right().node());
581 node->ReplaceInput(0, msub.right().node());
582 node->ReplaceInput(1, msub.left().node());
583 return Changed(node);
584 }
585 if (m.LeftEqualsRight()) return ReplaceBool(true); // x <= x => true
586 return ReduceCompare32(node);
587 }
588
589
590 Reduction MachineOperatorReducer::ReduceUint32LessThan(Node* node) {
591 Uint32BinopMatcher m(node);
592 if (m.left().Is(kMaxUInt32)) return ReplaceBool(false); // M < x => false
593 if (m.right().Is(0)) return ReplaceBool(false); // x < 0 => false
594 if (m.IsFoldable()) { // K < K => K
595 return ReplaceBool(m.left().Value() < m.right().Value());
596 }
597 if (m.LeftEqualsRight()) return ReplaceBool(false); // x < x => false
598 if (m.left().IsWord32Sar() && m.right().HasValue()) {
599 Int32BinopMatcher mleft(m.left().node());
600 if (mleft.right().HasValue()) {
601 // (x >> K) < C => x < (C << K) | (2^K - 1)
602 // when C < (M >> K)
603 const uint32_t c = m.right().Value();
604 const uint32_t k = mleft.right().Value() & 0x1f;
605 if (c < static_cast<uint32_t>(kMaxInt >> k)) {
606 node->ReplaceInput(0, mleft.left().node());
607 node->ReplaceInput(1, Uint32Constant((c << k) | ((1 << k) - 1)));
608 return Changed(node);
609 }
610 }
611 }
612 return ReduceCompare32(node);
613 }
614
615
616 Reduction MachineOperatorReducer::ReduceUint32LessThanOrEqual(Node* node) {
617 Uint32BinopMatcher m(node);
618 if (m.left().Is(0)) return ReplaceBool(true); // 0 <= x => true
619 if (m.right().Is(kMaxUInt32)) return ReplaceBool(true); // x <= M => true
620 if (m.IsFoldable()) { // K <= K => K
621 return ReplaceBool(m.left().Value() <= m.right().Value());
622 }
623 if (m.LeftEqualsRight()) return ReplaceBool(true); // x <= x => true
624 return ReduceCompare32(node);
625 }
626
627
541 Reduction MachineOperatorReducer::ReduceInt32Div(Node* node) { 628 Reduction MachineOperatorReducer::ReduceInt32Div(Node* node) {
542 Int32BinopMatcher m(node); 629 Int32BinopMatcher m(node);
543 if (m.left().Is(0)) return Replace(m.left().node()); // 0 / x => 0 630 if (m.left().Is(0)) return Replace(m.left().node()); // 0 / x => 0
544 if (m.right().Is(0)) return Replace(m.right().node()); // x / 0 => 0 631 if (m.right().Is(0)) return Replace(m.right().node()); // x / 0 => 0
545 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x 632 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x
546 if (m.IsFoldable()) { // K / K => K 633 if (m.IsFoldable()) { // K / K => K
547 return ReplaceInt32( 634 return ReplaceInt32(
548 base::bits::SignedDiv32(m.left().Value(), m.right().Value())); 635 base::bits::SignedDiv32(m.left().Value(), m.right().Value()));
549 } 636 }
550 if (m.LeftEqualsRight()) { // x / x => x != 0 637 if (m.LeftEqualsRight()) { // x / x => x != 0
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 MachineOperatorBuilder* MachineOperatorReducer::machine() const { 805 MachineOperatorBuilder* MachineOperatorReducer::machine() const {
719 return jsgraph()->machine(); 806 return jsgraph()->machine();
720 } 807 }
721 808
722 809
723 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } 810 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); }
724 811
725 } // namespace compiler 812 } // namespace compiler
726 } // namespace internal 813 } // namespace internal
727 } // namespace v8 814 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/machine-operator-reducer.h ('k') | test/unittests/compiler/machine-operator-reducer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698