This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: rs6000 stack_tie mishap again
- From: Olivier Hainque <hainque at adacore dot com>
- To: Jeff Law <law at redhat dot com>
- Cc: Andreas Krebbel <krebbel at linux dot vnet dot ibm dot com>, Alan Modra <amodra at gmail dot com>, GCC Patches <gcc-patches at gcc dot gnu dot org>, Richard Henderson <rth at redhat dot com>, Segher Boessenkool <segher at kernel dot crashing dot org>, uweigand at de dot ibm dot com
- Date: Thu, 14 Apr 2016 19:10:33 +0200
- Subject: Re: rs6000 stack_tie mishap again
- Authentication-results: sourceware.org; auth=none
- References: <DC6B501A-B999-41EC-B3D9-2D04E0A472CD at adacore dot com> <20160324041034 dot GB31470 at bubble dot grove dot modra dot org> <56F96CE2 dot 9020001 at redhat dot com> <888A9BC7-458D-46DE-BEC1-8AC000C6849D at adacore dot com> <570FBB7C dot 7060802 at linux dot vnet dot ibm dot com> <570FCA3B dot 2070001 at redhat dot com>
> On 14 Apr 2016, at 18:50, Jeff Law <law@redhat.com> wrote:
>
> I thought we had code to handle this case specially, but I can't immediately find it in sched-deps.c.
Unless I misunderstood what you were exactly looking for,
the special code is in alias.c. E.g. write_dependence_p:
/* (mem:BLK (scratch)) is a special mechanism to conflict with everything.
This is used in epilogue deallocation functions. */
...
> Some ports also use an unspec_volatile to achieve the same effect:
>
> ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
> ;; all of memory. This blocks insns from being moved across this point.
>
> (define_insn "blockage"
> [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
> ""
> ""
> [(set_attr "length" "0")])
Yes, I pondered this one and thought that a memory barrier
would be less aggressive, while good enough.
> ;; Do not schedule instructions accessing memory across this point.
>
> (define_expand "memory_blockage"
> [(set (match_dup 0)
> (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
> ""
> {
> operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
> MEM_VOLATILE_P (operands[0]) = 1;
> })
>
> (define_insn "*memory_blockage"
> [(set (match_operand:BLK 0)
> (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
> ""
> ""
> [(set_attr "length" "0")])
Emitting just that alone isn't enough though. The first attempt
I made did that and failed because the whole
reg-restore
reg-restore
tie (mem blockage only)
sequence was allowed to move past the stack pointer reset when
it's performed as a mere register to register move.
So I ended up adding the clobber mem:blk scratch to the existing
tie parallel, which references the stack pointer register as
well so is forbidden to move past it's update.
Olivier