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

Reply via email to