[LLVMdev] Named Register Implementation

Tom Stellard tom at stellard.net
Fri Mar 28 08:25:21 PDT 2014


On Fri, Mar 28, 2014 at 03:00:41PM +0000, Renato Golin wrote:
> Folks,
> 
> So, I think we kind of agree that some named registers could be
> implemented, and that it should be an intrinsic that passes the name
> of the register down.
> 
> This C code:
> 
> register unsigned long current_stack_pointer asm("sp");
> unsigned long get_stack_pointer_addr() {
>   return current_stack_pointer;
> }
> void set_stack_pointer_addr(unsigned long addr) {
>   current_stack_pointer = addr;
> }
> 
> Would become something like:
> 
> define i32 @get_stack_pointer_addr() nounwind {
> entry:
>   %0 = call i32 @llvm.read_register("sp")
>   ret i32 %0
> }
> 
> define void @set_stack_pointer_addr(i32 %addr) nounwind {
> entry:
>   call void @llvm.write_register("sp", %addr)
>   ret void
> }
> 
> Note particularly:
>  - There are no globals defined. Since you can't take the address of
> that variable, you can only read and write directly to it, it should
> be safe to translate all reads and writes to intrinsics without any
> reference to a global variable.
>  - I'm letting the name to be an argument (as opposed to metadata) for
> simplicity. It might be better to use metadata or some other way.
> 
> Is that a reasonable expectation of the implementation?
> 
> Now, onto specifics...
> 
> 1. RegisterByName
> 
> I couldn't find a way to get a register by name. I could teach the
> TableGen backend to print an additional table with a StringSwitch on
> <Target>GenRegisterInfo.inc and add a method getRegisterByName(char
> *), but that would expose a huge number of unwanted register classes
> which could open a huge can of worms.
> 
> My idea was to be very specific and let the implementation local as
> <Target>RegisterInfo::getNamedRegister(char *) which will be *just*
> for named registers and will only map a few cases,
> erring/warning/asserting otherwise.
> 
> With this, we can control what kind of register we do accept, and only
> expand the list when we actually implement support for them.
> Currently, the only registers we will support are the non-allocatable
> ones, mainly stack and program counters.
> 
> Since this is target specific, we could make the default behaviour to
> be emitting "Register not available for named register globals" error.
> 
> Is there a better way of doing this?
> 
> 
> 2. Name in SDNode
> 
> If I leave the name as a string literal ("sp"), would that become an
> i8* SDNode? I'm a big rusty on SDNodes, but if I get a
> Node->getValue() on an i8*, I'll get the address of it. How do I get
> the value as a string?
>

Couldn't you avoid using a string literal in the SDNode, by having the
SelectionDAGBuilder look up the register id with the function you
proposed above and then add that id as the operand to the intrinsic's
SDNode?

-Tom
 
> If I would use metadata, how do I pass it to the intrinsic?
> 
> @llvm.read_register(!0)
> !0 = metadata !{metadata !"sp"}
> 
> Is this valid IR?
> 
> cheers,
> --renato
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev



More information about the llvm-dev mailing list