void Mips16DAGToDAGISel::initGlobalBaseReg(MachineFunction &MF) { MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); if (!MipsFI->globalBaseRegSet()) return; MachineBasicBlock &MBB = MF.front(); MachineBasicBlock::iterator I = MBB.begin(); MachineRegisterInfo &RegInfo = MF.getRegInfo(); const TargetInstrInfo &TII = *Subtarget->getInstrInfo(); DebugLoc DL; unsigned V0, V1, V2, GlobalBaseReg = MipsFI->getGlobalBaseReg(); const TargetRegisterClass *RC = &Mips::CPU16RegsRegClass; V0 = RegInfo.createVirtualRegister(RC); V1 = RegInfo.createVirtualRegister(RC); V2 = RegInfo.createVirtualRegister(RC); BuildMI(MBB, I, DL, TII.get(Mips::GotPrologue16), V0). addReg(V1, RegState::Define). addExternalSymbol("_gp_disp", MipsII::MO_ABS_HI). addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO); BuildMI(MBB, I, DL, TII.get(Mips::SllX16), V2).addReg(V0).addImm(16); BuildMI(MBB, I, DL, TII.get(Mips::AdduRxRyRz16), GlobalBaseReg) .addReg(V1).addReg(V2); }
// Find a scratch register that we can use at the start of the prologue to // re-align the stack pointer. We avoid using callee-save registers since they // may appear to be free when this is called from canUseAsPrologue (during // shrink wrapping), but then no longer be free when this is called from // emitPrologue. // // FIXME: This is a bit conservative, since in the above case we could use one // of the callee-save registers as a scratch temp to re-align the stack pointer, // but we would then have to make sure that we were in fact saving at least one // callee-save register in the prologue, which is additional complexity that // doesn't seem worth the benefit. static unsigned findScratchNonCalleeSaveRegister(MachineBasicBlock *MBB) { MachineFunction *MF = MBB->getParent(); // If MBB is an entry block, use X9 as the scratch register if (&MF->front() == MBB) return AArch64::X9; RegScavenger RS; RS.enterBasicBlock(*MBB); // Prefer X9 since it was historically used for the prologue scratch reg. if (!RS.isRegUsed(AArch64::X9)) return AArch64::X9; // Find a free non callee-save reg. const AArch64Subtarget &Subtarget = MF->getSubtarget<AArch64Subtarget>(); const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo(); const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(MF); BitVector CalleeSaveRegs(RegInfo->getNumRegs()); for (unsigned i = 0; CSRegs[i]; ++i) CalleeSaveRegs.set(CSRegs[i]); BitVector Available = RS.getRegsAvailable(&AArch64::GPR64RegClass); for (int AvailReg = Available.find_first(); AvailReg != -1; AvailReg = Available.find_next(AvailReg)) if (!CalleeSaveRegs.test(AvailReg)) return AvailReg; return AArch64::NoRegister; }
bool Mips16FrameLowering:: spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector<CalleeSavedInfo> &CSI, const TargetRegisterInfo *TRI) const { MachineFunction *MF = MBB.getParent(); MachineBasicBlock *EntryBlock = &MF->front(); // // Registers RA, S0,S1 are the callee saved registers and they // will be saved with the "save" instruction // during emitPrologue // for (unsigned i = 0, e = CSI.size(); i != e; ++i) { // Add the callee-saved register as live-in. Do not add if the register is // RA and return address is taken, because it has already been added in // method MipsTargetLowering::LowerRETURNADDR. // It's killed at the spill, unless the register is RA and return address // is taken. unsigned Reg = CSI[i].getReg(); bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA) && MF->getFrameInfo()->isReturnAddressTaken(); if (!IsRAAndRetAddrIsTaken) EntryBlock->addLiveIn(Reg); } return true; }
void MipsFrameInfo::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); MachineFrameInfo *MFI = MF.getFrameInfo(); MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); const MipsRegisterInfo *RegInfo = static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); const MipsInstrInfo &TII = *static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo()); MachineBasicBlock::iterator MBBI = MBB.begin(); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); bool isPIC = (MF.getTarget().getRelocationModel() == Reloc::PIC_); // Get the right frame order for Mips. adjustMipsStackFrame(MF); // Get the number of bytes to allocate from the FrameInfo. unsigned StackSize = MFI->getStackSize(); // No need to allocate space on the stack. if (StackSize == 0 && !MFI->adjustsStack()) return; int FPOffset = MipsFI->getFPStackOffset(); int RAOffset = MipsFI->getRAStackOffset(); BuildMI(MBB, MBBI, dl, TII.get(Mips::NOREORDER)); // TODO: check need from GP here. if (isPIC && STI.isABI_O32()) BuildMI(MBB, MBBI, dl, TII.get(Mips::CPLOAD)) .addReg(RegInfo->getPICCallReg()); BuildMI(MBB, MBBI, dl, TII.get(Mips::NOMACRO)); // Adjust stack : addi sp, sp, (-imm) BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDiu), Mips::SP) .addReg(Mips::SP).addImm(-StackSize); // Save the return address only if the function isnt a leaf one. // sw $ra, stack_loc($sp) if (MFI->adjustsStack()) { BuildMI(MBB, MBBI, dl, TII.get(Mips::SW)) .addReg(Mips::RA).addImm(RAOffset).addReg(Mips::SP); } // if framepointer enabled, save it and set it // to point to the stack pointer if (hasFP(MF)) { // sw $fp,stack_loc($sp) BuildMI(MBB, MBBI, dl, TII.get(Mips::SW)) .addReg(Mips::FP).addImm(FPOffset).addReg(Mips::SP); // move $fp, $sp BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDu), Mips::FP) .addReg(Mips::SP).addReg(Mips::ZERO); } // Restore GP from the saved stack location if (MipsFI->needGPSaveRestore()) BuildMI(MBB, MBBI, dl, TII.get(Mips::CPRESTORE)) .addImm(MipsFI->getGPStackOffset()); }
/// Compute the sets of entry and return blocks for saving and restoring /// callee-saved registers, and placing prolog and epilog code. void PEI::calculateSaveRestoreBlocks(MachineFunction &Fn) { const MachineFrameInfo &MFI = Fn.getFrameInfo(); // Even when we do not change any CSR, we still want to insert the // prologue and epilogue of the function. // So set the save points for those. // Use the points found by shrink-wrapping, if any. if (MFI.getSavePoint()) { SaveBlocks.push_back(MFI.getSavePoint()); assert(MFI.getRestorePoint() && "Both restore and save must be set"); MachineBasicBlock *RestoreBlock = MFI.getRestorePoint(); // If RestoreBlock does not have any successor and is not a return block // then the end point is unreachable and we do not need to insert any // epilogue. if (!RestoreBlock->succ_empty() || RestoreBlock->isReturnBlock()) RestoreBlocks.push_back(RestoreBlock); return; } // Save refs to entry and return blocks. SaveBlocks.push_back(&Fn.front()); for (MachineBasicBlock &MBB : Fn) { if (MBB.isEHFuncletEntry()) SaveBlocks.push_back(&MBB); if (MBB.isReturnBlock()) RestoreBlocks.push_back(&MBB); } }
void NVPTXFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { if (MF.getFrameInfo()->hasStackObjects()) { assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); // Insert "mov.u32 %SP, %Depot" MachineBasicBlock::iterator MBBI = MBB.begin(); // This instruction really occurs before first instruction // in the BB, so giving it no debug location. DebugLoc dl = DebugLoc(); MachineRegisterInfo &MRI = MF.getRegInfo(); // mov %SPL, %depot; // cvta.local %SP, %SPL; if (static_cast<const NVPTXTargetMachine &>(MF.getTarget()).is64Bit()) { unsigned LocalReg = MRI.createVirtualRegister(&NVPTX::Int64RegsRegClass); MachineInstr *MI = BuildMI(MBB, MBBI, dl, MF.getSubtarget().getInstrInfo()->get( NVPTX::cvta_local_yes_64), NVPTX::VRFrame).addReg(LocalReg); BuildMI(MBB, MI, dl, MF.getSubtarget().getInstrInfo()->get(NVPTX::MOV_DEPOT_ADDR_64), LocalReg).addImm(MF.getFunctionNumber()); } else { unsigned LocalReg = MRI.createVirtualRegister(&NVPTX::Int32RegsRegClass); MachineInstr *MI = BuildMI(MBB, MBBI, dl, MF.getSubtarget().getInstrInfo()->get(NVPTX::cvta_local_yes), NVPTX::VRFrame).addReg(LocalReg); BuildMI(MBB, MI, dl, MF.getSubtarget().getInstrInfo()->get(NVPTX::MOV_DEPOT_ADDR), LocalReg).addImm(MF.getFunctionNumber()); } } }
void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); MachineFrameInfo *MFI = MF.getFrameInfo(); MachineBasicBlock::iterator MBBI = MBB.begin(); const HexagonRegisterInfo *QRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo(); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); determineFrameLayout(MF); // Get the number of bytes to allocate from the FrameInfo. int NumBytes = (int) MFI->getStackSize(); // LLVM expects allocframe not to be the first instruction in the // basic block. MachineBasicBlock::iterator InsertPt = MBB.begin(); // // ALLOCA adjust regs. Iterate over ADJDYNALLOC nodes and change the offset. // HexagonMachineFunctionInfo *FuncInfo = MF.getInfo<HexagonMachineFunctionInfo>(); const std::vector<MachineInstr*>& AdjustRegs = FuncInfo->getAllocaAdjustInsts(); for (std::vector<MachineInstr*>::const_iterator i = AdjustRegs.begin(), e = AdjustRegs.end(); i != e; ++i) { MachineInstr* MI = *i; assert((MI->getOpcode() == Hexagon::ADJDYNALLOC) && "Expected adjust alloca node"); MachineOperand& MO = MI->getOperand(2); assert(MO.isImm() && "Expected immediate"); MO.setImm(MFI->getMaxCallFrameSize()); } // // Only insert ALLOCFRAME if we need to. // if (hasFP(MF)) { // Check for overflow. // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used? const int ALLOCFRAME_MAX = 16384; const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); if (NumBytes >= ALLOCFRAME_MAX) { // Emit allocframe(#0). BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::S2_allocframe)).addImm(0); // Subtract offset from frame pointer. BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real), HEXAGON_RESERVED_REG_1).addImm(NumBytes); BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::A2_sub), QRI->getStackRegister()). addReg(QRI->getStackRegister()). addReg(HEXAGON_RESERVED_REG_1); } else { BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::S2_allocframe)).addImm(NumBytes); } } }
/// Insert BLOCK markers at appropriate places. static void PlaceBlockMarkers(MachineBasicBlock &MBB, MachineBasicBlock &Succ, MachineFunction &MF, const MachineLoopInfo &MLI, const WebAssemblyInstrInfo &TII) { // Backward branches are loop backedges, and we place the LOOP markers // separately. So only consider forward branches here. if (Succ.getNumber() <= MBB.getNumber()) return; // Place the BLOCK for a forward branch. For simplicity, we just insert // blocks immediately inside loop boundaries. MachineLoop *Loop = MLI.getLoopFor(&Succ); MachineBasicBlock &Header = *(Loop ? Loop->getHeader() : &MF.front()); MachineBasicBlock::iterator InsertPos = Header.begin(), End = Header.end(); if (InsertPos != End) { if (InsertPos->getOpcode() == WebAssembly::LOOP) ++InsertPos; int SuccNumber = Succ.getNumber(); // Position the BLOCK in nesting order. for (; InsertPos != End && InsertPos->getOpcode() == WebAssembly::BLOCK; ++InsertPos) { int N = InsertPos->getOperand(0).getMBB()->getNumber(); if (N < SuccNumber) break; // If there's already a BLOCK for Succ, we don't need another. if (N == SuccNumber) return; } } BuildMI(Header, InsertPos, DebugLoc(), TII.get(WebAssembly::BLOCK)) .addMBB(&Succ); }
void NyuziFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { assert(&MF.front() == &MBB); MachineFrameInfo *MFI = MF.getFrameInfo(); const NyuziInstrInfo &TII = *static_cast<const NyuziInstrInfo *>(MF.getSubtarget().getInstrInfo()); MachineModuleInfo &MMI = MF.getMMI(); const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); MachineBasicBlock::iterator MBBI = MBB.begin(); DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); // Compute stack size to allocate, keeping SP 64 byte aligned so we // can do block vector load/stores int StackSize = RoundUpToAlignment(MFI->getStackSize(), getStackAlignment()); // Bail if there is no stack allocation if (StackSize == 0 && !MFI->adjustsStack()) return; TII.adjustStackPointer(MBB, MBBI, -StackSize); // Emit DW_CFA_def_cfa unsigned CFIIndex = MMI.addFrameInst( MCCFIInstruction::createDefCfaOffset(nullptr, -StackSize)); BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex); // Find the instruction past the last instruction that saves a callee-saved // register to the stack. We need to set up FP after its old value has been // saved. const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); if (CSI.size()) { for (unsigned i = 0; i < CSI.size(); ++i) ++MBBI; // Iterate over list of callee-saved registers and emit .cfi_offset // directives (debug information) for (const auto &I : CSI) { int64_t Offset = MFI->getObjectOffset(I.getFrameIdx()); unsigned Reg = I.getReg(); unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createOffset( nullptr, MRI->getDwarfRegNum(Reg, 1), Offset)); BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex); } } // fp = sp if (hasFP(MF)) { BuildMI(MBB, MBBI, DL, TII.get(Nyuzi::MOVESS)) .addReg(Nyuzi::FP_REG) .addReg(Nyuzi::SP_REG); // emit ".cfi_def_cfa_register $fp" (debug information) unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister( nullptr, MRI->getDwarfRegNum(Nyuzi::FP_REG, true))); BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex); } }
bool VPreRegAllocSched::runOnMachineFunction(MachineFunction &MF) { TII = MF.getTarget().getInstrInfo(); MRI = &MF.getRegInfo(); FInfo = MF.getInfo<VFInfo>(); AA = &getAnalysis<AliasAnalysis>(); MLI = &getAnalysis<MachineLoopInfo>(); MDT= &getAnalysis<MachineDominatorTree>(); LI = &getAnalysis<LoopInfo>(); SE = &getAnalysis<ScalarEvolution>(); // Create a place holder for the virtual exit for the scheduling graph. MachineBasicBlock *VirtualExit = MF.CreateMachineBasicBlock(); MF.push_back(VirtualExit); VSchedGraph G(getAnalysis<DetialLatencyInfo>(), EnableDangling, false, 1); buildGlobalSchedulingGraph(G, &MF.front(), VirtualExit); schedule(G); DEBUG(G.viewCPGraph()); DEBUG(G.viewDPGraph()); // Erase the virtual exit block. VirtualExit->eraseFromParent(); MF.RenumberBlocks(&MF.back()); unsigned TotalCycles = G.emitSchedule(); FInfo->setTotalSlots(TotalCycles); cleanUpSchedule(); return true; }
void TMS320C64XFrameLowering::emitPrologue(MachineFunction &MF) const { int frame_size; MachineBasicBlock &MBB = MF.front(); MachineFrameInfo *MFI = MF.getFrameInfo(); MachineBasicBlock::iterator MBBI = MBB.begin(); DebugLoc dl = (MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc()); // Mark return address as being a live in - don't mark it as such for // the whole function, because we want to save it manually. Otherwise // extra code will be generated to store it elsewhere. // Ideally we don't need to save manually, but I call this easier // to debug. MBB.addLiveIn(TMS320C64X::B3); frame_size = MFI->getStackSize(); frame_size += 8; // Align the size of the stack - has to remain double word aligned. frame_size += 7; frame_size &= ~7; const TMS320C64XInstrInfo &TII = *TM.getInstrInfo(); // Different to epilogue, we always use the prolog pseudo function, which // will emit a 2- or 3-cycle prologue. TMS320C64XInstrInfo::addDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(TMS320C64X::prolog)).addImm(frame_size)); }
// Find a scratch register that we can use at the start of the prologue to // re-align the stack pointer. We avoid using callee-save registers since they // may appear to be free when this is called from canUseAsPrologue (during // shrink wrapping), but then no longer be free when this is called from // emitPrologue. // // FIXME: This is a bit conservative, since in the above case we could use one // of the callee-save registers as a scratch temp to re-align the stack pointer, // but we would then have to make sure that we were in fact saving at least one // callee-save register in the prologue, which is additional complexity that // doesn't seem worth the benefit. static unsigned findScratchNonCalleeSaveRegister(MachineBasicBlock *MBB) { MachineFunction *MF = MBB->getParent(); // If MBB is an entry block, use X9 as the scratch register if (&MF->front() == MBB) return AArch64::X9; const AArch64Subtarget &Subtarget = MF->getSubtarget<AArch64Subtarget>(); const AArch64RegisterInfo *TRI = Subtarget.getRegisterInfo(); LivePhysRegs LiveRegs(TRI); LiveRegs.addLiveIns(*MBB); // Mark callee saved registers as used so we will not choose them. const MCPhysReg *CSRegs = TRI->getCalleeSavedRegs(MF); for (unsigned i = 0; CSRegs[i]; ++i) LiveRegs.addReg(CSRegs[i]); // Prefer X9 since it was historically used for the prologue scratch reg. const MachineRegisterInfo &MRI = MF->getRegInfo(); if (LiveRegs.available(MRI, AArch64::X9)) return AArch64::X9; for (unsigned Reg : AArch64::GPR64RegClass) { if (LiveRegs.available(MRI, Reg)) return Reg; } return AArch64::NoRegister; }
/// Helper function to update the liveness information for the callee-saved /// registers. static void updateLiveness(MachineFunction &MF) { MachineFrameInfo &MFI = MF.getFrameInfo(); // Visited will contain all the basic blocks that are in the region // where the callee saved registers are alive: // - Anything that is not Save or Restore -> LiveThrough. // - Save -> LiveIn. // - Restore -> LiveOut. // The live-out is not attached to the block, so no need to keep // Restore in this set. SmallPtrSet<MachineBasicBlock *, 8> Visited; SmallVector<MachineBasicBlock *, 8> WorkList; MachineBasicBlock *Entry = &MF.front(); MachineBasicBlock *Save = MFI.getSavePoint(); if (!Save) Save = Entry; if (Entry != Save) { WorkList.push_back(Entry); Visited.insert(Entry); } Visited.insert(Save); MachineBasicBlock *Restore = MFI.getRestorePoint(); if (Restore) // By construction Restore cannot be visited, otherwise it // means there exists a path to Restore that does not go // through Save. WorkList.push_back(Restore); while (!WorkList.empty()) { const MachineBasicBlock *CurBB = WorkList.pop_back_val(); // By construction, the region that is after the save point is // dominated by the Save and post-dominated by the Restore. if (CurBB == Save && Save != Restore) continue; // Enqueue all the successors not already visited. // Those are by construction either before Save or after Restore. for (MachineBasicBlock *SuccBB : CurBB->successors()) if (Visited.insert(SuccBB).second) WorkList.push_back(SuccBB); } const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); MachineRegisterInfo &MRI = MF.getRegInfo(); for (unsigned i = 0, e = CSI.size(); i != e; ++i) { for (MachineBasicBlock *MBB : Visited) { MCPhysReg Reg = CSI[i].getReg(); // Add the callee-saved register as live-in. // It's killed at the spill. if (!MRI.isReserved(Reg) && !MBB->isLiveIn(Reg)) MBB->addLiveIn(Reg); } } }
static void emitGPDisp(MachineFunction &F, const MipsInstrInfo *TII) { MachineBasicBlock &MBB = F.front(); MachineBasicBlock::iterator I = MBB.begin(); DebugLoc DL = MBB.findDebugLoc(MBB.begin()); BuildMI(MBB, I, DL, TII->get(Mips::LUi), Mips::V0) .addExternalSymbol("_gp_disp", MipsII::MO_ABS_HI); BuildMI(MBB, I, DL, TII->get(Mips::ADDiu), Mips::V0) .addReg(Mips::V0).addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO); MBB.removeLiveIn(Mips::V0); }
void PatmosFrameLowering::emitPrologue(MachineFunction &MF) const { // get some references MachineBasicBlock &MBB = MF.front(); MachineFrameInfo *MFI = MF.getFrameInfo(); const TargetInstrInfo *TII = TM.getInstrInfo(); MachineBasicBlock::iterator MBBI = MBB.begin(); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); //---------------------------------------------------------------------------- // Handle the stack cache -- if enabled. if (MFI->getMaxAlignment() > 4) { dbgs() << "Stack alignment "; if (MF.getFunction()) dbgs() << "in " << MF.getFunction()->getName() << " "; dbgs() << "too large (" << MFI->getMaxAlignment() << ").\n"; report_fatal_error("Stack alignment other than 4 byte is not supported"); } // assign some FIs to the stack cache if possible unsigned stackSize = assignFrameObjects(MF, !DisableStackCache); if (!DisableStackCache) { // emit a reserve instruction MachineInstr *MI = emitSTC(MF, MBB, MBBI, Patmos::SRESi); if (MI) MI->setFlag(MachineInstr::FrameSetup); // patch all call sites patchCallSites(MF); } //---------------------------------------------------------------------------- // Handle the shadow stack // Do we need to allocate space on the stack? if (stackSize) { // adjust stack : sp -= stack size if (stackSize <= 0xFFF) { MachineInstr *MI = AddDefaultPred(BuildMI(MBB, MBBI, dl, TII->get(Patmos::SUBi), Patmos::RSP)) .addReg(Patmos::RSP).addImm(stackSize); MI->setFlag(MachineInstr::FrameSetup); } else { MachineInstr *MI = AddDefaultPred(BuildMI(MBB, MBBI, dl, TII->get(Patmos::SUBl), Patmos::RSP)) .addReg(Patmos::RSP).addImm(stackSize); MI->setFlag(MachineInstr::FrameSetup); } } }
bool SIWholeQuadMode::runOnMachineFunction(MachineFunction &MF) { if (MF.getFunction()->getCallingConv() != CallingConv::AMDGPU_PS) return false; Instructions.clear(); Blocks.clear(); ExecExports.clear(); LiveMaskQueries.clear(); const SISubtarget &ST = MF.getSubtarget<SISubtarget>(); TII = ST.getInstrInfo(); TRI = &TII->getRegisterInfo(); MRI = &MF.getRegInfo(); LIS = &getAnalysis<LiveIntervals>(); char GlobalFlags = analyzeFunction(MF); if (!(GlobalFlags & StateWQM)) { lowerLiveMaskQueries(AMDGPU::EXEC); return !LiveMaskQueries.empty(); } // Store a copy of the original live mask when required unsigned LiveMaskReg = 0; { MachineBasicBlock &Entry = MF.front(); MachineBasicBlock::iterator EntryMI = Entry.getFirstNonPHI(); if (GlobalFlags & StateExact || !LiveMaskQueries.empty()) { LiveMaskReg = MRI->createVirtualRegister(&AMDGPU::SReg_64RegClass); BuildMI(Entry, EntryMI, DebugLoc(), TII->get(AMDGPU::COPY), LiveMaskReg) .addReg(AMDGPU::EXEC); } if (GlobalFlags == StateWQM) { // For a shader that needs only WQM, we can just set it once. BuildMI(Entry, EntryMI, DebugLoc(), TII->get(AMDGPU::S_WQM_B64), AMDGPU::EXEC) .addReg(AMDGPU::EXEC); lowerLiveMaskQueries(LiveMaskReg); // EntryMI may become invalid here return true; } } lowerLiveMaskQueries(LiveMaskReg); // Handle the general case for (auto BII : Blocks) processBlock(*BII.first, LiveMaskReg, BII.first == &*MF.begin()); return true; }
bool WebAssemblyRegNumbering::runOnMachineFunction(MachineFunction &MF) { DEBUG(dbgs() << "********** Register Numbering **********\n" "********** Function: " << MF.getName() << '\n'); WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>(); MachineRegisterInfo &MRI = MF.getRegInfo(); const MachineFrameInfo &FrameInfo = *MF.getFrameInfo(); MFI.initWARegs(); // WebAssembly argument registers are in the same index space as local // variables. Assign the numbers for them first. MachineBasicBlock &EntryMBB = MF.front(); for (MachineInstr &MI : EntryMBB) { switch (MI.getOpcode()) { case WebAssembly::ARGUMENT_I32: case WebAssembly::ARGUMENT_I64: case WebAssembly::ARGUMENT_F32: case WebAssembly::ARGUMENT_F64: MFI.setWAReg(MI.getOperand(0).getReg(), MI.getOperand(1).getImm()); break; default: break; } } // Then assign regular WebAssembly registers for all remaining used // virtual registers. unsigned NumArgRegs = MFI.getParams().size(); unsigned NumVRegs = MF.getRegInfo().getNumVirtRegs(); unsigned NumStackRegs = 0; unsigned CurReg = 0; for (unsigned VRegIdx = 0; VRegIdx < NumVRegs; ++VRegIdx) { unsigned VReg = TargetRegisterInfo::index2VirtReg(VRegIdx); // Handle stackified registers. if (MFI.isVRegStackified(VReg)) { MFI.setWAReg(VReg, INT32_MIN | NumStackRegs++); continue; } // Skip unused registers. if (MRI.use_empty(VReg)) continue; if (MFI.getWAReg(VReg) == WebAssemblyFunctionInfo::UnusedReg) MFI.setWAReg(VReg, NumArgRegs + CurReg++); } // Allocate locals for used physical registers if (FrameInfo.getStackSize() > 0) MFI.addPReg(WebAssembly::SP32, CurReg++); return true; }
void Mips16FrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); MachineFrameInfo *MFI = MF.getFrameInfo(); const Mips16InstrInfo &TII = *static_cast<const Mips16InstrInfo *>(STI.getInstrInfo()); MachineBasicBlock::iterator MBBI = MBB.begin(); // Debug location must be unknown since the first debug location is used // to determine the end of the prologue. DebugLoc dl; uint64_t StackSize = MFI->getStackSize(); // No need to allocate space on the stack. if (StackSize == 0 && !MFI->adjustsStack()) return; MachineModuleInfo &MMI = MF.getMMI(); const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); MachineLocation DstML, SrcML; // Adjust stack. TII.makeFrame(Mips::SP, StackSize, MBB, MBBI); // emit ".cfi_def_cfa_offset StackSize" unsigned CFIIndex = MMI.addFrameInst( MCCFIInstruction::createDefCfaOffset(nullptr, -StackSize)); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex); const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); if (CSI.size()) { const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(), E = CSI.end(); I != E; ++I) { int64_t Offset = MFI->getObjectOffset(I->getFrameIdx()); unsigned Reg = I->getReg(); unsigned DReg = MRI->getDwarfRegNum(Reg, true); unsigned CFIIndex = MMI.addFrameInst( MCCFIInstruction::createOffset(nullptr, DReg, Offset)); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex); } } if (hasFP(MF)) BuildMI(MBB, MBBI, dl, TII.get(Mips::MoveR3216), Mips::S0) .addReg(Mips::SP).setMIFlag(MachineInstr::FrameSetup); }
bool MipsSEFrameLowering:: spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector<CalleeSavedInfo> &CSI, const TargetRegisterInfo *TRI) const { MachineFunction *MF = MBB.getParent(); MachineBasicBlock *EntryBlock = &MF->front(); const TargetInstrInfo &TII = *STI.getInstrInfo(); for (unsigned i = 0, e = CSI.size(); i != e; ++i) { // Add the callee-saved register as live-in. Do not add if the register is // RA and return address is taken, because it has already been added in // method MipsTargetLowering::LowerRETURNADDR. // It's killed at the spill, unless the register is RA and return address // is taken. unsigned Reg = CSI[i].getReg(); bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64) && MF->getFrameInfo()->isReturnAddressTaken(); if (!IsRAAndRetAddrIsTaken) EntryBlock->addLiveIn(Reg); // ISRs require HI/LO to be spilled into kernel registers to be then // spilled to the stack frame. bool IsLOHI = (Reg == Mips::LO0 || Reg == Mips::LO0_64 || Reg == Mips::HI0 || Reg == Mips::HI0_64); const Function *Func = MBB.getParent()->getFunction(); if (IsLOHI && Func->hasFnAttribute("interrupt")) { DebugLoc DL = MI->getDebugLoc(); unsigned Op = 0; if (!STI.getABI().ArePtrs64bit()) { Op = (Reg == Mips::HI0) ? Mips::MFHI : Mips::MFLO; Reg = Mips::K0; } else { Op = (Reg == Mips::HI0) ? Mips::MFHI64 : Mips::MFLO64; Reg = Mips::K0_64; } BuildMI(MBB, MI, DL, TII.get(Op), Mips::K0) .setMIFlag(MachineInstr::FrameSetup); } // Insert the spill to the stack frame. bool IsKill = !IsRAAndRetAddrIsTaken; const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); TII.storeRegToStackSlot(*EntryBlock, MI, Reg, IsKill, CSI[i].getFrameIdx(), RC, TRI); } return true; }
void X86RetpolineThunks::populateThunk(MachineFunction &MF, unsigned Reg) { // Set MF properties. We never use vregs... MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs); // Grab the entry MBB and erase any other blocks. O0 codegen appears to // generate two bbs for the entry block. MachineBasicBlock *Entry = &MF.front(); Entry->clear(); while (MF.size() > 1) MF.erase(std::next(MF.begin())); MachineBasicBlock *CaptureSpec = MF.CreateMachineBasicBlock(Entry->getBasicBlock()); MachineBasicBlock *CallTarget = MF.CreateMachineBasicBlock(Entry->getBasicBlock()); MCSymbol *TargetSym = MF.getContext().createTempSymbol(); MF.push_back(CaptureSpec); MF.push_back(CallTarget); const unsigned CallOpc = Is64Bit ? X86::CALL64pcrel32 : X86::CALLpcrel32; const unsigned RetOpc = Is64Bit ? X86::RETQ : X86::RETL; Entry->addLiveIn(Reg); BuildMI(Entry, DebugLoc(), TII->get(CallOpc)).addSym(TargetSym); // The MIR verifier thinks that the CALL in the entry block will fall through // to CaptureSpec, so mark it as the successor. Technically, CaptureTarget is // the successor, but the MIR verifier doesn't know how to cope with that. Entry->addSuccessor(CaptureSpec); // In the capture loop for speculation, we want to stop the processor from // speculating as fast as possible. On Intel processors, the PAUSE instruction // will block speculation without consuming any execution resources. On AMD // processors, the PAUSE instruction is (essentially) a nop, so we also use an // LFENCE instruction which they have advised will stop speculation as well // with minimal resource utilization. We still end the capture with a jump to // form an infinite loop to fully guarantee that no matter what implementation // of the x86 ISA, speculating this code path never escapes. BuildMI(CaptureSpec, DebugLoc(), TII->get(X86::PAUSE)); BuildMI(CaptureSpec, DebugLoc(), TII->get(X86::LFENCE)); BuildMI(CaptureSpec, DebugLoc(), TII->get(X86::JMP_1)).addMBB(CaptureSpec); CaptureSpec->setHasAddressTaken(); CaptureSpec->addSuccessor(CaptureSpec); CallTarget->addLiveIn(Reg); CallTarget->setHasAddressTaken(); CallTarget->setAlignment(4); insertRegReturnAddrClobber(*CallTarget, Reg); CallTarget->back().setPreInstrSymbol(MF, TargetSym); BuildMI(CallTarget, DebugLoc(), TII->get(RetOpc)); }
void SparcFrameLowering::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); MachineFrameInfo *MFI = MF.getFrameInfo(); const SparcInstrInfo &TII = *static_cast<const SparcInstrInfo*>(MF.getTarget().getInstrInfo()); MachineBasicBlock::iterator MBBI = MBB.begin(); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); // Get the number of bytes to allocate from the FrameInfo int NumBytes = (int) MFI->getStackSize(); if (SubTarget.is64Bit()) { // All 64-bit stack frames must be 16-byte aligned, and must reserve space // for spilling the 16 window registers at %sp+BIAS..%sp+BIAS+128. NumBytes += 128; // Frames with calls must also reserve space for 6 outgoing arguments // whether they are used or not. LowerCall_64 takes care of that. assert(NumBytes % 16 == 0 && "Stack size not 16-byte aligned"); } else { // Emit the correct save instruction based on the number of bytes in // the frame. Minimum stack frame size according to V8 ABI is: // 16 words for register window spill // 1 word for address of returned aggregate-value // + 6 words for passing parameters on the stack // ---------- // 23 words * 4 bytes per word = 92 bytes NumBytes += 92; // Round up to next doubleword boundary -- a double-word boundary // is required by the ABI. NumBytes = RoundUpToAlignment(NumBytes, 8); } NumBytes = -NumBytes; if (NumBytes >= -4096) { BuildMI(MBB, MBBI, dl, TII.get(SP::SAVEri), SP::O6) .addReg(SP::O6).addImm(NumBytes); } else { // Emit this the hard way. This clobbers G1 which we always know is // available here. unsigned OffHi = (unsigned)NumBytes >> 10U; BuildMI(MBB, MBBI, dl, TII.get(SP::SETHIi), SP::G1).addImm(OffHi); // Emit G1 = G1 + I6 BuildMI(MBB, MBBI, dl, TII.get(SP::ORri), SP::G1) .addReg(SP::G1).addImm(NumBytes & ((1 << 10)-1)); BuildMI(MBB, MBBI, dl, TII.get(SP::SAVErr), SP::O6) .addReg(SP::O6).addReg(SP::G1); } }
// Generates the following sequence for function entry: // st %fp,-4[*%sp] !push old FP // add %sp,8,%fp !generate new FP // sub %sp,0x4,%sp !allocate stack space (as needed) void LanaiFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); MachineFrameInfo *MFI = MF.getFrameInfo(); const LanaiInstrInfo &LII = *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo()); MachineBasicBlock::iterator MBBI = MBB.begin(); // Debug location must be unknown since the first debug location is used // to determine the end of the prologue. DebugLoc DL; // Determine the correct frame layout determineFrameLayout(MF); // FIXME: This appears to be overallocating. Needs investigation. // Get the number of bytes to allocate from the FrameInfo. unsigned StackSize = MFI->getStackSize(); // Push old FP // st %fp,-4[*%sp] BuildMI(MBB, MBBI, DL, LII.get(Lanai::SW_RI)) .addReg(Lanai::FP) .addReg(Lanai::SP) .addImm(-4) .addImm(LPAC::makePreOp(LPAC::ADD)) .setMIFlag(MachineInstr::FrameSetup); // Generate new FP // add %sp,8,%fp BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::FP) .addReg(Lanai::SP) .addImm(8) .setMIFlag(MachineInstr::FrameSetup); // Allocate space on the stack if needed // sub %sp,StackSize,%sp if (StackSize != 0) { BuildMI(MBB, MBBI, DL, LII.get(Lanai::SUB_I_LO), Lanai::SP) .addReg(Lanai::SP) .addImm(StackSize) .setMIFlag(MachineInstr::FrameSetup); } // Replace ADJDYNANALLOC if (MFI->hasVarSizedObjects()) replaceAdjDynAllocPseudo(MF); }
void Mips16FrameLowering::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); MachineFrameInfo *MFI = MF.getFrameInfo(); const Mips16InstrInfo &TII = *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo()); MachineBasicBlock::iterator MBBI = MBB.begin(); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); uint64_t StackSize = MFI->getStackSize(); // No need to allocate space on the stack. if (StackSize == 0 && !MFI->adjustsStack()) return; MachineModuleInfo &MMI = MF.getMMI(); const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); MachineLocation DstML, SrcML; // Adjust stack. TII.makeFrame(Mips::SP, StackSize, MBB, MBBI); // emit ".cfi_def_cfa_offset StackSize" MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel); MMI.addFrameInst( MCCFIInstruction::createDefCfaOffset(AdjustSPLabel, -StackSize)); const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); if (CSI.size()) { MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel); const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(), E = CSI.end(); I != E; ++I) { int64_t Offset = MFI->getObjectOffset(I->getFrameIdx()); unsigned Reg = I->getReg(); unsigned DReg = MRI->getDwarfRegNum(Reg, true); MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, DReg, Offset)); } } if (hasFP(MF)) BuildMI(MBB, MBBI, dl, TII.get(Mips::MoveR3216), Mips::S0) .addReg(Mips::SP); }
// Insert instructions to initialize the Mips16 SP Alias register in the // first MBB of the function. // void Mips16DAGToDAGISel::initMips16SPAliasReg(MachineFunction &MF) { MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); if (!MipsFI->mips16SPAliasRegSet()) return; MachineBasicBlock &MBB = MF.front(); MachineBasicBlock::iterator I = MBB.begin(); const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); unsigned Mips16SPAliasReg = MipsFI->getMips16SPAliasReg(); BuildMI(MBB, I, DL, TII.get(Mips::MoveR3216), Mips16SPAliasReg) .addReg(Mips::SP); }
void SparcFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>(); assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); MachineFrameInfo *MFI = MF.getFrameInfo(); const SparcInstrInfo &TII = *static_cast<const SparcInstrInfo *>(MF.getSubtarget().getInstrInfo()); MachineBasicBlock::iterator MBBI = MBB.begin(); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); // Get the number of bytes to allocate from the FrameInfo int NumBytes = (int) MFI->getStackSize(); unsigned SAVEri = SP::SAVEri; unsigned SAVErr = SP::SAVErr; if (FuncInfo->isLeafProc()) { if (NumBytes == 0) return; SAVEri = SP::ADDri; SAVErr = SP::ADDrr; } NumBytes = -MF.getSubtarget<SparcSubtarget>().getAdjustedFrameSize(NumBytes); emitSPAdjustment(MF, MBB, MBBI, NumBytes, SAVErr, SAVEri); MachineModuleInfo &MMI = MF.getMMI(); const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); unsigned regFP = MRI->getDwarfRegNum(SP::I6, true); // Emit ".cfi_def_cfa_register 30". unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, regFP)); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex); // Emit ".cfi_window_save". CFIIndex = MMI.addFrameInst(MCCFIInstruction::createWindowSave(nullptr)); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex); unsigned regInRA = MRI->getDwarfRegNum(SP::I7, true); unsigned regOutRA = MRI->getDwarfRegNum(SP::O7, true); // Emit ".cfi_register 15, 31". CFIIndex = MMI.addFrameInst( MCCFIInstruction::createRegister(nullptr, regOutRA, regInRA)); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex); }
/// runOnMachineFunction - Loop over all of the basic blocks, inserting /// NOOP instructions before early exits. bool PadShortFunc::runOnMachineFunction(MachineFunction &MF) { if (MF.getFunction()->optForSize()) { return false; } STI = &MF.getSubtarget<X86Subtarget>(); if (!STI->padShortFunctions()) return false; TII = STI->getInstrInfo(); // Search through basic blocks and mark the ones that have early returns ReturnBBs.clear(); VisitedBBs.clear(); findReturns(&MF.front()); bool MadeChange = false; MachineBasicBlock *MBB; unsigned int Cycles = 0; // Pad the identified basic blocks with NOOPs for (DenseMap<MachineBasicBlock*, unsigned int>::iterator I = ReturnBBs.begin(); I != ReturnBBs.end(); ++I) { MBB = I->first; Cycles = I->second; if (Cycles < Threshold) { // BB ends in a return. Skip over any DBG_VALUE instructions // trailing the terminator. assert(MBB->size() > 0 && "Basic block should contain at least a RET but is empty"); MachineBasicBlock::iterator ReturnLoc = --MBB->end(); while (ReturnLoc->isDebugValue()) --ReturnLoc; assert(ReturnLoc->isReturn() && !ReturnLoc->isCall() && "Basic block does not end with RET"); addPadding(MBB, ReturnLoc, Threshold - Cycles); NumBBsPadded++; MadeChange = true; } } return MadeChange; }
void SystemZRegisterInfo::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo(); MachineFrameInfo *MFI = MF.getFrameInfo(); SystemZMachineFunctionInfo *SystemZMFI = MF.getInfo<SystemZMachineFunctionInfo>(); MachineBasicBlock::iterator MBBI = MBB.begin(); DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc::getUnknownLoc()); // Get the number of bytes to allocate from the FrameInfo. // Note that area for callee-saved stuff is already allocated, thus we need to // 'undo' the stack movement. uint64_t StackSize = MFI->getStackSize(); StackSize -= SystemZMFI->getCalleeSavedFrameSize(); uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea(); // Skip the callee-saved push instructions. while (MBBI != MBB.end() && (MBBI->getOpcode() == SystemZ::MOV64mr || MBBI->getOpcode() == SystemZ::MOV64mrm)) ++MBBI; if (MBBI != MBB.end()) DL = MBBI->getDebugLoc(); // adjust stack pointer: R15 -= numbytes if (StackSize || MFI->hasCalls()) { assert(MF.getRegInfo().isPhysRegUsed(SystemZ::R15D) && "Invalid stack frame calculation!"); emitSPUpdate(MBB, MBBI, -(int64_t)NumBytes, TII); } if (hasFP(MF)) { // Update R11 with the new base value... BuildMI(MBB, MBBI, DL, TII.get(SystemZ::MOV64rr), SystemZ::R11D) .addReg(SystemZ::R15D); // Mark the FramePtr as live-in in every block except the entry. for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end(); I != E; ++I) I->addLiveIn(SystemZ::R11D); } }
void Mips16FrameLowering::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); MachineFrameInfo *MFI = MF.getFrameInfo(); const Mips16InstrInfo &TII = *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo()); MachineBasicBlock::iterator MBBI = MBB.begin(); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); uint64_t StackSize = MFI->getStackSize(); // No need to allocate space on the stack. if (StackSize == 0 && !MFI->adjustsStack()) return; MachineModuleInfo &MMI = MF.getMMI(); MachineLocation DstML, SrcML; // Adjust stack. TII.makeFrame(Mips::SP, StackSize, MBB, MBBI); // emit ".cfi_def_cfa_offset StackSize" MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel); DstML = MachineLocation(MachineLocation::VirtualFP); SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize); MMI.addFrameMove(AdjustSPLabel, DstML, SrcML); MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel); DstML = MachineLocation(MachineLocation::VirtualFP, -8); SrcML = MachineLocation(Mips::S1); MMI.addFrameMove(CSLabel, DstML, SrcML); DstML = MachineLocation(MachineLocation::VirtualFP, -12); SrcML = MachineLocation(Mips::S0); MMI.addFrameMove(CSLabel, DstML, SrcML); DstML = MachineLocation(MachineLocation::VirtualFP, -4); SrcML = MachineLocation(Mips::RA); MMI.addFrameMove(CSLabel, DstML, SrcML); if (hasFP(MF)) BuildMI(MBB, MBBI, dl, TII.get(Mips::MoveR3216), Mips::S0) .addReg(Mips::SP); }
void SparcFrameLowering::emitPrologue(MachineFunction &MF) const { SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>(); MachineBasicBlock &MBB = MF.front(); MachineFrameInfo *MFI = MF.getFrameInfo(); const SparcInstrInfo &TII = *static_cast<const SparcInstrInfo*>(MF.getTarget().getInstrInfo()); MachineBasicBlock::iterator MBBI = MBB.begin(); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); // Get the number of bytes to allocate from the FrameInfo int NumBytes = (int) MFI->getStackSize(); unsigned SAVEri = SP::SAVEri; unsigned SAVErr = SP::SAVErr; if (FuncInfo->isLeafProc()) { if (NumBytes == 0) return; SAVEri = SP::ADDri; SAVErr = SP::ADDrr; } NumBytes = - SubTarget.getAdjustedFrameSize(NumBytes); emitSPAdjustment(MF, MBB, MBBI, NumBytes, SAVErr, SAVEri); MachineModuleInfo &MMI = MF.getMMI(); const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, dl, TII.get(SP::PROLOG_LABEL)).addSym(FrameLabel); unsigned regFP = MRI->getDwarfRegNum(SP::I6, true); // Emit ".cfi_def_cfa_register 30". MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(FrameLabel, regFP)); // Emit ".cfi_window_save". MMI.addFrameInst(MCCFIInstruction::createWindowSave(FrameLabel)); unsigned regInRA = MRI->getDwarfRegNum(SP::I7, true); unsigned regOutRA = MRI->getDwarfRegNum(SP::O7, true); // Emit ".cfi_register 15, 31". MMI.addFrameInst(MCCFIInstruction::createRegister(FrameLabel, regOutRA, regInRA)); }
void MBlazeFrameLowering::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); MachineFrameInfo *MFI = MF.getFrameInfo(); const MBlazeInstrInfo &TII = *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo()); MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); MachineBasicBlock::iterator MBBI = MBB.begin(); DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); llvm::CallingConv::ID CallConv = MF.getFunction()->getCallingConv(); bool requiresRA = CallConv == llvm::CallingConv::MBLAZE_INTR; // Determine the correct frame layout determineFrameLayout(MF); // Get the number of bytes to allocate from the FrameInfo. unsigned StackSize = MFI->getStackSize(); // No need to allocate space on the stack. if (StackSize == 0 && !MFI->adjustsStack() && !requiresRA) return; int FPOffset = MBlazeFI->getFPStackOffset(); int RAOffset = MBlazeFI->getRAStackOffset(); // Adjust stack : addi R1, R1, -imm BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADDIK), MBlaze::R1) .addReg(MBlaze::R1).addImm(-StackSize); // swi R15, R1, stack_loc if (MFI->adjustsStack() || requiresRA) { BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI)) .addReg(MBlaze::R15).addReg(MBlaze::R1).addImm(RAOffset); } if (hasFP(MF)) { // swi R19, R1, stack_loc BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI)) .addReg(MBlaze::R19).addReg(MBlaze::R1).addImm(FPOffset); // add R19, R1, R0 BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADD), MBlaze::R19) .addReg(MBlaze::R1).addReg(MBlaze::R0); } }