Thanks for the updates.

Chung-Ju Wu <jasonw...@gmail.com> writes:
> On 9/29/13 7:25 PM, Richard Sandiford wrote:
>> Chung-Ju Wu <jasonw...@gmail.com> writes:
>> 
>>> +  /* We need to provide a customized rtx which contains
>>> +     necessary information for data analysis,
>>> +     so we create a parallel rtx like this:
>>> +     (parallel [(unspec [(reg: Rb)
>>> +                         (reg: Re)
>>> +                         (const_int En4)] UNSPEC_STACK_PUSH_MULTIPLE)
>>> +                (use (reg:SI Rb))
>>> +                (use (reg:SI Re))
>>> +                (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
>>> +                     (reg:SI LP_REGNUM))
>>> +                (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
>>> +                     (reg:SI GP_REGNUM))
>>> +                (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
>>> +                     (reg:SI FP_REGNUM))
>>> +                (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
>>> +                     (reg:SI Re))
>>> +                ...
>>> +                (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
>>> +                     (reg:SI Rb+1))
>>> +                (set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
>>> +                     (reg:SI Rb))
>>> +                (set (reg:SI SP_REGNUM)
>>> +                     (plus (reg:SI SP_REGNUM) (const_int -32)))]) */
>> 
>> The "use"s here should be redundant, since the "set"s say that the
>> registers are used.  Same comment for:
>> 
>>> +  /* We need to provide a customized rtx which contains
>>> +     necessary information for data analysis,
>>> +     so we create a parallel rtx like this:
>>> +     (NOTE: We have to clearly claim that we are using/clobbering Rb and 
>>> Re,
>>> +            otherwise it may be renamed by optimization.)
>>> +     (parallel [(unspec [(reg: Rb)
>>> +                         (reg: Re)
>>> +                         (const_int En4)] UNSPEC_STACK_POP_MULTIPLE)
>>> +                (use (reg:SI Rb))
>>> +                (use (reg:SI Re))
>>> +                (clobber (reg:SI Rb))
>>> +                (clobber (reg:SI Re))
>>> +                (set (reg:SI Rb)
>>> +                     (mem (plus (reg:SI SP_REGNUM) (const_int 0))))
>>> +                (set (reg:SI Rb+1)
>>> +                     (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
>>> +                ...
>>> +                (set (reg:SI Re)
>>> +                     (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
>>> +                (set (reg:SI FP_REGNUM)
>>> +                     (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
>>> +                (set (reg:SI GP_REGNUM)
>>> +                     (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
>>> +                (set (reg:SI LP_REGNUM)
>>> +                     (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
>>> +                (set (reg:SI SP_REGNUM)
>>> +                     (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
>> 
>> the "use"s and "clobber"s here.  As far as the note goes, adding clobbers
>> isn't guaranteed to stop renaming, and it's not really valid for an rtx
>> to assign to the same register twice.
>> 
>> The best way of preventing renaming is to have a match_parallel that
>> checks every "set", a bit like you already did for the load/store multiple.
>> That should make the "unspec" unnecessary too.
>> 
>
> Now we remove all "use"s and "clobber"s from parallel rtx and
> use predicate function to check stack push/pop operation.
> Furthermore, once I remove unspec rtx as you suggested,
> I notice gcc is aware of the def-use dependency and it wouldn't
> perform unexpected register renaming.  So I think it was my
> faulty design of placing unspec/use/clobber within parallel rtx.

FWIW, it'd probably be better for nds32_valid_stack_push_pop to check
all the SETs in the PARALLEL, like nds32_valid_multiple_load_store does.
They could share a subroutine that checks for conesecutive loads and stores.
I.e. something like:

static bool
nds32_valid_multiple_load_store_1 (rtx op, bool load_p, int start, int end)
{
  ...
}

bool
nds32_valid_multiple_load_store (rtx op, bool load_p)
{
  return nds32_valid_multiple_load_store_1 (op, load_p, 0, XVECLEN (op, 0));
}

bool
nds32_valid_multiple_push_pop (rtx op, bool load_p)
{
  ...handle $lp, $gp and $fp cases, based on cframe->...
  if (!nds32_valid_multiple_load_store_1 (op, load_p, i, count - 1))
    return false;
  ...check last element...
}

Thanks,
Richard

Reply via email to