On Thu, Feb 27, 2014 at 4:02 PM, Eric Botcazou <ebotca...@adacore.com> wrote:
>> After some investigation, we discovered that this behavior is caused by
>> big hammer in gcc/cse.c:
>>     /* A volatile ASM or an UNSPEC_VOLATILE invalidates everything.  */
>>     if (NONJUMP_INSN_P (insn)
>>         && volatile_insn_p (PATTERN (insn)))
>>       flush_hash_table ();
>> This code (introduced in
>> http://gcc.gnu.org/viewcvs/gcc?view=revision&revision=193802) aborts CSE
>> after seeing a volatile inline asm.
>
> Note that "introduced" is not really correct here, the code had been there for
> a long time but it was treating some volatile asms as barriers and some others
> as not.  Now it treats them all as barriers.
>
>> Is this compiler behavior reasonable? AFAIK GCC documentation only says
>> that __volatile__ prevents compiler from removing the asm but it does
>> not mention that it supresses optimization of all surrounding expressions.
>
> This is not crystal clear, but the conservative interpretation is that you can
> use volatile asms to do really nasty things behind the back of the compiler:
>
> /* Nonzero if X contains any volatile instructions.  These are instructions
>    which may cause unpredictable machine state instructions, and thus no
>    instructions or register uses should be moved or combined across them.
>    This includes only volatile asms and UNSPEC_VOLATILE instructions.  */
>
> int
> volatile_insn_p (const_rtx x)
>
>> If this behavior is not intended, what would be the best way to fix
>> performance? I could teach GCC to not remove constant RTXs in
>> flush_hash_table() but this is probably very naive and won't cover some
>> corner-cases.
>
> That could be a good starting point though.

Though with modifying "machine state" you can modify constants as well, no?

Richard.

> --
> Eric Botcazou

Reply via email to