[llvm-dev] Tail call optimization is getting affected due to local function related optimization with IPRA

vivek pandya via llvm-dev llvm-dev at lists.llvm.org
Sat Jun 25 10:33:14 PDT 2016


Hello LLVM Community,

To improve Interprocedural Register Allocation (IPRA) we are trying to
force caller
saved registers for local functions (which has likage type local). To
achive it
I have modified TargetFrameLowering::determineCalleeSaves() to return early
for
function which satisfies if (F->hasLocalLinkage() && !F->hasAddressTaken())
and
also reflecting the fact that for local function there are no caller saved
registers
I am also changing RegUsageInfoCollector.cpp to not to mark regiseters as
callee
saved in RegMask due to CC with follwoing change in code:

if (!F->hasLocalLinkage() || F->hasAddressTaken()) {
      const uint32_t *CallPreservedMask =
        TRI->getCallPreservedMask(MF, MF.getFunction()->getCallingConv());
      // Set callee saved register as preserved.
      for (unsigned i = 0; i < RegMaskSize; ++i)
        RegMask[i] = RegMask[i] | CallPreservedMask[i];
    }

For more details please follow following link.
https://groups.google.com/d/msg/llvm-dev/XRzGhJ9wtZg/bYFMzppXEwAJ

Now consider following bug due to forcing caller saved registers for local
function
when IPRA enable:

void makewt(int nw, int *ip, double *w) {
  ...
  bitrv2(nw, ip, w);
}

here bitrv2 is local fuction and for that when IPRA enable callee saved
registers
are set to none. So for that function following is set of collbered
register as
per regmaks collected by RegUsageInfoCollector pass.

Function Name : bitrv2
Clobbered Registers:
AH AL AX BH BL BP BPL BX CH CL CX DI DIL EAX EBP EBX ECX EDI EFLAGS ESI ESP
RAX
RBP RBX RCX RDI RSI RSP SI SIL SP SPL R8 R9 R10 R11 R12 R13 R14 R15 R8B R9B
R10B
R11B R12B R13B R14B R15B R8D R9D R10D R11D R12D R13D R14D R15D R8W R9W R10W
R11W
R12W R13W R14W R15W

How ever caller of bitrv2, makewt has callee saved registers as per CC, but
this
code results in segmentation fault when compliled with O1 because makewt
has value
of *ip in R14 register and that is stored and restore by makewt at begining
of call
but due to tail call optimization following code is generated and here
bitrv2 does
not preserve R14 so whwn execution returns to main (which is caller of
makewt)
value of *ip is gone from R14 (which sould not) and when main calls makewt
again
then value of *ip (R14) is wrong and result into segmentation fault.

Assembly code of makewt:
  _makewt:
  ...
  popq  %rbx
  popq  %r12
  popq  %r13
  popq  %r14
  popq  %r15
  popq  %rbp
  jmp _bitrv2                 ## TAILCALL

There is one more case of faluire due to local function related
optimization.
I am analysing that (sorry for taking more time but I am not much good at
assembly).

I need some hints for how to solve this. If you feel some problem with my
analyses
please let me know if you want me to send generated .s file and source .c
file.

Sincerely,
Vivek
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160625/135cfff9/attachment.html>


More information about the llvm-dev mailing list