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