public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Question on gcc RTL and scheduling step.
@ 2020-02-26 15:10 Henri Cloetens
  2020-02-26 16:39 ` Segher Boessenkool
  0 siblings, 1 reply; 6+ messages in thread
From: Henri Cloetens @ 2020-02-26 15:10 UTC (permalink / raw)
  To: gcc-help

Hello All,

I have a problem with GCC during scheduling.

The code I have after scheduling is given below (below the text).
What happens, is follows:

1. The epilogue generator emits an instruction "popret_internal" that
     a. Restores R18 in mode DI. (which corresponds to R18 and R19 in 
mode SI)
     b. Does the function return.
2. Then, during scheduling, the compiler shifts an add instruction PAST 
this return
     instruction, which is incorrect, because:
    (a.) The instruction writes R19. (it restores R18 and R19). The 
scheduler should see this.
    (b.) The instruction changes the PC (program counter).
Q. Why is this happening ?. How can I prevent this ?.

Best Regards,

Henri.

(insn:TI 44 15 18 2 (parallel [
             (parallel [
                     (set (reg/f:SI 31 %r31)
                         (plus:SI (reg/f:SI 31 %r31)
                             (const_int 24 [0x18])))
                     (set (reg:DI 0 %r0)
                         (mem/c:DI (plus:SI (reg/f:SI 31 %r31)
                                 (const_int 16 [0x10])) [2  S8 A64]))
                     (set (reg:DI 18 %r18)
                         (mem/c:DI (plus:SI (reg/f:SI 31 %r31)
                                 (const_int 8 [0x8])) [2  S8 A64]))
                 ])
             (set (pc)
                 (return))
         ]) "use_manyregs.c":9:1 1 {popret_internal}
      (nil))
(insn:TI 18 44 21 2 (set (reg:SI 21 %r21 [88])
         (plus:SI (reg:SI 19 %r19 [orig:87 b1 ] [87])
             (reg:SI 30 %r30 [orig:75 a1.0_2 ] [75]))) 
"use_manyregs.c":8:10 8 {addsi3_internal}
      (expr_list:REG_DEAD (reg:SI 19 %r19 [orig:87 b1 ] [87])
         (nil)))

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Question on gcc RTL and scheduling step.
  2020-02-26 15:10 Question on gcc RTL and scheduling step Henri Cloetens
@ 2020-02-26 16:39 ` Segher Boessenkool
  2020-02-26 17:02   ` Henri Cloetens
  0 siblings, 1 reply; 6+ messages in thread
From: Segher Boessenkool @ 2020-02-26 16:39 UTC (permalink / raw)
  To: Henri Cloetens; +Cc: gcc-help

Hi!

On Wed, Feb 26, 2020 at 01:02:46PM +0100, Henri Cloetens wrote:
> 1. The epilogue generator emits an instruction "popret_internal" that
>     a. Restores R18 in mode DI. (which corresponds to R18 and R19 in 
> mode SI)
>     b. Does the function return.
> 2. Then, during scheduling, the compiler shifts an add instruction PAST 
> this return
>     instruction, which is incorrect, because:
>    (a.) The instruction writes R19. (it restores R18 and R19). The 
> scheduler should see this.

Yes.  So why doesn't it?  Look at the various dump files to see what the
df ("dataflow") framework thinks about this.

>    (b.) The instruction changes the PC (program counter).

The documentation says you should write just
  (return)
instead of
  (set (pc) (return))
(unlikely to be causing any of this, but a good cleanup to make).

> Q. Why is this happening ?. How can I prevent this ?.

You can have the scheduler print much more debugging info, but I'd
start with the usual stuff: -dap.


Segher

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Question on gcc RTL and scheduling step.
  2020-02-26 16:39 ` Segher Boessenkool
@ 2020-02-26 17:02   ` Henri Cloetens
  2020-02-26 22:00     ` Segher Boessenkool
  0 siblings, 1 reply; 6+ messages in thread
From: Henri Cloetens @ 2020-02-26 17:02 UTC (permalink / raw)
  Cc: gcc-help

Hello Segher, all,

- On the issue of the restore of R18 in mode DI, it seems from
   analysing the log file that the compiler does not understand this
   also affects R19. This looks a bug to me ??. Anyway, I have resolved
   this, by adding a 'clobber' statement to R19 when R18 is written
   in mode 'DI'.
