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

Unified Diff: src/compiler/x64/instruction-selector-x64.cc

Issue 738073002: [turbofan]: More optimizations to add and subtract operations on x64 (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Latest 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 side-by-side diff with in-line comments
Download patch
Index: src/compiler/x64/instruction-selector-x64.cc
diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc
index ce7ce56616522b995dc51ce5ce3a1091556ad33c..9547a635090f8bd8c9418846c1a62eebb9d2b47b 100644
--- a/src/compiler/x64/instruction-selector-x64.cc
+++ b/src/compiler/x64/instruction-selector-x64.cc
@@ -434,9 +434,33 @@ void InstructionSelector::VisitInt32Add(Node* node) {
ScaledWithOffset32Matcher m(node);
X64OperandGenerator g(this);
if (m.matches() && (m.constant() == NULL || g.CanBeImmediate(m.constant()))) {
+ // The add can be represented as a "leal", but there may be a smaller
+ // representation that is better and no more expensive.
+ if (m.offset() != NULL) {
+ if (m.scaled() == NULL) {
+ if (!IsLive(m.offset())) {
+ // If the add is of the form (r1 + immediate) and the non-constant
+ // input to the add is owned by the add, then it doesn't need to be
+ // preserved across the operation, so use more compact,
+ // source-register-overwriting versions when they are available and
+ // smaller, e.g. "incl" and "decl".
+ int32_t value =
+ m.constant() == NULL ? 0 : OpParameter<int32_t>(m.constant());
+ if (value == 1) {
+ Emit(kX64Inc32, g.DefineSameAsFirst(node),
+ g.UseRegister(m.offset()));
+ return;
+ } else if (value == -1) {
+ Emit(kX64Dec32, g.DefineSameAsFirst(node),
+ g.UseRegister(m.offset()));
+ return;
+ }
+ }
+ }
+ }
+
InstructionOperand* inputs[4];
size_t input_count = 0;
-
AddressingMode mode = GenerateMemoryOperandInputs(
&g, m.scaled(), m.scale_exponent(), m.offset(), m.constant(), inputs,
&input_count);
@@ -468,6 +492,31 @@ void InstructionSelector::VisitInt32Sub(Node* node) {
if (m.left().Is(0)) {
Emit(kX64Neg32, g.DefineSameAsFirst(node), g.UseRegister(m.right().node()));
} else {
+ if (m.right().HasValue() && g.CanBeImmediate(m.right().node())) {
+ // If the Non-constant input is owned by the subtract, using a "decl" or
+ // "incl" that overwrites that input is smaller and probably an overall
+ // win.
+ if (!IsLive(m.left().node())) {
+ if (m.right().Value() == 1) {
+ Emit(kX64Dec32, g.DefineSameAsFirst(node),
+ g.UseRegister(m.left().node()));
+ return;
+ }
+ if (m.right().Value() == -1) {
+ Emit(kX64Inc32, g.DefineSameAsFirst(node),
+ g.UseRegister(m.left().node()));
+ return;
+ }
+ } else {
+ // Special handling for subtraction of constants where the non-constant
+ // input is used elsewhere. To eliminate the gap move before the sub to
+ // copy the destination register, use a "leal" instead.
+ Emit(kX64Lea32 | AddressingModeField::encode(kMode_MRI),
+ g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+ g.TempImmediate(-m.right().Value()));
+ return;
+ }
+ }
VisitBinop(this, node, kX64Sub32);
}
}
« no previous file with comments | « src/compiler/x64/instruction-codes-x64.h ('k') | test/unittests/compiler/x64/instruction-selector-x64-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698