Asm volatile causing performance regressions on ARM

Eric Botcazou ebotcazou@adacore.com
Thu Feb 27 15:03:00 GMT 2014


> 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.

-- 
Eric Botcazou



More information about the Gcc mailing list