aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkyukhin <kyukhin@138bc75d-0d04-0410-961f-82ee72b054a4>2011-11-07 08:47:15 +0000
committerkyukhin <kyukhin@138bc75d-0d04-0410-961f-82ee72b054a4>2011-11-07 08:47:15 +0000
commit8a321966c53867d68e5528c9935a3570349010a8 (patch)
tree2501b8e1269ccfd5641293b19f8449fd7d94719f
parent9efaf576cea19c6a1c5272af7e5c9eba26152c91 (diff)
gcc/
PR target/50962 * config/i386/i386-protos.h (ix86_use_lea_for_mov): New. * config/i386/i386.c (ix86_use_lea_for_mov): Likewise. * config/i386/i386.md (movsi_internal): Emit lea if profitable. (movdi_internal_rex64): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@181077 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/config/i386/i386-protos.h1
-rw-r--r--gcc/config/i386/i386.c23
-rw-r--r--gcc/config/i386/i386.md7
-rw-r--r--gcc/testsuite/ChangeLog7
4 files changed, 37 insertions, 1 deletions
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index b2eb9733559..6bfe13d47d6 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -93,6 +93,7 @@ extern bool ix86_binary_operator_ok (enum rtx_code, enum machine_mode, rtx[]);
extern bool ix86_lea_outperforms (rtx, unsigned int, unsigned int,
unsigned int, unsigned int);
extern bool ix86_avoid_lea_for_add (rtx, rtx[]);
+extern bool ix86_use_lea_for_mov (rtx, rtx[]);
extern bool ix86_avoid_lea_for_addr (rtx, rtx[]);
extern void ix86_split_lea_for_addr (rtx[], enum machine_mode);
extern bool ix86_lea_for_add_ok (rtx, rtx[]);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index ca62b229089..b735ab555e0 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -16509,6 +16509,29 @@ ix86_avoid_lea_for_add (rtx insn, rtx operands[])
return !ix86_lea_outperforms (insn, regno0, regno1, regno2, 1);
}
+/* Return true if we should emit lea instruction instead of mov
+ instruction. */
+
+bool
+ix86_use_lea_for_mov (rtx insn, rtx operands[])
+{
+ unsigned int regno0;
+ unsigned int regno1;
+
+ /* Check if we need to optimize. */
+ if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
+ return false;
+
+ /* Use lea for reg to reg moves only. */
+ if (!REG_P (operands[0]) || !REG_P (operands[1]))
+ return false;
+
+ regno0 = true_regnum (operands[0]);
+ regno1 = true_regnum (operands[1]);
+
+ return ix86_lea_outperforms (insn, regno0, regno1, -1, 0);
+}
+
/* Return true if we need to split lea into a sequence of
instructions to avoid AGU stalls. */
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 39c4cd73f69..d6a82b654cd 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -2053,6 +2053,8 @@
return "mov{l}\t{%k1, %k0|%k0, %k1}";
else if (which_alternative == 2)
return "movabs{q}\t{%1, %0|%0, %1}";
+ else if (ix86_use_lea_for_mov(insn, operands))
+ return "lea{q}\t{%a1, %0|%0, %a1}";
else
return "mov{q}\t{%1, %0|%0, %1}";
}
@@ -2288,7 +2290,10 @@
default:
gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
- return "mov{l}\t{%1, %0|%0, %1}";
+ if (ix86_use_lea_for_mov(insn, operands))
+ return "lea{l}\t{%a1, %0|%0, %a1}";
+ else
+ return "mov{l}\t{%1, %0|%0, %1}";
}
}
[(set (attr "type")
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7e7209c1d63..66e56ee0aa5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2011-11-07 Enkovich Ilya <ilya.enkovich@intel.com>
+
+ PR target/50962
+ * config/i386/i386-protos.h (ix86_use_lea_for_mov): New.
+ * config/i386/i386.c (ix86_use_lea_for_mov): Likewise.
+ * config/i386/i386.md (movsi_internal): Emit lea if profitable.
+ (movdi_internal_rex64): Likewise.
2011-11-07 Sergey Ostanevich <sergos.gnu@gmail.com>