Full test2.c.209r.reload is about 296kb and i can't send successfully.
Is there another way to send the dump file?

Shiva

2013/4/18 Shiva Chen <shiva0...@gmail.com>:
> Hi, Vladimir
>
> attachment is the ira dump of the case
>
> Shiva
>
> 2013/4/17 Vladimir Makarov <vmaka...@redhat.com>:
>> On 13-04-15 1:20 AM, shiva Chen wrote:
>>>
>>> HI,
>>>
>>> I'm trying to port a new 32bit target to GCC 4.8.0 with LRA enabled
>>>
>>> There is an error case which generates following RTL
>>>
>>>
>>>   (insn 536 267 643 3 (set (reg/f:SI 0 $r0 [477])  <== r477 assign to r0
>>>           (plus:SI (reg/f:SI 31 $sp)
>>>               (const_int 112 [0x70]))) test2.c:95 64 {*addsi3}
>>>        (nil))
>>>   (insn 643 536 537 3 (set (reg/f:SI 0 $r0 [565])   <== r565 assign to
>>> r0, and corrupt the usage of r477
>>>           (reg/f:SI 31 $sp)) test2.c:95 44 {*movsi}
>>>        (nil))
>>>   (insn 537 643 538 3 (set (reg/v:SI 13 $r13 [orig:61 i14 ] [61])
>>>           (mem/c:SI (plus:SI (reg/f:SI 0 $r0 [565])   <== use r565
>>>                   (const_int 136 [0x88])) [5 %sfp+24 S4 A32])) test2.c:95
>>> 39
>>> {*load_si}
>>>        (expr_list:REG_DEAD (reg/f:SI 0 $r0 [565])
>>>           (nil)))
>>> ...
>>>   (insn 539 540 270 3 (set (reg:SI 0 $r0 [479])
>>>           (plus:SI (reg/f:SI 0 $r0 [477])
>>>               (reg:SI 5 $r5 [480]))) test2.c:95 62 {*add_16bit}
>>>        (expr_list:REG_DEAD (reg:SI 5 $r5 [480])
>>>          (expr_list:REG_DEAD (reg/f:SI 0 $r0 [477]) <== use r477 which
>>> should be  $sp +112
>>>
>>> Note that the live ranges of r477 and r565 are overlapped but assigned
>>> same register $r0. (r31 is stack pointer)
>>>
>>> By tracing LRA process, I noticed that when r477 is created,
>>> the lra_reg_info[r477].val = lra_reg_info[r31] due to (set r477 r31).
>>> But after lra_eliminate(), the stack offset changes and
>>> r477 is equal to r31+112 instead.
>>>
>>> In next lra-iteration round, r565 is created, and r565 = r31.
>>>
>>> In that case, register content of r477 should treat as not equal to
>>> r565 due to eliminate offset have been changed.
>>>
>>> Otherwise, r565 and r477 may assign to same hard register.
>>>
>>>
>>> To recognize that, I record the eliminate offset when the pseudo
>>> register have been created.
>>>
>>> Register content are the same only when lra_reg_info[].val and
>>> lra_reg_info[].offset are equal.
>>>
>>>
>>>   gcc/lra-assigns.c |    6 ++++--
>>>   gcc/lra-int.h     |    2 ++
>>>   gcc/lra.c         |   12 +++++++++++-
>>>   3 files changed, 17 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c
>>> index b204513..daf0aa9 100644
>>> --- a/gcc/lra-assigns.c
>>> +++ b/gcc/lra-assigns.c
>>> @@ -448,7 +448,7 @@ find_hard_regno_for (int regno, int *cost, int
>>> try_only_hard_regno)
>>>     int hr, conflict_hr, nregs;
>>>     enum machine_mode biggest_mode;
>>>     unsigned int k, conflict_regno;
>>> -  int val, biggest_nregs, nregs_diff;
>>> +  int offset, val, biggest_nregs, nregs_diff;
>>>     enum reg_class rclass;
>>>     bitmap_iterator bi;
>>>     bool *rclass_intersect_p;
>>> @@ -508,9 +508,11 @@ find_hard_regno_for (int regno, int *cost, int
>>> try_only_hard_regno)
>>>   #endif
>>>     sparseset_clear_bit (conflict_reload_and_inheritance_pseudos, regno);
>>>     val = lra_reg_info[regno].val;
>>> +  offset = lra_reg_info[regno].offset;
>>>     CLEAR_HARD_REG_SET (impossible_start_hard_regs);
>>>     EXECUTE_IF_SET_IN_SPARSESET (live_range_hard_reg_pseudos,
>>> conflict_regno)
>>> -    if (val == lra_reg_info[conflict_regno].val)
>>> +    if ((val == lra_reg_info[conflict_regno].val)
>>> +        && (offset == lra_reg_info[conflict_regno].offset))
>>>         {
>>>          conflict_hr = live_pseudos_reg_renumber[conflict_regno];
>>>          nregs = (hard_regno_nregs[conflict_hr]
>>> diff --git a/gcc/lra-int.h b/gcc/lra-int.h
>>> index 98f2ff7..8ae4eb0 100644
>>> --- a/gcc/lra-int.h
>>> +++ b/gcc/lra-int.h
>>> @@ -116,6 +116,8 @@ struct lra_reg
>>>     /* Value holding by register.         If the pseudos have the same
>>> value
>>>        they do not conflict.  */
>>>     int val;
>>> +  /* Eliminate offset of the pseduo have been created.  */
>>> +  int offset;
>>>     /* These members are set up in lra-lives.c and updated in
>>>        lra-coalesce.c.  */
>>>     /* The biggest size mode in which each pseudo reg is referred in
>>> diff --git a/gcc/lra.c b/gcc/lra.c
>>> index 9df24b5..69962be 100644
>>> --- a/gcc/lra.c
>>> +++ b/gcc/lra.c
>>> @@ -194,7 +194,17 @@ lra_create_new_reg (enum machine_mode md_mode,
>>> rtx original,
>>>     new_reg
>>>       = lra_create_new_reg_with_unique_value (md_mode, original, rclass,
>>> title);
>>>     if (original != NULL_RTX && REG_P (original))
>>> -    lra_reg_info[REGNO (new_reg)].val = lra_reg_info[REGNO
>>> (original)].val;
>>> +    {
>>> +      lra_reg_info[REGNO (new_reg)].val = lra_reg_info[REGNO
>>> (original)].val;
>>> +
>>> +      rtx x = lra_eliminate_regs (original, VOIDmode, NULL_RTX);
>>> +
>>> +      if (GET_CODE (x) == PLUS
>>> +         && GET_CODE (XEXP (x, 1)) == CONST_INT)
>>> +       lra_reg_info[REGNO (new_reg)].offset = INTVAL (XEXP (x, 1));
>>> +      else
>>> +       lra_reg_info[REGNO (new_reg)].offset = 0;
>>> +    }
>>>     return new_reg;
>>>   }
>>>
>>> --
>>> 1.7.9.5
>>>
>>>
>>> Comments?
>>>
>>>
>> Thanks for working on it, Shiva.  Could you send me full dump for lra (and
>> ira if possible) for better understanding the problem situation.  It is hard
>> for me to say now that your solution is complete (e.g. offsets can be
>> changed again).

Reply via email to