- The other issue, I have changed ((set) (pc) (return)) to (return),
   but, as far as I understand the logfiles, and the documentation,
   both forms are equivalent. Anyway, after fixing the first issue, I do
   not see the second issue any more.

Best Regards and thanks,

Henri.



On 02/26/2020 01:59 PM, Segher Boessenkool wrote:
> Hi!
>
> On Wed, Feb 26, 2020 at 01:02:46PM +0100, Henri Cloetens wrote:
>> 1. The epilogue generator emits an instruction "popret_internal" that
>>      a. Restores R18 in mode DI. (which corresponds to R18 and R19 in
>> mode SI)
>>      b. Does the function return.
>> 2. Then, during scheduling, the compiler shifts an add instruction PAST
>> this return
>>      instruction, which is incorrect, because:
>>     (a.) The instruction writes R19. (it restores R18 and R19). The
>> scheduler should see this.
> Yes.  So why doesn't it?  Look at the various dump files to see what the
> df ("dataflow") framework thinks about this.
>
>>     (b.) The instruction changes the PC (program counter).
> The documentation says you should write just
>    (return)
> instead of
>    (set (pc) (return))
> (unlikely to be causing any of this, but a good cleanup to make).
>
>> Q. Why is this happening ?. How can I prevent this ?.
> You can have the scheduler print much more debugging info, but I'd
> start with the usual stuff: -dap.
>
>
> Segher
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Question on gcc RTL and scheduling step.
  2020-02-26 17:02   ` Henri Cloetens
@ 2020-02-26 22:00     ` Segher Boessenkool
  2020-02-27  7:43       ` Henri Cloetens
  0 siblings, 1 reply; 6+ messages in thread
From: Segher Boessenkool @ 2020-02-26 22:00 UTC (permalink / raw)
  To: Henri Cloetens; +Cc: gcc-help

[ Top-post do please not. ]

On Wed, Feb 26, 2020 at 04:11:06PM +0100, Henri Cloetens wrote:
> - On the issue of the restore of R18 in mode DI, it seems from
>   analysing the log file that the compiler does not understand this
>   also affects R19. This looks a bug to me ??. Anyway, I have resolved
>   this, by adding a 'clobber' statement to R19 when R18 is written
>   in mode 'DI'.

You haven't showed any evidence like this, so it's hard for use to help
you with this at all.  *Is* DImode a two register mode in your backend?

> - The other issue, I have changed ((set) (pc) (return)) to (return),
>   but, as far as I understand the logfiles, and the documentation,
>   both forms are equivalent. Anyway, after fixing the first issue, I do
>   not see the second issue any more.

The docs say
  Note that an insn pattern of @code{(return)} is logically equivalent to
  @code{(set (pc) (return))}, but the latter form is never used.

If something is never used, then not everything might expect that form,
that's all.


Segher

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Question on gcc RTL and scheduling step.
  2020-02-26 22:00     ` Segher Boessenkool
@ 2020-02-27  7:43       ` Henri Cloetens
  2020-02-27  9:23         ` Segher Boessenkool
  0 siblings, 1 reply; 6+ messages in thread
From: Henri Cloetens @ 2020-02-27  7:43 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-help

Hello Segher,

- Yes, DImode is a two register mode in my backend.
/static int hard_regno_nregs_internal(int regno, enum machine_mode mod)
{
...
//return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;//
}
/- In the example, file "use_manyregs.c.299r.sched2, line 95, I find:

;; *      11--> b  0: i  44 
{{%r31=%r31+0x18;%r0=[%r31+0x10];%r18=[%r31+0x8];clobber %r1;clobber 
%r19;};pc=return;}:LDST**
*
(This is the 'patched' version - I added the 'clobber' statements.)
In the same file, the RTL I emitted:

