On Thu, Mar 11, 2021 at 11:29:57AM -0300, Alexandre Oliva wrote: > On Mar 11, 2021, Richard Biener <richard.guent...@gmail.com> wrote: > > I wonder what the effect of this switch is - it's documented as > > affecting the call site (different call insn sequence by default), so > > the best representation would be an attribute on actual call stmts > > I don't think that would fulfill its purpose.
That is how it already works though. The option sets a flag that gives the default for a function attribute. The function attribute is used at the call site: === void f(void); void g(void) __attribute__((longcall)); void h(void) { f(); g(); } static void (*i)(void) = f; static void (*j)(void) __attribute__((longcall)) = f; void k(void) { i(); j(); } === Note that in "k" the call via "i" is done as a direct call, and that via "j" uses a bctr. > My understanding is that the longcall attribute is intended to issue > call sequences that assume the target of the call will be out of range > for available PC-relative addressing modes in call instructions. Yes. > One use I'm familiar with is when different modules are known to be > going to be linked separately, and dynamically loaded at disparate > memory locations, so that PC-relative branches across modules won't do, > and PLTs are not available. And you need to call via function pointers *anyway*, so you do not need this attribute at all? It could matter if you do cross-module IPA optimisations, but you don't (do you? That will cause no end of fresh new problems!) > Indirect calls are pretty much long calls by definition, It's the other way around. Longcalls are implemented as indirect calls. > but I suppose > the goal of retaining the long-call requests has to do with the > possibility of sometimes resolving an indirect call back to a direct > call. You will save yourself a lot of problems by simply making that impossible. Makes such function pointers explicit in your code. > If it wasn't associated with the type, It isn't. It is a function attribute. > > but it does look better than just a global flag. The flag is just for setting a default, which often is handy (esp. for code that is too humonguous to compile without it: it is a simple flag to add, and your program was probably slow to begin with, being huge and all). Segher