This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/28690] [4.2/4.3 Regression] Performace problem with indexed load/stores on powerpc
- From: "bergner at vnet dot ibm dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 8 Nov 2006 03:30:42 -0000
- Subject: [Bug middle-end/28690] [4.2/4.3 Regression] Performace problem with indexed load/stores on powerpc
- References: <bug-28690-5233@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #24 from bergner at vnet dot ibm dot com 2006-11-08 03:30 -------
Ok, Anton hit another test case the last patch doesn't transform. It's
actually the same test case as in comment #13, except, "int *base" is now a
global variable rather than a function parameter.
int *base;
int indexedload(int len)
{
int i, sum = 0;
for (i=0; i < len; i++)
sum += base[i];
return sum;
}
With this case, we get the following RTL generated for the load of *base into a
register:
;; base.1 = base
(insn 24 22 25 (set (reg:SI 129)
(high:SI (symbol_ref:SI ("base") [flags 0x84] <var_decl 0x400a6930
base>))) -1 (nil)
(nil))
(insn 25 24 26 (set (reg/f:SI 128)
(lo_sum:SI (reg:SI 129)
(symbol_ref:SI ("base") [flags 0x84] <var_decl 0x400a6930 base>)))
-1 (nil)
(expr_list:REG_EQUAL (symbol_ref:SI ("base") [flags 0x84] <var_decl
0x400a6930 base>)
(nil)))
(insn 26 25 0 (set (reg:SI 124 [ base.1 ])
(mem/c/i:SI (reg/f:SI 128) [3 base+0 S4 A32])) -1 (nil)
(nil))
There seem to be two problems here. First, the mem/c/i:SI (reg/f:SI 128) seems
to be missing a MEM_POINTER attribute. I tracked that down to
rtl.h:MEM_COPY_ATTRIBUTES(LHS,RHS) not copying the MEM_POINTER attribute from
RHS to LHS. I added the code to do that, so the mem above does get the
MEM_POINTER flag set. However, the reg:SI 124 [base.1] is still missing the
REG_POINTER flag.
This second problem seems to be a problem in expand_one_register_var(tree var).
In this specific case, var seems to be a pointer type, but looks to be
"artifical", so we skip the code that would have marked the reg rtx with the
REG_POINTER:
Breakpoint 4, expand_one_register_var (var=0x400a6d90) at
/home/bergner/gcc/gcc-mainline-rtlanal/gcc/cfgexpand.c:643
643 tree type = TREE_TYPE (var);
(gdb) call debug_tree (var)
<var_decl 0x400a6d90 base.1
type <pointer_type 0x4009ae38
type <integer_type 0x4009a340 int sizes-gimplified public SI
size <integer_cst 0x4008e5e0 constant invariant 32>
unit size <integer_cst 0x4008e2a0 constant invariant 4>
align 32 symtab 0 alias set 2 precision 32 min <integer_cst
0x4008e580 -2147483648> max <integer_cst 0x4008e5a0 2147483647>
pointer_to_this <pointer_type 0x4009ae38>>
public unsigned SI size <integer_cst 0x4008e5e0 32> unit size
<integer_cst 0x4008e2a0 4>
align 32 symtab 0 alias set 3>
used unsigned ignored SI file indexedload5.c line 7 size <integer_cst
0x4008e5e0 32> unit size <integer_cst 0x4008e2a0 4>
align 32 context <function_decl 0x40151f00 indexedload> chain <var_decl
0x400a6e00 D.1531>>
(gdb) p var->decl_common.artificial_flag
$8 = 1
If I clear var->decl_common.artificial_flag with the debugger and continue,
then we get the REG_POINTER flag set and the indexed load is generated with the
base pointer first like we want. Does anyone know why var above was marked as
artifical?
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28690