[LLVMdev] Named Register Implementation

Renato Golin renato.golin at linaro.org
Fri Mar 28 08:00:41 PDT 2014


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?

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



More information about the llvm-dev mailing list