+1
-Hal
>
> >> This is not exactly the semantics gcc uses since the register
> >> would
> >> still be allocatable, but should cover 99% of the uses, including
> >> reading the stack pointer in the kernel.
> >
> > http://gcc.gnu.org/onlinedocs/gcc/Global-Reg-Vars.html
> >
> > It seems that the semantics is to avoid PCS registers, or they will
> > be
> > clobbered...
>
> Yes, it is really odd. It says "Global register variables reserve
> registers throughout the program.", which is obviously not the case
> since not all compile units might see it.
>
> >
> >> For example, is it legal to move the read of rsp out of a
> >> loop?
> >
> > No. It should be a volatile read/write.
>
> Agreed. With the intrinsic the semantics are easy to represent.
>
> Cheers,
> Rafael
> _______________________________________________
> cfe-dev mailing list
> cfe...@cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
--
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory
_______________________________________________
On 27 Mar 2014 16:30, "Rafael Espíndola" <rafael.e...@gmail.com> wrote:
>
> > That's my idea, yes. I'm not sure how Clang would transform the named
> > registers into the intrinsic, but something along the lines of:
> >
> > i8* @SP = "SP";
> >
> > define void @step() nounwind {
> > entry:
> > %0 = call i32 @llvm.read_register(i8* @SP)
> > %1 = add i32 %0, i32 4
> > call void @llvm.write_register(i8* @SP, %1)
> > }
> >
> > declare void @llvm.write_register(i8*, i32) nounwind readnone
> > declare i32 @llvm.read_register(i8*) nounwind readnone
>
> I would not produce any llvm global for it. So some insanity like
>
> register long a asm("rsp");
> long f(long x) {
> long ret = a;
> a = x;
> return ret;
> }
>
> would compile to
>
> define i64 @f(i64 %x) {
> %ret = call i64 @llvm.read_register("rsp");
> call void @llvm.write_register("rsp", i64 %x)
> ret %ret
> }
> declare void @llvm.write_register(i8*, i64)
> declare i64 @llvm.read_register(i8*)
That was actually my first idea, but I got confused on the implementation. :-)
I'll try it again.
Cheers,
Renato
> That's my idea, yes. I'm not sure how Clang would transform the namedI would not produce any llvm global for it. So some insanity like
> registers into the intrinsic, but something along the lines of:
>
> i8* @SP = "SP";
>
> define void @step() nounwind {
> entry:
> %0 = call i32 @llvm.read_register(i8* @SP)
> %1 = add i32 %0, i32 4
> call void @llvm.write_register(i8* @SP, %1)
> }
>
> declare void @llvm.write_register(i8*, i32) nounwind readnone
> declare i32 @llvm.read_register(i8*) nounwind readnone
register long a asm("rsp");
long f(long x) {
long ret = a;
a = x;
return ret;
}
would compile to
define i64 @f(i64 %x) {
%ret = call i64 @llvm.read_register("rsp");
call void @llvm.write_register("rsp", i64 %x)
ret %ret
}
declare void @llvm.write_register(i8*, i64)
declare i64 @llvm.read_register(i8*)
On 28 March 2014 02:06, Rafael Espíndola <rafael.e...@gmail.com> wrote:AFAIK, GCC reserves the allocatable registers. If we're going to do
> Correct. The proposed solution would work for all non allocatable
> registers. We should probably still err if someone tries to use an
> allocatable one.
this we'd have to be as close as possible to the current behaviour to
avoid surprises.
On 28 March 2014 10:17, Chandler Carruth <chan...@google.com> wrote:Do you mean only the reserved part or the general named register idea?
> This has been the long standing historical objection to the feature. It is a
> *really* invasive change to the register allocator to plumb this kind of
> register reservation through it.
About reserving registers, we already have the ability to reserve
certain registers (R9 on ARM, for instance), so it should not be too
hard to reserve arbitrary registers.
As far as I could find looking backwards, there were many more
impediments back then. The inability to represent this in IR
correctly, the idea that it should be part of the language (not an
intrinsic) thus breaking optimisation rules, the lack of inline asm
knowledge in the back-end (fixed by MC and IAS), and the lack of
register reservation mechanisms (which we have today).
> Worse, the semantics for it beingI don't know LTO well enough to answer that, maybe Rafael can chime in.
> inherently translation-unit based become deeply confusing in LLVM due to the
> potential for (partial) LTO.
But ultimately, this particular feature is draconian in itself, and
the GCC docs describe lots of cases where it's not safe to use it.
This, and the clear_cache builtins, are particularly dangerous but
necessary extensions to implementing low level bare-metal code while
keeping the code in a manageable level (C-land).
On 28 March 2014 11:16, Chandler Carruth <chan...@google.com> wrote:
> Just the reserved part.
Ok, in that case, I share you concerns.
We could easily only implement the reserved ones (stack pointer being
the case in hand). If there is any mad reason why allocatable ones
should be used (I heard glibc uses R8 for some special things, haven't
confirmed myself), we can discuss this topic later.