On Tue, Aug 2, 2011 at 2:53 PM, Hans-Peter Nilsson <h...@bitrange.com> wrote: > On Tue, 2 Aug 2011, Richard Guenther wrote: >> On Tue, Aug 2, 2011 at 2:06 PM, Mikael Pettersson <mi...@it.uu.se> wrote: >> > Michael Walle writes: >> > > >> > > Hi, >> > > >> > > > To confirm that try -fno-tree-ter. >> > > >> > > "lm32-gcc -O1 -fno-tree-ter -S -c test.c" generates the following >> > working >> > > assembly code: >> > > >> > > f2: >> > > addi sp, sp, -4 >> > > sw (sp+4), ra >> > > addi r2, r0, 10 >> > > calli __ashrsi3 >> > > addi r8, r0, 10 >> > > scall >> > > lw ra, (sp+4) >> > > addi sp, sp, 4 >> > > b ra >> > >> > -fno-tree-ter also unbreaks the ARM test case in PR48863 comment #4. >> >> It's of course only a workaround, not a real fix as nothing prevents >> other optimizers from performing the re-scheduling TER does. >> >> I suggest to amend the documentation for local call-clobbered register >> variables to say that the only valid sequence using them is from a >> non-inlinable function that contains only direct initializations of the >> register variables from constants or parameters. > > I'd be ok with that, FWIW; I see the problem with keeping the > scheduling of operations in a working order (yuck) and I don't > see how else to keep it working ...except perhaps make gcc flag > functions with register asms as non-inlinable, maybe even flag > down any of the dangerous re-scheduling?
But then can't people use a pure assembler stub instead? Without inlining there isn't much benefit left from writing void f1(int arg) { register int a1 asm("r8") = 10; register int a2 asm("r1") = arg; asm("scall" : : "r"(a1), "r"(a2)); } instead of f1: mov r8, 10 mov r1, rX scall ret in a .s file no? I doubt much prologue/epilogue is needed. Or even write void f1(int arg) { asm("mov r8, %0; mov r1 %1; scall;" : : "g"(a1), "g"(a2) : "r8", "r1"); } which should be inlinable again (yes, in inlined for not optimally register-allocated, but compared to the non-inline routine?). Richard. > Maybe I can do that with some hand-holding? > >> Or go one step further and deprecate local register variables alltogether >> (they IMHO don't make much sense, and rather the targets should provide >> a way to properly constrain asm inputs and outputs). > > They do make sense when implementing e.g. system calls, and > they're documented to work as discussed. (I almost regret > making that happen, though.) Fortunately such functions are > small, and not relatively much helped by inlining (it's a > *syscall*; much more happening beyond the call than is affected > by inlining some parameter initialization). Sure, new targets > are much better off by implementing that through other means, > but preferably intrinsic functions to asms. > > brgds, H-P