On Dec 31, 2010, at 12:43 PM, Jakob Stoklund Olesen wrote:
>
> On Dec 31, 2010, at 11:34 AM, Benjamin Kramer wrote:
>> To sum this up, should we consider using local register vars outside of asm
>> statements
>> unsafe and just ignore them (as we do now)? While GCC supports them to some
>> extent I don't
>> think it's worth to support it just to enable some premature optimizations.
>> We don't even
>> need a warning in that case.
>
> There are three cases:
>
> 1. Pinned local variables are treated no differently than normal local
> variables except when they are used as operands for inline asm. This is what
> Rafael's patch implements. I suppose you could warn if such a variable is
> never used for inline asm.
Yes, this sounds right. The warning should be something like "warning:
register assignment ignored" to give people a head's up that they have useless
code.
Right, llvm-gcc implements this, but not the warning. This is useful and
documented by the GCC manual.
> 2. Global variables pinned to a reserved register. This is just an odd way of
> accessing a register, and it is fairly easy to support in the front end by
> emitting empty inline asm instead of reads and writes to the global.
Right, llvm-gcc does this. This is vaguely bogus but it is (obviously) used
and useful to support.
> 3. Global variables pinned to an allocatable register. For this to work, the
> backend must treat the pinned register as reserved, effectively changing the
> calling convention of all functions in the compilation unit. Other
> compilation units would have to be built with -ffixed-reg. I really don't
> want to support this if it can at all be avoided.
>
> It is very hard for the frontend to distinguish between 2. and 3., it would
> have to know if a register is reserved. Even the backend has a hard time
> telling when %ebp (the frame pointer) is reserved.
>
> I think we should consider not supporting pinned global variables, and
> instead provide a way of reading and writing specific registers with inline
> asm constraints.
>
> Instead of:
>
> register unsigned long current_stack_pointer asm("esp");
> foo = current_stack_pointer;
>
Interestingly enough, GCC emits a warning:
$ cat t.c
register int foo asm("rax");
void f() {
foo = 42;
}
t.c:1: warning: call-clobbered register used for global register variable
llvm-gcc doesn't produce the warning, and it compiles this into:
target datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-apple-darwin10.5"
define void @f() nounwind ssp noredzone {
entry:
tail call void asm sideeffect "", "{rax}"(i32 42) nounwind
ret void
}
My opinion is that the warning is a (really low priority) QoI issue and that we
should implement #2 and forget about people who get burned with #3.
We should not implement -ffixed-reg if possible IMO, though it has been
discussed on llvmdev as useful for people who have GC'd languages etc, and I
vaguely recall the Haskell folks doing some work in this area. To do this
right we'd have to do something like this:
http://nondot.org/sabre/LLVMNotes/GlobalRegisterVariables.txt
> We could permit:
> asm ("" : "={esp}"(foo));
> The curly brace syntax for inline asm constraints also obsoletes pinned local
> variables.
Lets not extend GCC assembly syntax anymore! :)
-Chris
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits