On 04/03/2011 12:43 AM, Frits van Bommel wrote:> On Sat, Apr 2, 2011 at 9:46 PM, Yiannis Tsiouris > <yiannis.tsiouris at gmail.com> wrote: > >> I am not sure i made myself clear about what i want. I was wondering >> if there >> is a way to communicate to LLVM's register allocator and define which >> registers are pre-coloured and should not be used for allocation. >> > Do you really need that, or would it be enough to be able to get the > value of the register at the start of a function and be able to set it > (or pass it along) when calling other functions? If so, the easiest > way really is to define a calling convention that uses it as e.g. the > first parameter register. Then you can just read the value from that > parameter, and have your compiler automatically pass it as that > parameter to other functions. > > If it ever changes you'll also need to add it as e.g. the first return > register so functions can return the current value in it (note that > functions can return multiple values by returning structs). To keep > things simple, it's probably best to treat it as a local variable in > your frontend: alloca at the start of the function, store to it at the > start of the function and after every call that returns the current > value for it, then load it whenever you need it. Optimization passes > will easily clean this up. > This is probably a good idea even if it doesn't change, simply because > it tells the code generator that the parameter register isn't changed. > Or at least, that the value in the register after the call is still > the value it needs to use. Otherwise, it would likely store it to the > stack before the first call and load it before every subsequent call. > > After optimization, the code generator would most likely prefer to > keep the value in the right register (since it starts there and later > needs to be there), but it might get moved elsewhere if there's a lot > of code between uses of the variable and the register is better used > for other things. This is usually a *good* thing, because it should be > better for performance. > As Sam said, the only place this might mess things up is when > interrupt functions (which aren't explicitly called, meaning LLVM > wouldn't know the register needs to contain the variable at that point > in the code) are involved. Well, and maybe debuggers I suppose, if the > register is hardcoded somewhere or you explicitly ask for the register > instead of the variable. > > > P.S. If it's important (or just convenient) for you to use a > unmodified LLVM, you might be able to get these changes into the > repository if you post a patch to the commits list. GHC had their own > special calling convention committed, for example. >First of all, i would like to thank you both for your quick answers! I am working on creating a backend for a language that already has a compiler. This compiler already maps some virtual registers of the VM, such as stack and heap pointers, to physical ones for performance and interoperability. If I understood well, there is no simple, predefined way to retain these conventions (custom pre-coloured registers) with LLVM compiler infrastructure. I would be surprised if I was the first one to have ever stumbled upon this problem! ~y.
On Sun, Apr 3, 2011 at 12:51 AM, Yiannis Tsiouris <yiannis.tsiouris at gmail.com> wrote:> On 04/03/2011 12:43 AM, Frits van Bommel wrote: >> P.S. If it's important (or just convenient) for you to use a >> unmodified LLVM, you might be able to get these changes into the >> repository if you post a patch to the commits list. GHC had their own >> special calling convention committed, for example. >> > I am working on creating a backend for a language that already has a > compiler. This compiler already maps some virtual registers of the VM, > such as stack and heap pointers, to physical ones for performance and > interoperability. If I understood well, there is no simple, predefined > way to retain these conventions (custom pre-coloured registers) with > LLVM compiler infrastructure. I would be surprised if I was the first > one to have ever stumbled upon this problem!No, like I said you're not the first one: GHC also had this problem (but on perhaps a slightly larger scale: they seemed to have multiple pinned registers). They fixed it by implementing a custom calling convention, and getting it committed in the LLVM repository.
Hi Yiannis, As has been said GHC had this problem (I'm the author of GHC's LLVM backend). GHC uses 4 pinned registers on x86-32 and 16 on x86-64. The solution is to use a custom calling convention. I would argue that this is a better solution then having the registers completely reserved as in the middle of a function llvm can spill those registers to free them up for temporary use. Also, if when generating code you know that one of the pinned registers doesn't actually store anything useful for this function then you can avoid passing it on to the next function so that the register will be free to use during the function. Here is a link to the original discussion about this problem and the solution: http://nondot.org/sabre/LLVMNotes/GlobalRegisterVariables.txt You should also check out the GHC calling convention as there is a good chance you could use it to get what you want and not have to modify llvm at all. The calling conventions for X86 are defined in 'lib/Target/X86/X86CallingConv.td' in a very easy to read format. On X86-64 the arguments are passed in R13, RBP, R12, RBX, R14, RSI, RDI, R8, R9, R15, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, in that order. So lets say the compiler you are trying to work with currently stores a Sp and a Hp in %R13 and %R12 respectively. You could define your functions like so: function cc 10 void f (Sp, tmp1, Hp) { [...] tail call g (Sp', undef, Hp'); ret void; } Cheers, David On 2 April 2011 15:51, Yiannis Tsiouris <yiannis.tsiouris at gmail.com> wrote:> On 04/03/2011 12:43 AM, Frits van Bommel wrote: >> On Sat, Apr 2, 2011 at 9:46 PM, Yiannis Tsiouris >> <yiannis.tsiouris at gmail.com> wrote: >> >>> I am not sure i made myself clear about what i want. I was wondering >>> if there >>> is a way to communicate to LLVM's register allocator and define which >>> registers are pre-coloured and should not be used for allocation. >>> >> Do you really need that, or would it be enough to be able to get the >> value of the register at the start of a function and be able to set it >> (or pass it along) when calling other functions? If so, the easiest >> way really is to define a calling convention that uses it as e.g. the >> first parameter register. Then you can just read the value from that >> parameter, and have your compiler automatically pass it as that >> parameter to other functions. >> >> If it ever changes you'll also need to add it as e.g. the first return >> register so functions can return the current value in it (note that >> functions can return multiple values by returning structs). To keep >> things simple, it's probably best to treat it as a local variable in >> your frontend: alloca at the start of the function, store to it at the >> start of the function and after every call that returns the current >> value for it, then load it whenever you need it. Optimization passes >> will easily clean this up. >> This is probably a good idea even if it doesn't change, simply because >> it tells the code generator that the parameter register isn't changed. >> Or at least, that the value in the register after the call is still >> the value it needs to use. Otherwise, it would likely store it to the >> stack before the first call and load it before every subsequent call. >> >> After optimization, the code generator would most likely prefer to >> keep the value in the right register (since it starts there and later >> needs to be there), but it might get moved elsewhere if there's a lot >> of code between uses of the variable and the register is better used >> for other things. This is usually a *good* thing, because it should be >> better for performance. >> As Sam said, the only place this might mess things up is when >> interrupt functions (which aren't explicitly called, meaning LLVM >> wouldn't know the register needs to contain the variable at that point >> in the code) are involved. Well, and maybe debuggers I suppose, if the >> register is hardcoded somewhere or you explicitly ask for the register >> instead of the variable. >> >> >> P.S. If it's important (or just convenient) for you to use a >> unmodified LLVM, you might be able to get these changes into the >> repository if you post a patch to the commits list. GHC had their own >> special calling convention committed, for example. >> > First of all, i would like to thank you both for your quick answers! > > I am working on creating a backend for a language that already has a > compiler. This compiler already maps some virtual registers of the VM, > such as stack and heap pointers, to physical ones for performance and > interoperability. If I understood well, there is no simple, predefined > way to retain these conventions (custom pre-coloured registers) with > LLVM compiler infrastructure. I would be surprised if I was the first > one to have ever stumbled upon this problem! > > ~y. > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
On 04/03/2011 02:58 AM, David Terei wrote:> Hi Yiannis, > > As has been said GHC had this problem (I'm the author of GHC's LLVM > backend). GHC uses 4 pinned registers on x86-32 and 16 on x86-64. The > solution is to use a custom calling convention. I would argue that > this is a better solution then having the registers completely > reserved as in the middle of a function llvm can spill those registers > to free them up for temporary use. Also, if when generating code you > know that one of the pinned registers doesn't actually store anything > useful for this function then you can avoid passing it on to the next > function so that the register will be free to use during the function. > > Here is a link to the original discussion about this problem and the solution: > > http://nondot.org/sabre/LLVMNotes/GlobalRegisterVariables.txt > > You should also check out the GHC calling convention as there is a > good chance you could use it to get what you want and not have to > modify llvm at all. The calling conventions for X86 are defined in > 'lib/Target/X86/X86CallingConv.td' in a very easy to read format. > > On X86-64 the arguments are passed in R13, RBP, R12, RBX, R14, RSI, > RDI, R8, R9, R15, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, in that order. > > So lets say the compiler you are trying to work with currently stores > a Sp and a Hp in %R13 and %R12 respectively. You could define your > functions like so: > > function cc 10 void f (Sp, tmp1, Hp) { > [...] > tail call g (Sp', undef, Hp'); > ret void; > } > > Cheers, > David >Hi, I 'll work further on what you and Frits van Bommel suggested. Using a custom calling convention seems like a reasonable approach after some minor research on how that could be done with LLVM. By the way, great work on your thesis, David! :-) Thank you for your suggestions, ~y.
On Sun, Apr 3, 2011 at 2:58 AM, David Terei <davidterei at gmail.com> wrote:> Hi Yiannis, > > As has been said GHC had this problem (I'm the author of GHC's LLVM > backend). GHC uses 4 pinned registers on x86-32 and 16 on x86-64. The > solution is to use a custom calling convention. I would argue that > this is a better solution then having the registers completely > reserved as in the middle of a function llvm can spill those registers > to free them up for temporary use. Also, if when generating code you > know that one of the pinned registers doesn't actually store anything > useful for this function then you can avoid passing it on to the next > function so that the register will be free to use during the function. > > Here is a link to the original discussion about this problem and the > solution: > > http://nondot.org/sabre/LLVMNotes/GlobalRegisterVariables.txt > > You should also check out the GHC calling convention as there is a > good chance you could use it to get what you want and not have to > modify llvm at all. The calling conventions for X86 are defined in > 'lib/Target/X86/X86CallingConv.td' in a very easy to read format. > > On X86-64 the arguments are passed in R13, RBP, R12, RBX, R14, RSI, > RDI, R8, R9, R15, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, in that order. > > So lets say the compiler you are trying to work with currently stores > a Sp and a Hp in %R13 and %R12 respectively. You could define your > functions like so: > > function cc 10 void f (Sp, tmp1, Hp) { > [...] > tail call g (Sp', undef, Hp'); > ret void; > } > > Cheers, > David > > Hey people,It has been some time since the last email on this topic. Since then i have successfully used your advice and implemented a custom calling convention for my backend that adheres to the runtime system's ABI. To summarize what i do: i have three virtual registers (HP, P, NSP) pinned to some physical registers by defining it in the custom calling convention. I have also defined a custom return cc in order to guarantee that the physical registers also have the correct values on exit of the function. In that way i am sure that the registers are updated both on entrance and exit and that is exactly what i want. The problem with that is the case of an 'invoke' call. According to the semantics of the invoke instruction the return value is not available when a stack unwind happens. From the Language Reference Manual: "For the purposes of the SSA form, the definition of the value returned by the 'invoke' instruction is deemed to occur on the edge from the current block to the "normal" label. If the callee unwinds then no return value is available." In that case, how can i get the values of the pinned registers, i.e. HP, P and NSP, needed in the Fail code block? Cheers, Yiannis -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110708/06edb62c/attachment.html>