diff options
Diffstat (limited to 'gnu/llvm/lib/Target/ARC/ARCFrameLowering.cpp')
| -rw-r--r-- | gnu/llvm/lib/Target/ARC/ARCFrameLowering.cpp | 471 |
1 files changed, 0 insertions, 471 deletions
diff --git a/gnu/llvm/lib/Target/ARC/ARCFrameLowering.cpp b/gnu/llvm/lib/Target/ARC/ARCFrameLowering.cpp deleted file mode 100644 index ca59cb2baaa..00000000000 --- a/gnu/llvm/lib/Target/ARC/ARCFrameLowering.cpp +++ /dev/null @@ -1,471 +0,0 @@ -//===- ARCFrameLowering.cpp - ARC Frame Information -------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the ARC implementation of the TargetFrameLowering class. -// -//===----------------------------------------------------------------------===// - -#include "ARCFrameLowering.h" -#include "ARCMachineFunctionInfo.h" -#include "ARCSubtarget.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/RegisterScavenging.h" -#include "llvm/CodeGen/TargetRegisterInfo.h" -#include "llvm/IR/Function.h" -#include "llvm/Support/Debug.h" - -#define DEBUG_TYPE "arc-frame-lowering" - -using namespace llvm; - -static cl::opt<bool> - UseSaveRestoreFunclet("arc-save-restore-funclet", cl::Hidden, - cl::desc("Use arc callee save/restore functions"), - cl::init(true)); - -static const char *store_funclet_name[] = { - "__st_r13_to_r15", "__st_r13_to_r16", "__st_r13_to_r17", "__st_r13_to_r18", - "__st_r13_to_r19", "__st_r13_to_r20", "__st_r13_to_r21", "__st_r13_to_r22", - "__st_r13_to_r23", "__st_r13_to_r24", "__st_r13_to_r25", -}; - -static const char *load_funclet_name[] = { - "__ld_r13_to_r15", "__ld_r13_to_r16", "__ld_r13_to_r17", "__ld_r13_to_r18", - "__ld_r13_to_r19", "__ld_r13_to_r20", "__ld_r13_to_r21", "__ld_r13_to_r22", - "__ld_r13_to_r23", "__ld_r13_to_r24", "__ld_r13_to_r25", -}; - -static void generateStackAdjustment(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MBBI, - const ARCInstrInfo &TII, DebugLoc dl, - int Amount, int StackPtr) { - unsigned AdjOp; - if (!Amount) - return; - bool Positive; - unsigned AbsAmount; - if (Amount < 0) { - AbsAmount = -Amount; - Positive = false; - } else { - AbsAmount = Amount; - Positive = true; - } - - LLVM_DEBUG(dbgs() << "Internal: adjust stack by: " << Amount << "," - << AbsAmount << "\n"); - - assert((AbsAmount % 4 == 0) && "Stack adjustments must be 4-byte aligned."); - if (isUInt<6>(AbsAmount)) - AdjOp = Positive ? ARC::ADD_rru6 : ARC::SUB_rru6; - else - AdjOp = Positive ? ARC::ADD_rrlimm : ARC::SUB_rrlimm; - - BuildMI(MBB, MBBI, dl, TII.get(AdjOp), StackPtr) - .addReg(StackPtr) - .addImm(AbsAmount); -} - -static unsigned -determineLastCalleeSave(const std::vector<CalleeSavedInfo> &CSI) { - unsigned Last = 0; - for (auto Reg : CSI) { - assert(Reg.getReg() >= ARC::R13 && Reg.getReg() <= ARC::R25 && - "Unexpected callee saved reg."); - if (Reg.getReg() > Last) - Last = Reg.getReg(); - } - return Last; -} - -void ARCFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - LLVM_DEBUG(dbgs() << "Determine Callee Saves: " << MF.getName() << "\n"); - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); - SavedRegs.set(ARC::BLINK); -} - -void ARCFrameLowering::adjustStackToMatchRecords( - MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - bool Allocate) const { - MachineFunction &MF = *MBB.getParent(); - int ScalarAlloc = MF.getFrameInfo().getStackSize(); - - if (Allocate) { - // Allocate by adjusting by the negative of what the record holder tracked - // it tracked a positive offset in a downward growing stack. - ScalarAlloc = -ScalarAlloc; - } - - generateStackAdjustment(MBB, MBBI, *ST.getInstrInfo(), DebugLoc(), - ScalarAlloc, ARC::SP); -} - -/// Insert prolog code into the function. -/// For ARC, this inserts a call to a function that puts required callee saved -/// registers onto the stack, when enough callee saved registers are required. -void ARCFrameLowering::emitPrologue(MachineFunction &MF, - MachineBasicBlock &MBB) const { - LLVM_DEBUG(dbgs() << "Emit Prologue: " << MF.getName() << "\n"); - auto *AFI = MF.getInfo<ARCFunctionInfo>(); - MachineModuleInfo &MMI = MF.getMMI(); - MCContext &Context = MMI.getContext(); - const MCRegisterInfo *MRI = Context.getRegisterInfo(); - const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().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; - MachineFrameInfo &MFI = MF.getFrameInfo(); - const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); - unsigned Last = determineLastCalleeSave(CSI); - unsigned StackSlotsUsedByFunclet = 0; - bool SavedBlink = false; - unsigned AlreadyAdjusted = 0; - if (MF.getFunction().isVarArg()) { - // Add in the varargs area here first. - LLVM_DEBUG(dbgs() << "Varargs\n"); - unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex()); - BuildMI(MBB, MBBI, dl, TII->get(ARC::SUB_rru6)) - .addReg(ARC::SP) - .addReg(ARC::SP) - .addImm(VarArgsBytes); - } - if (hasFP(MF)) { - LLVM_DEBUG(dbgs() << "Saving FP\n"); - BuildMI(MBB, MBBI, dl, TII->get(ARC::ST_AW_rs9)) - .addReg(ARC::SP, RegState::Define) - .addReg(ARC::FP) - .addReg(ARC::SP) - .addImm(-4); - AlreadyAdjusted += 4; - } - if (UseSaveRestoreFunclet && Last > ARC::R14) { - LLVM_DEBUG(dbgs() << "Creating store funclet.\n"); - // BL to __save_r13_to_<TRI->getRegAsmName()> - StackSlotsUsedByFunclet = Last - ARC::R12; - BuildMI(MBB, MBBI, dl, TII->get(ARC::PUSH_S_BLINK)); - BuildMI(MBB, MBBI, dl, TII->get(ARC::SUB_rru6)) - .addReg(ARC::SP) - .addReg(ARC::SP) - .addImm(4 * StackSlotsUsedByFunclet); - BuildMI(MBB, MBBI, dl, TII->get(ARC::BL)) - .addExternalSymbol(store_funclet_name[Last - ARC::R15]) - .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill); - AlreadyAdjusted += 4 * (StackSlotsUsedByFunclet + 1); - SavedBlink = true; - } - // If we haven't saved BLINK, but we need to...do that now. - if (MFI.hasCalls() && !SavedBlink) { - LLVM_DEBUG(dbgs() << "Creating save blink.\n"); - BuildMI(MBB, MBBI, dl, TII->get(ARC::PUSH_S_BLINK)); - AlreadyAdjusted += 4; - } - if (AFI->MaxCallStackReq > 0) - MFI.setStackSize(MFI.getStackSize() + AFI->MaxCallStackReq); - // We have already saved some of the stack... - LLVM_DEBUG(dbgs() << "Adjusting stack by: " - << (MFI.getStackSize() - AlreadyAdjusted) << "\n"); - generateStackAdjustment(MBB, MBBI, *ST.getInstrInfo(), dl, - -(MFI.getStackSize() - AlreadyAdjusted), ARC::SP); - - if (hasFP(MF)) { - LLVM_DEBUG(dbgs() << "Setting FP from SP.\n"); - BuildMI(MBB, MBBI, dl, - TII->get(isUInt<6>(MFI.getStackSize()) ? ARC::ADD_rru6 - : ARC::ADD_rrlimm), - ARC::FP) - .addReg(ARC::SP) - .addImm(MFI.getStackSize()); - } - - // Emit CFI records: - // .cfi_def_cfa_offset StackSize - // .cfi_offset fp, -StackSize - // .cfi_offset blink, -StackSize+4 - unsigned CFIIndex = MF.addFrameInst( - MCCFIInstruction::createDefCfaOffset(nullptr, -MFI.getStackSize())); - BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex) - .setMIFlags(MachineInstr::FrameSetup); - - int CurOffset = -4; - if (hasFP(MF)) { - CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( - nullptr, MRI->getDwarfRegNum(ARC::FP, true), CurOffset)); - BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex) - .setMIFlags(MachineInstr::FrameSetup); - CurOffset -= 4; - } - - if (MFI.hasCalls()) { - CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( - nullptr, MRI->getDwarfRegNum(ARC::BLINK, true), CurOffset)); - BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex) - .setMIFlags(MachineInstr::FrameSetup); - } - // CFI for the rest of the registers. - for (const auto &Entry : CSI) { - unsigned Reg = Entry.getReg(); - int FI = Entry.getFrameIdx(); - // Skip BLINK and FP. - if ((hasFP(MF) && Reg == ARC::FP) || (MFI.hasCalls() && Reg == ARC::BLINK)) - continue; - CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( - nullptr, MRI->getDwarfRegNum(Reg, true), MFI.getObjectOffset(FI))); - BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex) - .setMIFlags(MachineInstr::FrameSetup); - } -} - -/// Insert epilog code into the function. -/// For ARC, this inserts a call to a function that restores callee saved -/// registers onto the stack, when enough callee saved registers are required. -void ARCFrameLowering::emitEpilogue(MachineFunction &MF, - MachineBasicBlock &MBB) const { - LLVM_DEBUG(dbgs() << "Emit Epilogue: " << MF.getName() << "\n"); - auto *AFI = MF.getInfo<ARCFunctionInfo>(); - const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo(); - MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator(); - MachineFrameInfo &MFI = MF.getFrameInfo(); - uint64_t StackSize = MF.getFrameInfo().getStackSize(); - bool SavedBlink = false; - unsigned AmountAboveFunclet = 0; - // If we have variable sized frame objects, then we have to move - // the stack pointer to a known spot (fp - StackSize). - // Then, replace the frame pointer by (new) [sp,StackSize-4]. - // Then, move the stack pointer the rest of the way (sp = sp + StackSize). - if (hasFP(MF)) { - BuildMI(MBB, MBBI, DebugLoc(), TII->get(ARC::SUB_rru6), ARC::SP) - .addReg(ARC::FP) - .addImm(StackSize); - AmountAboveFunclet += 4; - } - - // Now, move the stack pointer to the bottom of the save area for the funclet. - const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); - unsigned Last = determineLastCalleeSave(CSI); - unsigned StackSlotsUsedByFunclet = 0; - // Now, restore the callee save registers. - if (UseSaveRestoreFunclet && Last > ARC::R14) { - // BL to __ld_r13_to_<TRI->getRegAsmName()> - StackSlotsUsedByFunclet = Last - ARC::R12; - AmountAboveFunclet += 4 * (StackSlotsUsedByFunclet + 1); - SavedBlink = true; - } - - if (MFI.hasCalls() && !SavedBlink) { - AmountAboveFunclet += 4; - SavedBlink = true; - } - - // Move the stack pointer up to the point of the funclet. - if (StackSize - AmountAboveFunclet) { - BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6)) - .addReg(ARC::SP) - .addReg(ARC::SP) - .addImm(StackSize - AmountAboveFunclet); - } - - if (StackSlotsUsedByFunclet) { - BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::BL)) - .addExternalSymbol(load_funclet_name[Last - ARC::R15]) - .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill); - BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6)) - .addReg(ARC::SP) - .addReg(ARC::SP) - .addImm(4 * (StackSlotsUsedByFunclet)); - } - // Now, pop blink if necessary. - if (SavedBlink) { - BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::POP_S_BLINK)); - } - // Now, pop fp if necessary. - if (hasFP(MF)) { - BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::LD_AB_rs9)) - .addReg(ARC::SP, RegState::Define) - .addReg(ARC::FP, RegState::Define) - .addReg(ARC::SP) - .addImm(4); - } - - // Relieve the varargs area if necessary. - if (MF.getFunction().isVarArg()) { - // Add in the varargs area here first. - LLVM_DEBUG(dbgs() << "Varargs\n"); - unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex()); - BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6)) - .addReg(ARC::SP) - .addReg(ARC::SP) - .addImm(VarArgsBytes); - } -} - -static std::vector<CalleeSavedInfo>::iterator -getSavedReg(std::vector<CalleeSavedInfo> &V, unsigned reg) { - for (auto I = V.begin(), E = V.end(); I != E; ++I) { - if (reg == I->getReg()) - return I; - } - return V.end(); -} - -bool ARCFrameLowering::assignCalleeSavedSpillSlots( - MachineFunction &MF, const TargetRegisterInfo *TRI, - std::vector<CalleeSavedInfo> &CSI) const { - // Use this opportunity to assign the spill slots for all of the potential - // callee save registers (blink, fp, r13->r25) that we care about the - // placement for. We can calculate all of that data here. - int CurOffset = -4; - unsigned Last = determineLastCalleeSave(CSI); - MachineFrameInfo &MFI = MF.getFrameInfo(); - if (hasFP(MF)) { - // Create a fixed slot at for FP - int StackObj = MFI.CreateFixedSpillStackObject(4, CurOffset, true); - LLVM_DEBUG(dbgs() << "Creating fixed object (" << StackObj << ") for FP at " - << CurOffset << "\n"); - (void)StackObj; - CurOffset -= 4; - } - if (MFI.hasCalls() || (UseSaveRestoreFunclet && Last > ARC::R14)) { - // Create a fixed slot for BLINK. - int StackObj = MFI.CreateFixedSpillStackObject(4, CurOffset, true); - LLVM_DEBUG(dbgs() << "Creating fixed object (" << StackObj - << ") for BLINK at " << CurOffset << "\n"); - (void)StackObj; - CurOffset -= 4; - } - - // Create slots for last down to r13. - for (unsigned Which = Last; Which > ARC::R12; Which--) { - auto RegI = getSavedReg(CSI, Which); - if (RegI == CSI.end() || RegI->getFrameIdx() == 0) { - // Always create the stack slot. If for some reason the register isn't in - // the save list, then don't worry about it. - int FI = MFI.CreateFixedSpillStackObject(4, CurOffset, true); - if (RegI != CSI.end()) - RegI->setFrameIdx(FI); - } else - MFI.setObjectOffset(RegI->getFrameIdx(), CurOffset); - CurOffset -= 4; - } - for (auto &I : CSI) { - if (I.getReg() > ARC::R12) - continue; - if (I.getFrameIdx() == 0) { - I.setFrameIdx(MFI.CreateFixedSpillStackObject(4, CurOffset, true)); - LLVM_DEBUG(dbgs() << "Creating fixed object (" << I.getFrameIdx() - << ") for other register at " << CurOffset << "\n"); - } else { - MFI.setObjectOffset(I.getFrameIdx(), CurOffset); - LLVM_DEBUG(dbgs() << "Updating fixed object (" << I.getFrameIdx() - << ") for other register at " << CurOffset << "\n"); - } - CurOffset -= 4; - } - return true; -} - -bool ARCFrameLowering::spillCalleeSavedRegisters( - MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector<CalleeSavedInfo> &CSI, - const TargetRegisterInfo *TRI) const { - LLVM_DEBUG(dbgs() << "Spill callee saved registers: " - << MBB.getParent()->getName() << "\n"); - // There are routines for saving at least 3 registers (r13 to r15, etc.) - unsigned Last = determineLastCalleeSave(CSI); - if (UseSaveRestoreFunclet && Last > ARC::R14) { - // Use setObjectOffset for these registers. - // Needs to be in or before processFunctionBeforeFrameFinalized. - // Or, do assignCalleeSaveSpillSlots? - // Will be handled in prolog. - return true; - } - return false; -} - -bool ARCFrameLowering::restoreCalleeSavedRegisters( - MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - std::vector<CalleeSavedInfo> &CSI, const TargetRegisterInfo *TRI) const { - LLVM_DEBUG(dbgs() << "Restore callee saved registers: " - << MBB.getParent()->getName() << "\n"); - // There are routines for saving at least 3 registers (r13 to r15, etc.) - unsigned Last = determineLastCalleeSave(CSI); - if (UseSaveRestoreFunclet && Last > ARC::R14) { - // Will be handled in epilog. - return true; - } - return false; -} - -// Adjust local variables that are 4-bytes or larger to 4-byte boundary -void ARCFrameLowering::processFunctionBeforeFrameFinalized( - MachineFunction &MF, RegScavenger *RS) const { - const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); - LLVM_DEBUG(dbgs() << "Process function before frame finalized: " - << MF.getName() << "\n"); - MachineFrameInfo &MFI = MF.getFrameInfo(); - LLVM_DEBUG(dbgs() << "Current stack size: " << MFI.getStackSize() << "\n"); - const TargetRegisterClass *RC = &ARC::GPR32RegClass; - if (MFI.hasStackObjects()) { - int RegScavFI = MFI.CreateStackObject( - RegInfo->getSpillSize(*RC), RegInfo->getSpillAlignment(*RC), false); - RS->addScavengingFrameIndex(RegScavFI); - LLVM_DEBUG(dbgs() << "Created scavenging index RegScavFI=" << RegScavFI - << "\n"); - } -} - -static void emitRegUpdate(MachineBasicBlock &MBB, - MachineBasicBlock::iterator &MBBI, DebugLoc dl, - unsigned Reg, int NumBytes, bool IsAdd, - const ARCInstrInfo *TII) { - unsigned Opc = IsAdd ? ARC::ADD_rru6 : ARC::SUB_rru6; - BuildMI(MBB, MBBI, dl, TII->get(Opc), Reg) - .addReg(Reg, RegState::Kill) - .addImm(NumBytes); -} - -MachineBasicBlock::iterator ARCFrameLowering::eliminateCallFramePseudoInstr( - MachineFunction &MF, MachineBasicBlock &MBB, - MachineBasicBlock::iterator I) const { - LLVM_DEBUG(dbgs() << "EmitCallFramePseudo: " << MF.getName() << "\n"); - const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo(); - MachineInstr &Old = *I; - DebugLoc dl = Old.getDebugLoc(); - unsigned Amt = Old.getOperand(0).getImm(); - auto *AFI = MF.getInfo<ARCFunctionInfo>(); - if (!hasFP(MF)) { - if (Amt > AFI->MaxCallStackReq && Old.getOpcode() == ARC::ADJCALLSTACKDOWN) - AFI->MaxCallStackReq = Amt; - } else { - if (Amt != 0) { - assert((Old.getOpcode() == ARC::ADJCALLSTACKDOWN || - Old.getOpcode() == ARC::ADJCALLSTACKUP) && - "Unknown Frame Pseudo."); - bool IsAdd = (Old.getOpcode() == ARC::ADJCALLSTACKUP); - emitRegUpdate(MBB, I, dl, ARC::SP, Amt, IsAdd, TII); - } - } - return MBB.erase(I); -} - -bool ARCFrameLowering::hasFP(const MachineFunction &MF) const { - const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); - bool HasFP = MF.getTarget().Options.DisableFramePointerElim(MF) || - MF.getFrameInfo().hasVarSizedObjects() || - MF.getFrameInfo().isFrameAddressTaken() || - RegInfo->needsStackRealignment(MF); - return HasFP; -} |
