----- Original Message ----- > From: "Richard Henderson" <r...@twiddle.net> > To: "Peter Zijlstra" <pet...@infradead.org>, "Mathieu Desnoyers" > <mathieu.desnoy...@efficios.com> > Cc: "Will Deacon" <will.dea...@arm.com>, linux-ker...@vger.kernel.org, > "Catalin Marinas" <catalin.mari...@arm.com>, > lttng-...@lists.lttng.org, "Nathan Lynch" <nathan_ly...@mentor.com>, "Paul E. > McKenney" > <paul...@linux.vnet.ibm.com>, "Linus Torvalds" > <torva...@linux-foundation.org>, "Andrew Morton" > <a...@linux-foundation.org>, "Jakub Jelinek" <ja...@redhat.com>, > gcc@gcc.gnu.org > Sent: Tuesday, November 19, 2013 4:56:57 PM > Subject: Multiple local register variables w/ same register > > On 11/20/2013 03:33 AM, Peter Zijlstra wrote: > > On Tue, Nov 19, 2013 at 05:02:20PM +0000, Mathieu Desnoyers wrote: > >> Unfortunately I don't have a ARM cross-compiler setup ready. Nathan could > >> test > >> it for us though. > >> > >> It might shuffle things around enough to work around the issue, but with > >> the > >> approach you propose, I would be concerned about the compiler being within > >> its rights to reorder the code into the following sequence: > >> > >> struct thread_info *ptra, *ptrb; > >> > >> ptra = current_thread_info(); > >> /* > >> * each current_thread_info() would have a clobber on *sp, which orders > >> * those two wrt each other. > >> */ > >> ptrb = current_thread_info(); > >> > >> load from ptra->preempt_count; > >> /* > >> * however, the following accesses that depend on ptra and ptrb could be > >> * reordered if the compiler has no way to know that ptra and ptrb are > >> * aliased. > >> */ > >> store to ptrb->preempt_count; > >> > >> One question that might be worth asking: with the local register variable > >> extension > >> (http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Local-Reg-Vars.html#Local-Reg-Vars) > >> (thanks to Jakub for the pointer), should the compiler consider two > >> variables > >> bound to the same register as being aliased or not ? AFAIU, local reg vars > >> appear > >> to be architecture-specific, so maybe there is something fishy on ARM ? > > It appears not: > > int __attribute__((noinline)) f(void) > { > { > register int x __asm__("eax"); > x = 1; > } > { > register int y __asm__("eax"); > return ++y; > } > } > > extern void abort(void); > > int main(void) > { > if (f() != 2) > abort(); > return 0; > } > > Anyone see anything wrong with the testcase?
This testcase is targeting a general purpose register, whereas the issue I'm presenting gets the stack pointer as base address for many memory operations targeting the same offset from this base address. So strictly speaking, I think the two cases are slightly different. Thanks, Mathieu > Do we thing this sort of thing > ought to work, perhaps with scopes lengthened? > > > r~ > -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com