On 04/02/2011 06:26 PM, Samuel Crow wrote:> Hello Yiannis, > > You could write a custom backend that doesn't allocate %r15 for general usage. > The normal way to do this is to set up a custom calling convention for all > functions that keeps a sentinel in %r15 so that it always holds the sentinel. > This is how new operating systems are supported with custom ABIs. The only > problem is that you cannot be assured that %r15 stays put between function calls > such as for an interrupt. > > If you had asked "Is there another EASY way to force explicit register usage?" > the answer would have been "No." > > > --Sam Crow > > > ----- Original Message ---- > >> From: Yiannis Tsiouris <yiannis.tsiouris at gmail.com> >> To: llvmdev at cs.uiuc.edu >> Cc: Chris Stavrakakis <hydralisk.r at gmail.com> >> Sent: Sat, April 2, 2011 9:39:13 AM >> Subject: [LLVMdev] Explicit register usage in LLVM assembly >> >> Hello! >> Is there a way to force explicit register usage (e.g. %r15 in amd64 >> architecture) in >> LLVM assembly code? I was proposed in #llvm channel at irc.oftc.net to >> use inline >> assembly but i find it rather impractical in my case. Is there any other >> way? >> >> Thanx, >> ~y. >>Hello Sam, 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. ~y.
Hello Yiannis, The answer to your question is "no" or at least "not without getting your hands really, really dirty". The intermediate representation of code is entirely processor agnostic or tries to be. Specifying something specific to just one processor is made impossible on purpose to prevent people from making system-specific code that would only work on one LLVM Backend. If you want your AMD64 processor to generate different code, you'll have to modify the AMD64 backend of LLVM and give %r15 a different register classification. Doing this will probably require some proficiency with TableGen (which I'm not so familiar with yet) and require that changes be made to all of the other processor specifications as well that you plan on using with your compiler. This would probably require a fork of the LLVM project altogether and should not be considered lightly. The reason I brought up about ABIs of operating systems earlier is that that is the only time LLVM knows or even cares what register goes to what. It is defined by the calling conventions of function calls. I'm certain that the subject of "pegging" a register to a variable in a compiler came up before in a previous discussion but the closest my Google searches revealed was this one: http://lists.cs.uiuc.edu/pipermail/llvmdev/2007-November/011536.html This begs the questions: Are you trying to make a compiler only for AMD64? What operating systems do you plan on supporting with your compiler? Do you know that LLVM is deliberately maintained as a cross-platform framework for many operating systems and processors? What exactly are you trying to do that requires such system-specific knowledge other than support a specific operating system? Maybe somebody else who is on the team can give a more specific answer than what I gave. I hope this helps, --Sam ----- Original Message ----> From: Yiannis Tsiouris <yiannis.tsiouris at gmail.com> > To: Samuel Crow <samuraileumas at yahoo.com> > Cc: llvmdev at cs.uiuc.edu; Chris Stavrakakis <hydralisk.r at gmail.com> > Sent: Sat, April 2, 2011 2:46:15 PM > Subject: Re: [LLVMdev] Explicit register usage in LLVM assembly >> Hello Sam, > 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. > > > ~y. > > On 04/02/2011 06:26 PM, Samuel Crow wrote: > > Hello Yiannis, > > > > You could write a custom backend that doesn't allocate %r15 for general >usage. > > > The normal way to do this is to set up a custom calling convention for all> > functions that keeps a sentinel in %r15 so that it always holds the >sentinel. > > > This is how new operating systems are supported with custom ABIs. The only > > > problem is that you cannot be assured that %r15 stays put between function >calls > > > such as for an interrupt. > > > > If you had asked "Is there another EASY way to force explicit register >usage?" > > > the answer would have been "No." > > > > > > --Sam Crow > > > > > > ----- Original Message ---- > > > >> From: Yiannis Tsiouris <yiannis.tsiouris at gmail.com> > >> To: llvmdev at cs.uiuc.edu > >> Cc: Chris Stavrakakis <hydralisk.r at gmail.com> > >> Sent: Sat, April 2, 2011 9:39:13 AM > >> Subject: [LLVMdev] Explicit register usage in LLVM assembly > >> > >> Hello! > >> Is there a way to force explicit register usage (e.g. %r15 in amd64> >> architecture) in > >> LLVM assembly code? I was proposed in #llvm channel at irc.oftc.net to > >> use inline > >> assembly but i find it rather impractical in my case. Is there any other > >> way? > >> > >> Thanx, > >> ~y. > >>
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.
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.