Hi all,
This is the first attempt at implementing named register globals in LLVM. There are a number of hacks that will need to be pruned and properly implemented and a number of questions that I have in the code about how to better achieve this. They're commented inline as FIXME.
The key design decisions:
- The LangRef change explains the semantics of the change. Basically:
- The register name is a private global string
- The value on write is a pointer type, to get the correct size from the target description
- The front end is responsible for casting it (ptrtoint/inttoptr) when needed
- I'm using an intrinsic for read/write from registers, so that way there will be no side effects from emitting them, nor will it allow taking the address of the register variable.
- I'm using a global string as the description, as it was the simplest IR I could come up with. I couldn't find a way to have literal strings ([3 x i8]* "sp\0") or how to embed metadata as a node. The problem with this is that the constant is still being emitted in the final file.
- If the constant is fine, I need to remove it from the DAG at the right moment. On getRegisterStringValue() is a bit too soon, as it breaks the DAG shortly after. I'll check when it's safe to call the clean up routines.
- If metadata is better, to avoid dangling data sections, how do I embed it in the intrinsic call?
- SelectionDAG -> Lower Intrinsic will lower the intrinsic call into either READ_REGISTER or WRITE_REGISTER nodes. The former is a simple replacement, the latter needs to become a DAG root and long the chain from the value's chain.
- I'm not sure that's the best way to catch the chain from the value, which could be anything, not just a copy from virtual register.
- TargetLowering simply converts READ -> CopyFromReg and WRITE -> CopyToReg(Value)
- getRegisterStringValue encodes the knowledge of reading the literal string from the global/metadata
- getRegisterByName encodes the logic of which registers are valid. This could be a TableGen property and auto-generated
- On all targets, lowering READ/WRITE nodes and getting the string literal are identical. Is there a place I can common them up?
Welcoming any comment. Thanks!
I'd make it polymorphic. I suspect quite a few targets have pointer types that are inadequate to represent all registers (for various reasons).