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

Side by Side Diff: src/compiler/x64/instruction-selector-x64.cc

Issue 737153003: [turbofan]: remove optimization of adds/subs to inc and dec (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Whitespace 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 | test/unittests/compiler/x64/instruction-selector-x64-unittest.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 #include "src/compiler/generic-node-inl.h" 5 #include "src/compiler/generic-node-inl.h"
6 #include "src/compiler/instruction-selector-impl.h" 6 #include "src/compiler/instruction-selector-impl.h"
7 #include "src/compiler/node-matchers.h" 7 #include "src/compiler/node-matchers.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 return mode; 420 return mode;
421 } 421 }
422 422
423 } // namespace 423 } // namespace
424 424
425 425
426 void InstructionSelector::VisitInt32Add(Node* node) { 426 void InstructionSelector::VisitInt32Add(Node* node) {
427 // Try to match the Add to a leal pattern 427 // Try to match the Add to a leal pattern
428 ScaledWithOffset32Matcher m(node); 428 ScaledWithOffset32Matcher m(node);
429 X64OperandGenerator g(this); 429 X64OperandGenerator g(this);
430 // It's possible to use a "leal", but it may not be smaller/cheaper. In the
431 // case that there are only two operands to the add and one of them isn't
432 // live, use a plain "addl".
430 if (m.matches() && (m.constant() == NULL || g.CanBeImmediate(m.constant()))) { 433 if (m.matches() && (m.constant() == NULL || g.CanBeImmediate(m.constant()))) {
431 // The add can be represented as a "leal", but there may be a smaller
432 // representation that is better and no more expensive.
433 if (m.offset() != NULL) { 434 if (m.offset() != NULL) {
434 if (m.scaled() == NULL) { 435 if (m.constant() == NULL) {
435 if (!IsLive(m.offset())) { 436 if (m.scaled() != NULL && m.scale_exponent() == 0) {
436 // If the add is of the form (r1 + immediate) and the non-constant 437 if (!IsLive(m.offset())) {
437 // input to the add is owned by the add, then it doesn't need to be 438 Emit(kX64Add32, g.DefineSameAsFirst(node),
438 // preserved across the operation, so use more compact, 439 g.UseRegister(m.offset()), g.Use(m.scaled()));
439 // source-register-overwriting versions when they are available and
440 // smaller, e.g. "incl" and "decl".
441 int32_t value =
442 m.constant() == NULL ? 0 : OpParameter<int32_t>(m.constant());
443 if (value == 1) {
444 Emit(kX64Inc32, g.DefineSameAsFirst(node),
445 g.UseRegister(m.offset()));
446 return; 440 return;
447 } else if (value == -1) { 441 } else if (!IsLive(m.scaled())) {
448 Emit(kX64Dec32, g.DefineSameAsFirst(node), 442 Emit(kX64Add32, g.DefineSameAsFirst(node),
449 g.UseRegister(m.offset())); 443 g.UseRegister(m.scaled()), g.Use(m.offset()));
450 return; 444 return;
451 } 445 }
452 } 446 }
447 } else {
448 if (m.scale_exponent() == 0) {
449 if (m.scaled() == NULL || m.offset() == NULL) {
450 Node* non_constant = m.scaled() == NULL ? m.offset() : m.scaled();
451 if (!IsLive(non_constant)) {
452 Emit(kX64Add32, g.DefineSameAsFirst(node),
453 g.UseRegister(non_constant), g.UseImmediate(m.constant()));
454 return;
455 }
456 }
457 }
453 } 458 }
454 } 459 }
455 460
456 InstructionOperand* inputs[4]; 461 InstructionOperand* inputs[4];
457 size_t input_count = 0; 462 size_t input_count = 0;
458 AddressingMode mode = GenerateMemoryOperandInputs( 463 AddressingMode mode = GenerateMemoryOperandInputs(
459 &g, m.scaled(), m.scale_exponent(), m.offset(), m.constant(), inputs, 464 &g, m.scaled(), m.scale_exponent(), m.offset(), m.constant(), inputs,
460 &input_count); 465 &input_count);
461 466
462 DCHECK_NE(0, static_cast<int>(input_count)); 467 DCHECK_NE(0, static_cast<int>(input_count));
(...skipping 17 matching lines...) Expand all
480 } 485 }
481 486
482 487
483 void InstructionSelector::VisitInt32Sub(Node* node) { 488 void InstructionSelector::VisitInt32Sub(Node* node) {
484 X64OperandGenerator g(this); 489 X64OperandGenerator g(this);
485 Int32BinopMatcher m(node); 490 Int32BinopMatcher m(node);
486 if (m.left().Is(0)) { 491 if (m.left().Is(0)) {
487 Emit(kX64Neg32, g.DefineSameAsFirst(node), g.UseRegister(m.right().node())); 492 Emit(kX64Neg32, g.DefineSameAsFirst(node), g.UseRegister(m.right().node()));
488 } else { 493 } else {
489 if (m.right().HasValue() && g.CanBeImmediate(m.right().node())) { 494 if (m.right().HasValue() && g.CanBeImmediate(m.right().node())) {
490 // If the Non-constant input is owned by the subtract, using a "decl" or 495 if (IsLive(m.left().node())) {
491 // "incl" that overwrites that input is smaller and probably an overall
492 // win.
493 if (!IsLive(m.left().node())) {
494 if (m.right().Value() == 1) {
495 Emit(kX64Dec32, g.DefineSameAsFirst(node),
496 g.UseRegister(m.left().node()));
497 return;
498 }
499 if (m.right().Value() == -1) {
500 Emit(kX64Inc32, g.DefineSameAsFirst(node),
501 g.UseRegister(m.left().node()));
502 return;
503 }
504 } else {
505 // Special handling for subtraction of constants where the non-constant 496 // Special handling for subtraction of constants where the non-constant
506 // input is used elsewhere. To eliminate the gap move before the sub to 497 // input is used elsewhere. To eliminate the gap move before the sub to
507 // copy the destination register, use a "leal" instead. 498 // copy the destination register, use a "leal" instead.
508 Emit(kX64Lea32 | AddressingModeField::encode(kMode_MRI), 499 Emit(kX64Lea32 | AddressingModeField::encode(kMode_MRI),
509 g.DefineAsRegister(node), g.UseRegister(m.left().node()), 500 g.DefineAsRegister(node), g.UseRegister(m.left().node()),
510 g.TempImmediate(-m.right().Value())); 501 g.TempImmediate(-m.right().Value()));
511 return; 502 return;
512 } 503 }
513 } 504 }
514 VisitBinop(this, node, kX64Sub32); 505 VisitBinop(this, node, kX64Sub32);
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 MachineOperatorBuilder::kFloat64Ceil | 1200 MachineOperatorBuilder::kFloat64Ceil |
1210 MachineOperatorBuilder::kFloat64RoundTruncate | 1201 MachineOperatorBuilder::kFloat64RoundTruncate |
1211 MachineOperatorBuilder::kWord32ShiftIsSafe; 1202 MachineOperatorBuilder::kWord32ShiftIsSafe;
1212 } 1203 }
1213 return MachineOperatorBuilder::kNoFlags; 1204 return MachineOperatorBuilder::kNoFlags;
1214 } 1205 }
1215 1206
1216 } // namespace compiler 1207 } // namespace compiler
1217 } // namespace internal 1208 } // namespace internal
1218 } // namespace v8 1209 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/unittests/compiler/x64/instruction-selector-x64-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698