diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-12-22 23:34:07 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-12-22 23:34:07 +0000 |
commit | ad0a178f65bb4cf3be066dcc451820d15687c213 (patch) | |
tree | 5971e3d6c2cd233e84f89d0395f6d5c1beecc681 /gcc/builtins.c | |
parent | a1fd6678441313c9641660ee48a40d8d01afb1db (diff) | |
download | gcc-ad0a178f65bb4cf3be066dcc451820d15687c213.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@142891 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index d64290d3a0c..607d7dd36b1 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 |