Frame Lowering in LLVM

0

So I am trying to implement a Toy Backend using LLVM using the below codes as reference for the different steps

I have a rough idea as to what frame lowering is (read emit prologue and emit epilogue) below are the codes for the same from the reference that I am using

emitPrologue:

void TOYFrameLowering::emitPrologue(MachineFunction &MF) const {
  const TargetInstrInfo &TII =*MF.getSubtarget().getInstrInfo();
  MachineBasicBlock &MBB = MF.front();
  MachineBasicBlock::iterator MBBI = MBB.begin();
  DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() :DebugLoc();
  uint64_t StackSize = computeStackSize(MF);
  if (!StackSize) {
      return;
  }
  unsigned StackReg = TOY::SP; //stack pointer
  unsigned OffsetReg = materializeOffset(MF, MBB, MBBI,
  (unsigned)StackSize);
  if (OffsetReg) {
      BuildMI(MBB, MBBI, dl, TII.get(TOY::SUBrr), StackReg)
        .addReg(StackReg)
        .addReg(OffsetReg)
        .setMIFlag(MachineInstr::FrameSetup);
  } else {
      BuildMI(MBB, MBBI, dl, TII.get(TOY::SUBri), StackReg)
        .addReg(StackReg)
        .addImm(StackSize)
        .setMIFlag(MachineInstr::FrameSetup);
        }
  }

emitEpilogue:

void TOYFrameLowering::emitEpilogue(MachineFunction &MF,MachineBasicBlock &MBB)const {
   const TargetInstrInfo &TII =*MF.getSubtarget().getInstrInfo();
   MachineBasicBlock::iterator MBBI =MBB.getLastNonDebugInstr();
   DebugLoc dl = MBBI->getDebugLoc();
   uint64_t StackSize = computeStackSize(MF);
   if (!StackSize) {
      return;
   }
   unsigned StackReg = TOY::SP;
   unsigned OffsetReg = materializeOffset(MF, MBB, MBBI,(unsigned)StackSize);
   if (OffsetReg) {
      BuildMI(MBB, MBBI, dl, TII.get(TOY::ADDrr), StackReg)
      .addReg(StackReg)
      .addReg(OffsetReg)
      .setMIFlag(MachineInstr::FrameSetup);
   } 
   else {
      BuildMI(MBB, MBBI, dl, TII.get(TOY::ADDri), StackReg)
      .addReg(StackReg)
      .addImm(StackSize)
      .setMIFlag(MachineInstr::FrameSetup);
    }
  }

Some helper Functions:

compute stack size:

uint64_t TOYFrameLowering::computeStackSize(MachineFunction &MF) const {
    MachineFrameInfo *MFI = MF.getFrameInfo();
    uint64_t StackSize = MFI->getStackSize();
    unsigned StackAlign = getStackAlignment();
    if (StackAlign > 0) {
    StackSize = RoundUpToAlignment(StackSize, StackAlign);
    }
    return StackSize;
}

materialize offset:

static unsigned materializeOffset(MachineFunction &MF,MachineBasicBlock &MBB,MachineBasicBlock::iterator MBBI,unsigned Offset) {
        const TargetInstrInfo &TII =*MF.getSubtarget().getInstrInfo();
        DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
        const uint64_t MaxSubImm = 0xfff;
        if (Offset <= MaxSubImm) {
            return 0;
        } 
        else {
            unsigned OffsetReg = TOY::R2;
            unsigned OffsetLo = (unsigned)(Offset & 0xffff);
            unsigned OffsetHi = (unsigned)((Offset & 0xffff0000) >>16);
            BuildMI(MBB, MBBI, dl, TII.get(TOY::MOVLOi16),OffsetReg)
            .addImm(OffsetLo)
            .setMIFlag(MachineInstr::FrameSetup);
            if (OffsetHi) {
               BuildMI(MBB, MBBI, dl, TII.get(TOY::MOVHIi16),OffsetReg)
               .addReg(OffsetReg)
               .addImm(OffsetHi)
               .setMIFlag(MachineInstr::FrameSetup);
              }
            return OffsetReg;
          }
}

Everything is pretty self-explanatory except the materializeoffset() function I cannot seem to wrap my head around as to what it does can someone explain the same using an example

assembly
llvm
system
llvm-ir
asked on Stack Overflow Jun 25, 2020 by lava_07

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0