[LLVMdev] Properly handling mem-loc arguments when prologue adjusts FP.

Stephen McGruer stephen.mcgruer at gmail.com
Fri Oct 26 03:54:58 PDT 2012


For my target, I handle incoming memory arguments by creating a store to
memory (in LowerCall, [1]), then creating a fixed object on the stack and
loading from it (in LowerFormalArguments[2]). This approach was based on
MSP430.

I now have the problem that the resulting loads in my output assembly are
done assuming that the call stack looks something like:

------
MemArg
------
MemArg
------ <-- Frame Pointer

This isn't true, because during prologue I emit a number of instructions to
store the return address, the old frame pointer value, etc[3], so that the
stack ends up looking like:

------
MemArg
------
MemArg
------
VarArg
------
Return Addr Register
------
Old Frame Pointer
------ <-- Frame Pointer

At this point, the memory-argument instructions like 'ld rX, [fp]' (load
from frame-pointer) now obviously load the wrong data.

How can I 'fix' the load instructions to point to the right locations in
memory? (That is, increase their offset by the space that the prologue adds
to the stack)?

One thing that I've just realized may be notable is that my prologue code
(see [3]) uses a special "st.a" instruction that both stores to a memory
location and decrements the address-argument-register. (i.e. st.a r1, [r2,
4] does r2 = r2 - 4 then stores to [r2]). So if LLVM normally guesses these
things automatically from the instructions, it wouldn't be able to guess
that. But here I'm just conjecturing - may not be relevant!

Thanks,
Stephen

[1]: LowerCall
...
    // Arguments that can be passed in a register must be kept in the
    // RegsToPass vector.
    if (VA.isRegLoc()) {
      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
    } else {
      // Sanity check.
      assert(VA.isMemLoc());

      // Get the stack pointer if needed.
      if (StackPtr.getNode() == 0) {
        StackPtr = DAG.getCopyFromReg(Chain, dl, ARC::SP, getPointerTy());
      }

      SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), StackPtr,
          DAG.getIntPtrConstant(VA.getLocMemOffset()));
      MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
          MachinePointerInfo(),false, false, 0));
    }
...

[2]: LowerFormalArguments
...
    if (VA.isRegLoc()) {
      // Arguments passed in registers.

      const TargetRegisterClass *RC = ARC::CPURegsRegisterClass;
      unsigned int Register = MF.addLiveIn(VA.getLocReg(), RC);
      EVT RegisterValueType = VA.getLocVT();
      ArgValue = DAG.getCopyFromReg(Chain, dl, Register, RegisterValueType);

      InVals.push_back(ArgValue);
    } else {
      // Sanity check
      assert(VA.isMemLoc());

      // Load the argument to a virtual register
      unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;

      if (ObjSize != 4) {
        llvm_unreachable("Memory argument is wrong size - not 32 bit!");
      }

      // Create the frame index object for this incoming parameter...
      int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);

      // Create the SelectionDAG nodes corresponding to a load from this
      // parameter.
      SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
      InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
                                   MachinePointerInfo::getFixedStack(FI),
                                   false, false, false, 0));
    }
...

[3] Example of prologue moving stack pointer (which the frame pointer is
then set to.)
...
  if (VARegSaveSize) {
    BuildMI(MBB, MBBI, dl, TII.get(ARC::SUBrsi), ARC::SP).addReg(ARC::SP)
        .addImm(VARegSaveSize);
  }

  // Save the return address register, if necessary
  if (MFI->adjustsStack()) {
    BuildMI(MBB, MBBI, dl, TII.get(ARC::STrri_a)).addReg(ARC::SP)
        .addImm(-UNITS_PER_WORD).addReg(ARC::BLINK);
  }

  // Save the caller's frame pointer (if required), and set new FP to this
  // location.
  BuildMI(MBB, MBBI, dl, TII.get(ARC::STrri_a)).addReg(ARC::SP)
      .addImm(-UNITS_PER_WORD).addReg(ARC::FP);
  BuildMI(MBB, MBBI, dl, TII.get(ARC::MOVrr), ARC::FP).addReg(ARC::SP);
...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20121026/8f1f3bfa/attachment.html>


More information about the llvm-dev mailing list