------- 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

Reply via email to