[LLVMdev] Register scavenger and SP/FP adjustments

Evan Cheng evan.cheng at apple.com
Thu Sep 26 11:24:59 PDT 2013


CallFrameSetupOpcode is a pseudo opcode like X86::ADJCALLSTACKDOWN64. That means when the code is expected to be called before the pseudo instructions are eliminated. I don't know why it's not the case for you. A quick look at PEI code indicates the pseudo's should not have been removed at the time when replaceFrameIndices are run.

Evan


On Sep 25, 2013, at 8:57 AM, Krzysztof Parzyszek <kparzysz at codeaurora.org> wrote:

> Hi All,
> I'm dealing with a problem where the spill/restore instructions inserted during scavenging span an adjustment of the SP/FP register.  The result is that despite the base register (SP/FP) being changed between the spill and the restore, both store and load use the same immediate offset.
> 
> I see code in the PEI (replaceFrameIndices) that is supposed to track the SP/FP adjustment:
> 
> ----------------------------------------
> void PEI::replaceFrameIndices(MachineBasicBlock *BB,
>                              MachineFunction &Fn, int &SPAdj) {
>  const TargetMachine &TM = Fn.getTarget();
>  assert(TM.getRegisterInfo() &&
>         "TM::getRegisterInfo() must be implemented!");
>  const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo();
>  const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
>  const TargetFrameLowering *TFI = TM.getFrameLowering();
>  bool StackGrowsDown =
>    TFI->getStackGrowthDirection() ==
>                TargetFrameLowering::StackGrowsDown;
>  int FrameSetupOpcode   = TII.getCallFrameSetupOpcode();
>  int FrameDestroyOpcode = TII.getCallFrameDestroyOpcode();
> 
>  if (RS && !FrameIndexVirtualScavenging) RS->enterBasicBlock(BB);
> 
>  for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
> 
>    if (I->getOpcode() == FrameSetupOpcode ||
>        I->getOpcode() == FrameDestroyOpcode) {
>      // Remember how much SP has been adjusted to create the call
>      // frame.
>      int Size = I->getOperand(0).getImm();
> 
>      if ((!StackGrowsDown && I->getOpcode() == FrameSetupOpcode) ||
>          (StackGrowsDown && I->getOpcode() == FrameDestroyOpcode))
>        Size = -Size;
> 
>      SPAdj += Size;
> 
>  [...]
> ----------------------------------------
> 
> 
> The problem is that it expects frame-setup and frame-destroy opcodes, but at the time it runs (after emitPrologue/emitEpilogue) the frame setup and teardown will be expanded into instruction sequences that can be different for each target, let alone having the immediate value in the 0-th operand.
> 
> As I see, this code won't work, although I'm not sure what was the original idea behind it.  Should this code run before the target specific generation of prolog/epilog?  Even then, there won't need to be ADJCALLSTACKUP/DOWN instructions (if it's a leaf function).  If it runs where it should, should it instead use some target-specific hook that identifies the actual stack adjustment amount?
> 
> -Krzysztof
> 
> 
> -- 
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130926/f44fe118/attachment.html>


More information about the llvm-dev mailing list