[LLVMdev] Register scavenger and SP/FP adjustments

Krzysztof Parzyszek kparzysz at codeaurora.org
Wed Sep 25 08:57:31 PDT 2013

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() ==
   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?


Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
hosted by The Linux Foundation

More information about the llvm-dev mailing list