[cfe-commits] r122643 - in /cfe/trunk: lib/CodeGen/CGDecl.cpp lib/CodeGen/CGStmt.cpp test/CodeGen/asm-variable.c

Chris Lattner clattner at apple.com
Fri Dec 31 19:05:12 PST 2010

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 {
  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:

> 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! :)


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20101231/b889d937/attachment.html>

More information about the cfe-commits mailing list