aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2008-12-23 00:34:07 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2008-12-23 00:34:07 +0100
commit805903b5251042186344830f35161eaec7fedb69 (patch)
tree5971e3d6c2cd233e84f89d0395f6d5c1beecc681 /gcc/builtins.c
parentd797a4ed797b6ba140e7fc9059835b74335cbcf5 (diff)
downloadgcc-805903b5251042186344830f35161eaec7fedb69.zip
gcc-805903b5251042186344830f35161eaec7fedb69.tar.gz
gcc-805903b5251042186344830f35161eaec7fedb69.tar.bz2
re PR target/38488 (x86_64 generates much larger and slightly slower code for memset)
* config/i386/i386.c (expand_setmem_via_rep_stos): Add ORIG_VALUE argument. If ORIG_VALUE is const0_rtx and COUNT is constant, set MEM_SIZE on DESTMEM. (ix86_expand_setmem): Adjust callers. PR target/38488 * expr.h (get_mem_align_offset): New prototype. * emit-rtl.c (get_mem_align_offset): New function. * config/i386/i386.c (expand_movmem_via_rep_mov): Set MEM_SIZE correctly. (expand_constant_movmem_prologue, expand_constant_setmem_prologue): New functions. (ix86_expand_movmem): Optimize if COUNT_EXP is constant, desired_align > align and dst & (desired_align - 1) is computable at compile time. (ix86_expand_setmem): Likewise. * builtins.c (get_memory_rtx): Try to derive MEM_ATTRS from not yet resolved SAVE_EXPR or POINTER_PLUS_EXPR. From-SVN: r142891
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index d64290d..607d7dd 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -1094,8 +1094,17 @@ expand_builtin_prefetch (tree exp)
static rtx
get_memory_rtx (tree exp, tree len)
{
- rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
- rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
+ tree orig_exp = exp;
+ rtx addr, mem;
+ HOST_WIDE_INT off;
+
+ /* When EXP is not resolved SAVE_EXPR, MEM_ATTRS can be still derived
+ from its expression, for expr->a.b only <variable>.a.b is recorded. */
+ if (TREE_CODE (exp) == SAVE_EXPR && !SAVE_EXPR_RESOLVED_P (exp))
+ exp = TREE_OPERAND (exp, 0);
+
+ addr = expand_expr (orig_exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
+ mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
/* Get an expression we can use to find the attributes to assign to MEM.
If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
@@ -1104,7 +1113,13 @@ get_memory_rtx (tree exp, tree len)
&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
exp = TREE_OPERAND (exp, 0);
- if (TREE_CODE (exp) == ADDR_EXPR)
+ off = 0;
+ if (TREE_CODE (exp) == POINTER_PLUS_EXPR
+ && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
+ && host_integerp (TREE_OPERAND (exp, 1), 0)
+ && (off = tree_low_cst (TREE_OPERAND (exp, 1), 0)) > 0)
+ exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+ else if (TREE_CODE (exp) == ADDR_EXPR)
exp = TREE_OPERAND (exp, 0);
else if (POINTER_TYPE_P (TREE_TYPE (exp)))
exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
@@ -1118,6 +1133,9 @@ get_memory_rtx (tree exp, tree len)
{
set_mem_attributes (mem, exp, 0);
+ if (off)
+ mem = adjust_automodify_address_nv (mem, BLKmode, NULL, off);
+
/* Allow the string and memory builtins to overflow from one
field into another, see http://gcc.gnu.org/PR23561.
Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole