<div dir="ltr"><div>Hello LLVM Community,<br></div><div><br></div><div>To improve Interprocedural Register Allocation (IPRA) we are trying to force caller</div><div>saved registers for local functions (which has likage type local). To achive it</div><div>I have modified TargetFrameLowering::determineCalleeSaves() to return early for</div><div>function which satisfies if (F->hasLocalLinkage() && !F->hasAddressTaken()) and</div><div>also reflecting the fact that for local function there are no caller saved registers</div><div>I am also changing RegUsageInfoCollector.cpp to not to mark regiseters as callee</div><div>saved in RegMask due to CC with follwoing change in code:</div><div><br></div><div>if (!F->hasLocalLinkage() || F->hasAddressTaken()) {</div><div>      const uint32_t *CallPreservedMask =</div><div>        TRI->getCallPreservedMask(MF, MF.getFunction()->getCallingConv());</div><div>      // Set callee saved register as preserved.</div><div>      for (unsigned i = 0; i < RegMaskSize; ++i)</div><div>        RegMask[i] = RegMask[i] | CallPreservedMask[i];</div><div>    } </div><div><br></div><div>For more details please follow following link.</div><div><a href="https://groups.google.com/d/msg/llvm-dev/XRzGhJ9wtZg/bYFMzppXEwAJ">https://groups.google.com/d/msg/llvm-dev/XRzGhJ9wtZg/bYFMzppXEwAJ</a></div><div><br></div><div>Now consider following bug due to forcing caller saved registers for local function</div><div>when IPRA enable:</div><div><br></div><div>void makewt(int nw, int *ip, double *w) {</div><div>  ...</div><div>  bitrv2(nw, ip, w);</div><div>}</div><div><br></div><div>here bitrv2 is local fuction and for that when IPRA enable callee saved registers</div><div>are set to none. So for that function following is set of collbered register as</div><div>per regmaks collected by RegUsageInfoCollector pass.</div><div><br></div><div>Function Name : bitrv2</div><div>Clobbered Registers:</div><div>AH AL AX BH BL BP BPL BX CH CL CX DI DIL EAX EBP EBX ECX EDI EFLAGS ESI ESP RAX</div><div>RBP RBX RCX RDI RSI RSP SI SIL SP SPL R8 R9 R10 R11 R12 R13 R14 R15 R8B R9B R10B</div><div>R11B R12B R13B R14B R15B R8D R9D R10D R11D R12D R13D R14D R15D R8W R9W R10W R11W</div><div>R12W R13W R14W R15W</div><div><br></div><div>How ever caller of bitrv2, makewt has callee saved registers as per CC, but this</div><div>code results in segmentation fault when compliled with O1 because makewt has value</div><div>of *ip in R14 register and that is stored and restore by makewt at begining of call</div><div>but due to tail call optimization following code is generated and here bitrv2 does</div><div>not preserve R14 so whwn execution returns to main (which is caller of makewt)</div><div>value of *ip is gone from R14 (which sould not) and when main calls makewt again</div><div>then value of *ip (R14) is wrong and result into segmentation fault.</div><div><br></div><div>Assembly code of makewt:</div><div>  _makewt:</div><div>  ...</div><div>  popq  %rbx</div><div>  popq  %r12</div><div>  popq  %r13</div><div>  popq  %r14</div><div>  popq  %r15</div><div>  popq  %rbp</div><div>  jmp _bitrv2                 ## TAILCALL</div><div><br></div><div>There is one more case of faluire due to local function related optimization.</div><div>I am analysing that (sorry for taking more time but I am not much good at assembly).</div><div><br></div><div>I need some hints for how to solve this. If you feel some problem with my analyses</div><div>please let me know if you want me to send generated .s file and source .c file.</div><div><br></div><div>Sincerely,</div><div>Vivek</div></div>