On 28 March 2014 11:16, Chandler Carruth <chandlerc at google.com> wrote:> Just the reserved part.Ok, in that case, I share you concerns. We could easily only implement the reserved ones (stack pointer being the case in hand). If there is any mad reason why allocatable ones should be used (I heard glibc uses R8 for some special things, haven't confirmed myself), we can discuss this topic later.> I don't understand how taking registers out of the allocation set within the > innards of the target definition itself is really comparable to making some > functions register allocate with one set of registers and other functions > register allocate with a different set of registers. I don't think this > example really means anything.The way the ARM back-end does is to treat R9 as a special register from birth, like the frame pointer, and use it to calculate register pressure and to allow it to be allocated or not. I agree this is not the same as doing it with *any* register, but it shouldn't be particularly hard to add isReserved(Reg), add it to the Reserved list, and avoid it during allocation on a per-module (not function) granularity. We'd have to do that on all targets, yes, it won't be easy, but it should be doable and the register allocator already respects a restricted list of reserved registers dynamically. That's not to say that I'm willing to do it now. I agree we should start with the half-sane implementation of already reserved registers.> I don't understand this paragraph. It seems wrong.It probably is... ;)> - We have never (and still don't have) a representation for this in the IR. > But that's OK, the whole point has always been that such a representation > would be invented. > - I don't recall anyone caring about "language" versus intrinsics.So, from my defective memory, I remember people proposing to add a `register` keyword for global variables with some metadata to identify which register, and the loads and stores would have to behave differently (similar to volatile, but with a specific register attached). I don't remember when, or who, or where, it could have been on an LLVM dev meeting. That was not a good idea. Using intrinsics, we don't need to create the global variables at all, and all reads and writes can be mapped to intrinsics, making this change a lot simpler with zero changes to the IR except the creation of two new intrinsics.> - We have always had knowledge of the important part of inline asm: the > constraints and clobbers. Neither MC nor IAS is relevant here.What I meant here is that the MC layer allowed us to interpret inline assembly more thoroughly and add checks (that we do now for textual output as well, as you know). One of the uses of named registers is to pinpoint inline asm variables to specific registers (for instance to mark the stack pointer as clobbered during an MRC call), and in the past, we couldn't guarantee it because we didn't know what the inline asm had inside, as it was just opaque text. Now we can warn users if they're using it wrong, or if there's any danger of clobbering the wrong registers, because we have that knowledge in the MC layer. Makes sense?> - We don't have a generic register reservation mechanism today.Well, TargetRegisterInfo::getAllocatableSet() enquires the targets for getReservedRegs() which could be set to take into account named register globals. Since they're module globals, this could be done once per compilation job, making it a lot simpler.> If you don't believe the last part...I didn't say it would be simple... ;) And I agree with you that we should not do it "just because". There's where the technical reasons for not implementing it trump the reasons for having it as a feature.> And these seem like excellent reasons to not implement the dangerous feature > and instead to provide a significantly safer feature and direct users either > to not do the dangerous things, or if they are trying to do the safe thing, > use the feature which was designed for it.The point here is that __builting_stack_pointer doesn't provide enough additional value to be worth deviating from the norm. True, you can only use the stack pointers and not allocatable registers, and you don't have to name the register, so it's slightly more target-independent, but those were the only reasons. Named registers exist (and will exist) for ages, and people that use it know of the constraints and they're reportedly not an issue. We could add a warning if the user defines any allocatable register, saying that the register will not be reserved... cheers, --renato
On Fri, Mar 28, 2014 at 4:50 AM, Renato Golin <renato.golin at linaro.org>wrote:> On 28 March 2014 11:16, Chandler Carruth <chandlerc at google.com> wrote: > > Just the reserved part. > > Ok, in that case, I share you concerns. > > We could easily only implement the reserved ones (stack pointer being > the case in hand). If there is any mad reason why allocatable ones > should be used (I heard glibc uses R8 for some special things, haven't > confirmed myself), we can discuss this topic later.I'm a bit confused by this. The GCC documentation makes it pretty clear that *only* the allocatable registers are suitable for use as global register variables (and that things like the stack pointer make no sense here). From the doc: "Defining a global register variable in a certain register reserves that register entirely for this use, at least within the current compilation. The register is not allocated for any other purpose in the functions in the current compilation, and is not saved and restored by these functions. Stores into this register are never deleted even if they appear to be dead, but references may be deleted or moved or simplified." Obviously it's not possible to reserve the stack pointer register entirely for use as a global register variable, and any attempt to do so would be abusing the mechanism. Is there some other specification that you guys are working from, or are you basing this on observations of GCC's actual behavior? -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140402/dff77405/attachment.html>
On 2 April 2014 23:35, Richard Smith <richard at metafoo.co.uk> wrote:> I'm a bit confused by this. The GCC documentation makes it pretty clear that > *only* the allocatable registers are suitable for use as global register > variables (and that things like the stack pointer make no sense here). From > the doc:That document is terribly confusing...> Obviously it's not possible to reserve the stack pointer register entirely > for use as a global register variable, and any attempt to do so would be > abusing the mechanism.Absolutely! We just can't do it.> Is there some other specification that you guys are working from, or are you > basing this on observations of GCC's actual behavior?Observations and discussions in the GCC mailing list, unfortunately. Most of the GNU extensions are either badly documented or completely undocumented, and that's yet-another example of both! About the implementation, I'd like to make clear that the __builtin_stack_pointer can still exist as aliases to read_register/write_register. We can even create a special name in the IR "stack_pointer", so that each back end can do that and not force the front-end to know what's the stack pointer on each platform. In a way, I'm implementing both of them at the same time. So, we'll start with the non-allocatable ones because that's what the original idea (the builtin) implements, and because that's the problem we have right now. After this is in, maybe even with an additional builtin, we can think about the allocatable ones. cheers, --renato
Richard Smith <richard at metafoo.co.uk> writes:> On Fri, Mar 28, 2014 at 4:50 AM, Renato Golin <renato.golin at linaro.org>wrote: >> On 28 March 2014 11:16, Chandler Carruth <chandlerc at google.com> wrote: >> > Just the reserved part. >> >> Ok, in that case, I share you concerns. >> >> We could easily only implement the reserved ones (stack pointer being >> the case in hand). If there is any mad reason why allocatable ones >> should be used (I heard glibc uses R8 for some special things, haven't >> confirmed myself), we can discuss this topic later. > > > I'm a bit confused by this. The GCC documentation makes it pretty clear > that *only* the allocatable registers are suitable for use as global > register variables (and that things like the stack pointer make no sense > here). From the doc: > > "Defining a global register variable in a certain register reserves that > register entirely for this use, at least within the current compilation. > The register is not allocated for any other purpose in the functions in the > current compilation, and is not saved and restored by these functions. > Stores into this register are never deleted even if they appear to be dead, > but references may be deleted or moved or simplified." > > Obviously it's not possible to reserve the stack pointer register entirely > for use as a global register variable, and any attempt to do so would be > abusing the mechanism.It might not matter, but MIPS linux is one case where a non-allocatable register is used as a true global variable, rather than as a convienent way of getting the value of a fixed-purpose register. The register used there is $gp, which on bare-metal is usually reserved for small-data and (in theory) GOT accesses. Since linux knows it doesn't use either, it instead uses $gp to hold information about the current thread. I realise that's probably an unusual case though. Thanks, Richard