Philip Reames via llvm-dev
2021-Sep-02 00:48 UTC
[llvm-dev] [RFC] Introduce new call-site attribute
The basic problem you're solving makes sense to me, and I agree we need a good solution. I'm not quite sure that your propose is the right starting point though. The notion of having different ways to encode targets with different offsets shows up in a bunch of different ways, not just calls, and in particular, not just the pcRel32 flavor you mention here. A few other examples: * For an address which whose relative offset is unknown, but whose absolute address is known, you can use a 32bit move to materialize the address in a register. * For relative calls, x86 supports a 16 bit relative version as well. Though, I'm not sure this is profitable on modern hardware. * With tail calls, you get all the jump variants (8b relative, 16b relative, 32b relative, 32b register, 64b register). * For data accesses, we have many of the same options. I think it's reasonable to (mostly) start with calls, and ignore the data access side of things. All of these tightly interlock with the relocations available from the dynamic loader. I'd previously played with specifying bounds on the absolute addresses of functions. (We have some bit of support for that, though I can't find it in LangRef currently.) This quickly tripped into implementation complexity problems, but I didn't see any fundamental reason why e.g. having both callee and caller functions specified to be within a 1.x GB region wouldn't allow us to use 32 bit relative calls. I think we need to phrase this as a set of restrictions on both the absolute and relative offset of a callee, and then leave it up to backend to select the optimal lowering. The codemodel in this world becomes simply the default set of restrictions for an otherwise unspecified target address. All of the above is a really involved way of saving that I think you need to change your spelling on the attribute a bit. I think we need to be able to support fairly arbitrary restrictions on the relative range, and then leave it up to the code generator which option it actually picks. As a strawman, how about the following syntax: call void @foo() target-address-relative-bound(-2147483648, 2147483647) OR declare void @foo() address-absolute-bound(X, X + 100MB) Philip p.s. I'm not a linker or loader person, I know just enough about them to be very dangerous. If anyone who is actually familiar with relocation types wants to tell me something is horrible wrong with my proposed model, please feel free. :) On 9/1/21 6:31 AM, Evgueni Brevnov via llvm-dev wrote:> Hi Everyone, > > Introduction: > On Intel x86_64 architecture you can make a call using either relative > 32 bits offset or absolute address. Currently LLVM uses a notion of > "code model" that defines which version will be generated. In other > words, for small and medium code models 32 bits relative calls are > generated, for large code model calls via an absolute address are > generated. The thing is that a single lowering scheme is used for the > entire compilation unit and there is no way to specialize for a > particular call. In managed environments (JIT compilers) we have > control where specific functions are loaded in memory and can > guarantee that particular call site is within 32-bits offset. We would > like to use relative calls for such functions while the global code > model is set to 'large'. > > Proposal: > Introduce 'fits-32bits' call site attribute. For calls marked with the > attribute compiler may assume the target address is within 32-bits > offset from the end of the generated call. Program semantics is not > changed if it is ignored by the compiler.The attribute overrides the > current code model for the specific call site. > > Thanks > Evgeniy > > > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210901/2dcef83a/attachment.html>
Philip Reames via llvm-dev
2021-Sep-02 01:14 UTC
[llvm-dev] [RFC] Introduce new call-site attribute
On 9/1/21 5:48 PM, Philip Reames wrote:> > The basic problem you're solving makes sense to me, and I agree we > need a good solution. I'm not quite sure that your propose is the > right starting point though. > > The notion of having different ways to encode targets with different > offsets shows up in a bunch of different ways, not just calls, and in > particular, not just the pcRel32 flavor you mention here. A few other > examples: > > * For an address which whose relative offset is unknown, but whose > absolute address is known, you can use a 32bit move to materialize > the address in a register. > * For relative calls, x86 supports a 16 bit relative version as > well. Though, I'm not sure this is profitable on modern hardware. > * With tail calls, you get all the jump variants (8b relative, 16b > relative, 32b relative, 32b register, 64b register). > * For data accesses, we have many of the same options. I think it's > reasonable to (mostly) start with calls, and ignore the data > access side of things. > > All of these tightly interlock with the relocations available from the > dynamic loader. > > I'd previously played with specifying bounds on the absolute addresses > of functions. (We have some bit of support for that, though I can't > find it in LangRef currently.) This quickly tripped into > implementation complexity problems, but I didn't see any fundamental > reason why e.g. having both callee and caller functions specified to > be within a 1.x GB region wouldn't allow us to use 32 bit relative calls. >The syntax I couldn't find was absolute_symbol <https://llvm.org/docs/LangRef.html#absolute-symbol-metadata>. There does appear to be some precedent using that mechanism, but I don't see that it's been applied to calls. I vaguely remember I stopped working on this when a rough prototype failed to show profitability.> I think we need to phrase this as a set of restrictions on both the > absolute and relative offset of a callee, and then leave it up to > backend to select the optimal lowering. The codemodel in this world > becomes simply the default set of restrictions for an otherwise > unspecified target address. > > All of the above is a really involved way of saving that I think you > need to change your spelling on the attribute a bit. I think we need > to be able to support fairly arbitrary restrictions on the relative > range, and then leave it up to the code generator which option it > actually picks. As a strawman, how about the following syntax: > > call void @foo() target-address-relative-bound(-2147483648, 2147483647) > > OR > > declare void @foo() address-absolute-bound(X, X + 100MB) > > Philip > > p.s. I'm not a linker or loader person, I know just enough about them > to be very dangerous. If anyone who is actually familiar with > relocation types wants to tell me something is horrible wrong with my > proposed model, please feel free. :) > > On 9/1/21 6:31 AM, Evgueni Brevnov via llvm-dev wrote: >> Hi Everyone, >> >> Introduction: >> On Intel x86_64 architecture you can make a call using either >> relative 32 bits offset or absolute address. Currently LLVM uses a >> notion of "code model" that defines which version will be generated. >> In other words, for small and medium code models 32 bits relative >> calls are generated, for large code model calls via an absolute >> address are generated. The thing is that a single lowering scheme is >> used for the entire compilation unit and there is no way to >> specialize for a particular call. In managed environments (JIT >> compilers) we have control where specific functions are loaded in >> memory and can guarantee that particular call site is within 32-bits >> offset. We would like to use relative calls for such functions while >> the global code model is set to 'large'. >> >> Proposal: >> Introduce 'fits-32bits' call site attribute. For calls marked with >> the attribute compiler may assume the target address is within >> 32-bits offset from the end of the generated call. Program semantics >> is not changed if it is ignored by the compiler.The attribute >> overrides the current code model for the specific call site. >> >> Thanks >> Evgeniy >> >> >> >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210901/ff4c0a06/attachment.html>
Reid Kleckner via llvm-dev
2021-Sep-02 18:44 UTC
[llvm-dev] [RFC] Introduce new call-site attribute
On Wed, Sep 1, 2021 at 5:49 PM Philip Reames via llvm-dev < llvm-dev at lists.llvm.org> wrote:> All of the above is a really involved way of saving that I think you need > to change your spelling on the attribute a bit. I think we need to be able > to support fairly arbitrary restrictions on the relative range, and then > leave it up to the code generator which option it actually picks. As a > strawman, how about the following syntax: > > call void @foo() target-address-relative-bound(-2147483648 > <(214)%20748-3648>, 2147483647 <(214)%20748-3647>) > > OR > > declare void @foo() address-absolute-bound(X, X + 100MB) > > I agree, this makes sense to me. My bikeshedding suggestion is to storethe offsets in log2 form. Something like "target-pc-rel"(32) , "target-pc-rel"(12), "target-pc-abs"(32). This should generalize from X86 to ARM/AArch64 and other ISAs with shorter displacements. Later you could imagine throwing in other relocation variants like "tocrel", "gotrel", or anything you need for your particular architecture. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210902/3ea5ab05/attachment.html>