***(insn:TI 44 27 28 2 (parallel [
             (parallel [
                     (set (reg/f:SI 31 %r31)
                         (plus:SI (reg/f:SI 31 %r31)
                             (const_int 24 [0x18])))
                     (set (reg:DI 0 %r0)
                         (mem/c:DI (plus:SI (reg/f:SI 31 %r31)
                                 (const_int 16 [0x10])) [2  S8 A64]))
                     (set (reg:DI 18 %r18)
                         (mem/c:DI (plus:SI (reg/f:SI 31 %r31)
                                 (const_int 8 [0x8])) [2  S8 A64]))
                     (clobber:SI (reg:DI 1 %r1))
                     (clobber:SI (reg:DI 19 %r19))
                 ])
             (set (pc)
                 (return))

*Note that, the statement on line 95 does not contain the mode the 
register is used in.
The result of this, is that the scheduler cannot find the operation on 
R18 also clobbers R19.
In my opinion, this is wrong, as the function /hard_regno_nregs()/ is 
correctly defined.
Anyway, the addition of the "clobber" statements fix it.
On the (set (pc) (return)) and (return) statements, I think you are 
right. I mean,
the use of (return) leads to the double "parallel" statement in the RTL. 
(With (set (pc) (return))
there is only one "parallel", and then the tool misunderstands.)

Best Regards,

Henri.
*
*


On 02/26/2020 05:38 PM, Segher Boessenkool wrote:
> [ Top-post do please not. ]
>
> On Wed, Feb 26, 2020 at 04:11:06PM +0100, Henri Cloetens wrote:
>> - On the issue of the restore of R18 in mode DI, it seems from
>>    analysing the log file that the compiler does not understand this
>>    also affects R19. This looks a bug to me ??. Anyway, I have resolved
>>    this, by adding a 'clobber' statement to R19 when R18 is written
>>    in mode 'DI'.
> You haven't showed any evidence like this, so it's hard for use to help
> you with this at all.  *Is* DImode a two register mode in your backend?
>
>> - The other issue, I have changed ((set) (pc) (return)) to (return),
>>    but, as far as I understand the logfiles, and the documentation,
>>    both forms are equivalent. Anyway, after fixing the first issue, I do
>>    not see the second issue any more.
> The docs say
>    Note that an insn pattern of @code{(return)} is logically equivalent to
>    @code{(set (pc) (return))}, but the latter form is never used.
>
> If something is never used, then not everything might expect that form,
> that's all.
>
>
> Segher
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Question on gcc RTL and scheduling step.
  2020-02-27  7:43       ` Henri Cloetens
@ 2020-02-27  9:23         ` Segher Boessenkool
  0 siblings, 0 replies; 6+ messages in thread
From: Segher Boessenkool @ 2020-02-27  9:23 UTC (permalink / raw)
  To: Henri Cloetens; +Cc: gcc-help

Hi!

On Wed, Feb 26, 2020 at 06:03:18PM +0100, Henri Cloetens wrote:
> ;; *      11--> b  0: i  44 
> {{%r31=%r31+0x18;%r0=[%r31+0x10];%r18=[%r31+0x8];clobber %r1;clobber 
> %r19;};pc=return;}:LDST**

This is a "slim" RTL dump, it leaves out quite a lot of important info,
like modes.  That info actually *is* there in the insn, usually, it just
isn't printed here.

> ***(insn:TI 44 27 28 2 (parallel [
>             (parallel [
>                     (set (reg/f:SI 31 %r31)
>                         (plus:SI (reg/f:SI 31 %r31)
>                             (const_int 24 
> [0x18])))
>                     (set (reg:DI 0 %r0)
>                         (mem/c:DI (plus:SI (reg/f:SI 
> 31 %r31)
>                                 (const_int 
> 16 [0x10])) [2  S8 A64]))
>                     (set (reg:DI 18 %r18)
>                         (mem/c:DI (plus:SI (reg/f:SI 
> 31 %r31)
>                                 (const_int 8 
> [0x8])) [2  S8 A64]))
>                     (clobber:SI (reg:DI 1 %r1))
>                     (clobber:SI (reg:DI 19 %r19))
>                 ])
>             (set (pc)
>                 (return))

Yeah, parallel of parallel, there is your problem.  You probably have a
parallel in a define_insn, but you already have an implicit one there?
A problem in your .md file, anyway.


Segher

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-02-26 22:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-26 15:10 Question on gcc RTL and scheduling step Henri Cloetens
2020-02-26 16:39 ` Segher Boessenkool
2020-02-26 17:02   ` Henri Cloetens
2020-02-26 22:00     ` Segher Boessenkool
2020-02-27  7:43       ` Henri Cloetens
2020-02-27  9:23         ` Segher Boessenkool

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).