/// deleted during LiveDebugVariables analysis.
void markUsesInDebugValueAsUndef(unsigned Reg) const;
+ /// Return true if the specified register is modified in this function.
+ /// This checks that no defining machine operands exist for the register or
+ /// any of its aliases. Definitions found on functions marked noreturn are
+ /// ignored.
+ bool isPhysRegModified(unsigned PhysReg) const;
+
//===--------------------------------------------------------------------===//
// Physical Register Use Info
//===--------------------------------------------------------------------===//
/// function. Also check for clobbered aliases and registers clobbered by
/// function calls with register mask operands.
///
- /// This only works after register allocation. It is primarily used by
- /// PrologEpilogInserter to determine which callee-saved registers need
- /// spilling.
+ /// This only works after register allocation.
bool isPhysRegUsed(unsigned Reg) const {
if (UsedPhysRegMask.test(Reg))
return true;
#include <vector>
namespace llvm {
+ class BitVector;
class CalleeSavedInfo;
class MachineFunction;
class RegScavenger;
return 0;
}
- /// processFunctionBeforeCalleeSavedScan - This method is called immediately
- /// before PrologEpilogInserter scans the physical registers used to determine
- /// what callee saved registers should be spilled. This method is optional.
- virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS = nullptr) const {
-
- }
+ /// This method determines which of the registers reported by
+ /// TargetRegisterInfo::getCalleeSavedRegs() should actually get saved.
+ /// The default implementation checks populates the \p SavedRegs bitset with
+ /// all registers which are modified in the function, targets may override
+ /// this function to save additional registers.
+ /// This method also sets up the register scavenger ensuring there is a free
+ /// register or a frameindex available.
+ virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
+ RegScavenger *RS = nullptr) const;
/// processFunctionBeforeFrameFinalized - This method is called immediately
/// before the specified function's frame layout (MF.getFrameInfo()) is
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/IR/Function.h"
#include "llvm/Support/raw_os_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
UseMI->getOperand(0).setReg(0U);
}
}
+
+static const Function *getCalledFunction(const MachineInstr &MI) {
+ for (const MachineOperand &MO : MI.operands()) {
+ if (!MO.isGlobal())
+ continue;
+ const Function *Func = dyn_cast<Function>(MO.getGlobal());
+ if (Func != nullptr)
+ return Func;
+ }
+ return nullptr;
+}
+
+static bool isNoReturnDef(const MachineOperand &MO) {
+ // Anything which is not a noreturn function is a real def.
+ const MachineInstr &MI = *MO.getParent();
+ if (!MI.isCall())
+ return false;
+ const MachineBasicBlock &MBB = *MI.getParent();
+ if (!MBB.succ_empty())
+ return false;
+ const MachineFunction &MF = *MBB.getParent();
+ // We need to keep correct unwind information even if the function will
+ // not return, since the runtime may need it.
+ if (MF.getFunction()->hasFnAttribute(Attribute::UWTable))
+ return false;
+ const Function *Called = getCalledFunction(MI);
+ if (Called == nullptr || !Called->hasFnAttribute(Attribute::NoReturn)
+ || !Called->hasFnAttribute(Attribute::NoUnwind))
+ return false;
+
+ return true;
+}
+
+bool MachineRegisterInfo::isPhysRegModified(unsigned PhysReg) const {
+ if (UsedPhysRegMask.test(PhysReg))
+ return true;
+ const TargetRegisterInfo *TRI = getTargetRegisterInfo();
+ for (MCRegAliasIterator AI(PhysReg, TRI, true); AI.isValid(); ++AI) {
+ for (const MachineOperand &MO : make_range(def_begin(*AI), def_end())) {
+ if (isNoReturnDef(MO))
+ continue;
+ return true;
+ }
+ }
+ return false;
+}
void calculateSets(MachineFunction &Fn);
void calculateCallsInformation(MachineFunction &Fn);
- void calculateCalleeSavedRegisters(MachineFunction &Fn);
+ void assignCalleeSavedSpillSlots(MachineFunction &Fn,
+ const BitVector &SavedRegs);
void insertCSRSpillsAndRestores(MachineFunction &Fn);
void calculateFrameObjectOffsets(MachineFunction &Fn);
void replaceFrameIndices(MachineFunction &Fn);
// instructions.
calculateCallsInformation(Fn);
- // Allow the target machine to make some adjustments to the function
- // e.g. UsedPhysRegs before calculateCalleeSavedRegisters.
- TFI->processFunctionBeforeCalleeSavedScan(Fn, RS);
+ // Determine which of the registers in the callee save list should be saved.
+ BitVector SavedRegs;
+ TFI->determineCalleeSaves(Fn, SavedRegs, RS);
- // Scan the function for modified callee saved registers and insert spill code
- // for any callee saved registers that are modified.
- calculateCalleeSavedRegisters(Fn);
+ // Insert spill code for any callee saved registers that are modified.
+ assignCalleeSavedSpillSlots(Fn, SavedRegs);
// Determine placement of CSR spill/restore code:
// place all spills in the entry block, all restores in return blocks.
}
}
-
-/// calculateCalleeSavedRegisters - Scan the function for modified callee saved
-/// registers.
-void PEI::calculateCalleeSavedRegisters(MachineFunction &F) {
- const TargetRegisterInfo *RegInfo = F.getSubtarget().getRegisterInfo();
- const TargetFrameLowering *TFI = F.getSubtarget().getFrameLowering();
- MachineFrameInfo *MFI = F.getFrameInfo();
-
- // Get the callee saved register list...
- const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&F);
-
+void PEI::assignCalleeSavedSpillSlots(MachineFunction &F,
+ const BitVector &SavedRegs) {
// These are used to keep track the callee-save area. Initialize them.
MinCSFrameIndex = INT_MAX;
MaxCSFrameIndex = 0;
- // Early exit for targets which have no callee saved registers.
- if (!CSRegs || CSRegs[0] == 0)
+ if (SavedRegs.empty())
return;
- // In Naked functions we aren't going to save any registers.
- if (F.getFunction()->hasFnAttribute(Attribute::Naked))
- return;
+ const TargetRegisterInfo *RegInfo = F.getSubtarget().getRegisterInfo();
+ const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&F);
std::vector<CalleeSavedInfo> CSI;
for (unsigned i = 0; CSRegs[i]; ++i) {
unsigned Reg = CSRegs[i];
- // Functions which call __builtin_unwind_init get all their registers saved.
- if (F.getRegInfo().isPhysRegUsed(Reg) || F.getMMI().callsUnwindInit()) {
- // If the reg is modified, save it!
+ if (SavedRegs.test(Reg))
CSI.push_back(CalleeSavedInfo(Reg));
- }
}
+ const TargetFrameLowering *TFI = F.getSubtarget().getFrameLowering();
+ MachineFrameInfo *MFI = F.getFrameInfo();
if (!TFI->assignCalleeSavedSpillSlots(F, RegInfo, CSI)) {
// If target doesn't implement this, use generic code.
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/BitVector.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h"
const MachineFunction &MF) const {
return MF.getFrameInfo()->hasStackObjects();
}
+
+void TargetFrameLowering::determineCalleeSaves(MachineFunction &MF,
+ BitVector &SavedRegs,
+ RegScavenger *RS) const {
+ // Get the callee saved register list...
+ const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
+ const MCPhysReg *CSRegs = TRI.getCalleeSavedRegs(&MF);
+
+ // Early exit if there are no callee saved registers.
+ if (!CSRegs || CSRegs[0] == 0)
+ return;
+
+ SavedRegs.resize(TRI.getNumRegs());
+
+ // In Naked functions we aren't going to save any registers.
+ if (MF.getFunction()->hasFnAttribute(Attribute::Naked))
+ return;
+
+ // Functions which call __builtin_unwind_init get all their registers saved.
+ bool CallsUnwindInit = MF.getMMI().callsUnwindInit();
+ const MachineRegisterInfo &MRI = MF.getRegInfo();
+ for (unsigned i = 0; CSRegs[i]; ++i) {
+ unsigned Reg = CSRegs[i];
+ if (CallsUnwindInit || MRI.isPhysRegModified(Reg))
+ SavedRegs.set(Reg);
+ }
+}
return true;
}
-void AArch64FrameLowering::processFunctionBeforeCalleeSavedScan(
- MachineFunction &MF, RegScavenger *RS) const {
+void AArch64FrameLowering::determineCalleeSaves(MachineFunction &MF,
+ BitVector &SavedRegs,
+ RegScavenger *RS) const {
+ // All calls are tail calls in GHC calling conv, and functions have no
+ // prologue/epilogue.
+ if (MF.getFunction()->getCallingConv() == CallingConv::GHC)
+ return;
+
+ TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
const AArch64RegisterInfo *RegInfo = static_cast<const AArch64RegisterInfo *>(
MF.getSubtarget().getRegisterInfo());
AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
- MachineRegisterInfo *MRI = &MF.getRegInfo();
SmallVector<unsigned, 4> UnspilledCSGPRs;
SmallVector<unsigned, 4> UnspilledCSFPRs;
// The frame record needs to be created by saving the appropriate registers
if (hasFP(MF)) {
- MRI->setPhysRegUsed(AArch64::FP);
- MRI->setPhysRegUsed(AArch64::LR);
+ SavedRegs.set(AArch64::FP);
+ SavedRegs.set(AArch64::LR);
}
// Spill the BasePtr if it's used. Do this first thing so that the
// getCalleeSavedRegs() below will get the right answer.
if (RegInfo->hasBasePointer(MF))
- MRI->setPhysRegUsed(RegInfo->getBaseRegister());
+ SavedRegs.set(RegInfo->getBaseRegister());
if (RegInfo->needsStackRealignment(MF) && !RegInfo->hasBasePointer(MF))
- MRI->setPhysRegUsed(AArch64::X9);
+ SavedRegs.set(AArch64::X9);
// If any callee-saved registers are used, the frame cannot be eliminated.
unsigned NumGPRSpilled = 0;
AArch64::FPR64RegClass.contains(EvenReg)) &&
"Register class mismatch!");
- const bool OddRegUsed = MRI->isPhysRegUsed(OddReg);
- const bool EvenRegUsed = MRI->isPhysRegUsed(EvenReg);
+ const bool OddRegUsed = SavedRegs.test(OddReg);
+ const bool EvenRegUsed = SavedRegs.test(EvenReg);
// Early exit if none of the registers in the register pair is actually
// used.
if (OddRegUsed ^ EvenRegUsed) {
// Find out which register is the additional spill.
Reg = OddRegUsed ? EvenReg : OddReg;
- MRI->setPhysRegUsed(Reg);
+ SavedRegs.set(Reg);
}
DEBUG(dbgs() << ' ' << PrintReg(OddReg, RegInfo));
UnspilledCSGPRs.pop_back();
DEBUG(dbgs() << "Spilling " << PrintReg(Reg, RegInfo)
<< " to get a scratch register.\n");
- MRI->setPhysRegUsed(Reg);
+ SavedRegs.set(Reg);
ExtraCSSpill = true;
++Count;
}
bool hasFP(const MachineFunction &MF) const override;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
- void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS) const override;
+ void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
+ RegScavenger *RS) const override;
};
} // End llvm namespace
// This is bad, if an interrupt is taken after the mov, sp is in an
// inconsistent state.
// Use the first callee-saved register as a scratch register.
- assert(MF.getRegInfo().isPhysRegUsed(ARM::R4) &&
+ assert(!MFI->getPristineRegs(MF).test(ARM::R4) &&
"No scratch register to restore SP from FP!");
emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::R4, FramePtr, -NumBytes,
ARMCC::AL, 0, TII);
// callee-saved vector registers after realigning the stack. The vst1 and vld1
// instructions take alignment hints that can improve performance.
//
-static void checkNumAlignedDPRCS2Regs(MachineFunction &MF) {
+static void
+checkNumAlignedDPRCS2Regs(MachineFunction &MF, BitVector &SavedRegs) {
MF.getInfo<ARMFunctionInfo>()->setNumAlignedDPRCS2Regs(0);
if (!SpillAlignedNEONRegs)
return;
// callee-saved registers in order, but it can happen that there are holes in
// the range. Registers above the hole will be spilled to the standard DPRCS
// area.
- MachineRegisterInfo &MRI = MF.getRegInfo();
unsigned NumSpills = 0;
for (; NumSpills < 8; ++NumSpills)
- if (!MRI.isPhysRegUsed(ARM::D8 + NumSpills))
+ if (!SavedRegs.test(ARM::D8 + NumSpills))
break;
// Don't do this for just one d-register. It's not worth it.
MF.getInfo<ARMFunctionInfo>()->setNumAlignedDPRCS2Regs(NumSpills);
// A scratch register is required for the vst1 / vld1 instructions.
- MF.getRegInfo().setPhysRegUsed(ARM::R4);
+ SavedRegs.set(ARM::R4);
}
-void
-ARMFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS) const {
+void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
+ BitVector &SavedRegs,
+ RegScavenger *RS) const {
+ TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
// This tells PEI to spill the FP as if it is any other callee-save register
// to take advantage the eliminateFrameIndex machinery. This also ensures it
// is spilled in the order specified by getCalleeSavedRegs() to make it easier
// FIXME: It will be better just to find spare register here.
if (AFI->isThumb2Function() &&
(MFI->hasVarSizedObjects() || RegInfo->needsStackRealignment(MF)))
- MRI.setPhysRegUsed(ARM::R4);
+ SavedRegs.set(ARM::R4);
if (AFI->isThumb1OnlyFunction()) {
// Spill LR if Thumb1 function uses variable length argument lists.
if (AFI->getArgRegsSaveSize() > 0)
- MRI.setPhysRegUsed(ARM::LR);
+ SavedRegs.set(ARM::LR);
// Spill R4 if Thumb1 epilogue has to restore SP from FP. We don't know
// for sure what the stack size will be, but for this, an estimate is good
// FIXME: It will be better just to find spare register here.
unsigned StackSize = MFI->estimateStackSize(MF);
if (MFI->hasVarSizedObjects() || StackSize > 508)
- MRI.setPhysRegUsed(ARM::R4);
+ SavedRegs.set(ARM::R4);
}
// See if we can spill vector registers to aligned stack.
- checkNumAlignedDPRCS2Regs(MF);
+ checkNumAlignedDPRCS2Regs(MF, SavedRegs);
// Spill the BasePtr if it's used.
if (RegInfo->hasBasePointer(MF))
- MRI.setPhysRegUsed(RegInfo->getBaseRegister());
+ SavedRegs.set(RegInfo->getBaseRegister());
// Don't spill FP if the frame can be eliminated. This is determined
- // by scanning the callee-save registers to see if any is used.
+ // by scanning the callee-save registers to see if any is modified.
const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&MF);
for (unsigned i = 0; CSRegs[i]; ++i) {
unsigned Reg = CSRegs[i];
bool Spilled = false;
- if (MRI.isPhysRegUsed(Reg)) {
+ if (SavedRegs.test(Reg)) {
Spilled = true;
CanEliminateFrame = false;
}
// If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled.
// Spill LR as well so we can fold BX_RET to the registers restore (LDM).
if (!LRSpilled && CS1Spilled) {
- MRI.setPhysRegUsed(ARM::LR);
+ SavedRegs.set(ARM::LR);
NumGPRSpills++;
SmallVectorImpl<unsigned>::iterator LRPos;
LRPos = std::find(UnspilledCS1GPRs.begin(), UnspilledCS1GPRs.end(),
}
if (hasFP(MF)) {
- MRI.setPhysRegUsed(FramePtr);
+ SavedRegs.set(FramePtr);
auto FPPos = std::find(UnspilledCS1GPRs.begin(), UnspilledCS1GPRs.end(),
FramePtr);
if (FPPos != UnspilledCS1GPRs.end())
// Don't spill high register if the function is thumb
if (!AFI->isThumbFunction() ||
isARMLowRegister(Reg) || Reg == ARM::LR) {
- MRI.setPhysRegUsed(Reg);
+ SavedRegs.set(Reg);
if (!MRI.isReserved(Reg))
ExtraCSSpill = true;
break;
}
} else if (!UnspilledCS2GPRs.empty() && !AFI->isThumb1OnlyFunction()) {
unsigned Reg = UnspilledCS2GPRs.front();
- MRI.setPhysRegUsed(Reg);
+ SavedRegs.set(Reg);
if (!MRI.isReserved(Reg))
ExtraCSSpill = true;
}
}
if (Extras.size() && NumExtras == 0) {
for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
- MRI.setPhysRegUsed(Extras[i]);
+ SavedRegs.set(Extras[i]);
}
} else if (!AFI->isThumb1OnlyFunction()) {
// note: Thumb1 functions spill to R12, not the stack. Reserve a slot
}
if (ForceLRSpill) {
- MRI.setPhysRegUsed(ARM::LR);
+ SavedRegs.set(ARM::LR);
AFI->setLRIsSpilledForFarJump(true);
}
}
unsigned &FrameReg, int SPAdj) const;
int getFrameIndexOffset(const MachineFunction &MF, int FI) const override;
- void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS) const override;
+ void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
+ RegScavenger *RS) const override;
void adjustForSegmentedStacks(MachineFunction &MF,
MachineBasicBlock &MBB) const override;
// frame pointer stack slot, the target is ELF and the function has FP, or
// the target uses var sized objects.
if (NumBytes) {
- assert(MF.getRegInfo().isPhysRegUsed(ARM::R4) &&
+ assert(!MFI->getPristineRegs(MF).test(ARM::R4) &&
"No scratch register to restore SP from FP!");
emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::R4, FramePtr, -NumBytes,
TII, *RegInfo);
void BPFFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {}
-void BPFFrameLowering::processFunctionBeforeCalleeSavedScan(
- MachineFunction &MF, RegScavenger *RS) const {
- MachineRegisterInfo &MRI = MF.getRegInfo();
-
- MRI.setPhysRegUnused(BPF::R6);
- MRI.setPhysRegUnused(BPF::R7);
- MRI.setPhysRegUnused(BPF::R8);
- MRI.setPhysRegUnused(BPF::R9);
+void BPFFrameLowering::determineCalleeSaves(MachineFunction &MF,
+ BitVector &SavedRegs,
+ RegScavenger *RS) const {
+ TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
+ SavedRegs.reset(BPF::R6);
+ SavedRegs.reset(BPF::R7);
+ SavedRegs.reset(BPF::R8);
+ SavedRegs.reset(BPF::R9);
}
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
bool hasFP(const MachineFunction &MF) const override;
- void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS) const override;
+ void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
+ RegScavenger *RS) const override;
void
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
}
-void HexagonFrameLowering::processFunctionBeforeCalleeSavedScan(
- MachineFunction &MF, RegScavenger* RS) const {
+void HexagonFrameLowering::determineCalleeSaves(MachineFunction &MF,
+ BitVector &SavedRegs,
+ RegScavenger *RS) const {
+ TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
+
auto &HST = static_cast<const HexagonSubtarget&>(MF.getSubtarget());
auto &HRI = *HST.getRegisterInfo();
// If we have a function containing __builtin_eh_return we want to spill and
// restore all callee saved registers. Pretend that they are used.
if (HasEHReturn) {
- MachineRegisterInfo &MRI = MF.getRegInfo();
for (const MCPhysReg *CSRegs = HRI.getCalleeSavedRegs(&MF); *CSRegs;
++CSRegs)
- if (!MRI.isPhysRegUsed(*CSRegs))
- MRI.setPhysRegUsed(*CSRegs);
+ SavedRegs.set(*CSRegs);
}
const TargetRegisterClass &RC = Hexagon::IntRegsRegClass;
MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override;
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
RegScavenger *RS = nullptr) const override;
- void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
+ void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
RegScavenger *RS) const override;
bool targetHandlesStackFrameRounding() const override {
return isInt<15>(MFI->getMaxCallFrameSize()) && !MFI->hasVarSizedObjects();
}
-void Mips16FrameLowering::
-processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS) const {
+void Mips16FrameLowering::determineCalleeSaves(MachineFunction &MF,
+ BitVector &SavedRegs,
+ RegScavenger *RS) const {
+ TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
const Mips16InstrInfo &TII =
*static_cast<const Mips16InstrInfo *>(STI.getInstrInfo());
const MipsRegisterInfo &RI = TII.getRegisterInfo();
const BitVector Reserved = RI.getReservedRegs(MF);
bool SaveS2 = Reserved[Mips::S2];
if (SaveS2)
- MF.getRegInfo().setPhysRegUsed(Mips::S2);
+ SavedRegs.set(Mips::S2);
if (hasFP(MF))
- MF.getRegInfo().setPhysRegUsed(Mips::S0);
+ SavedRegs.set(Mips::S0);
}
const MipsFrameLowering *
bool hasReservedCallFrame(const MachineFunction &MF) const override;
- void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS) const override;
+ void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
+ RegScavenger *RS) const override;
};
} // End llvm namespace
!MFI->hasVarSizedObjects();
}
-void MipsSEFrameLowering::
-processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS) const {
- MachineRegisterInfo &MRI = MF.getRegInfo();
+/// Mark \p Reg and all registers aliasing it in the bitset.
+void setAliasRegs(MachineFunction &MF, BitVector &SavedRegs, unsigned Reg) {
+ const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
+ for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
+ SavedRegs.set(*AI);
+}
+
+void MipsSEFrameLowering::determineCalleeSaves(MachineFunction &MF,
+ BitVector &SavedRegs,
+ RegScavenger *RS) const {
+ TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
MipsABIInfo ABI = STI.getABI();
unsigned FP = ABI.GetFramePtr();
// Mark $fp as used if function has dedicated frame pointer.
if (hasFP(MF))
- MRI.setPhysRegUsed(FP);
+ setAliasRegs(MF, SavedRegs, FP);
// Mark $s7 as used if function has dedicated base pointer.
if (hasBP(MF))
- MRI.setPhysRegUsed(BP);
+ setAliasRegs(MF, SavedRegs, BP);
// Create spill slots for eh data registers if function calls eh_return.
if (MipsFI->callsEhReturn())
bool hasReservedCallFrame(const MachineFunction &MF) const override;
- void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS) const override;
+ void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
+ RegScavenger *RS) const override;
unsigned ehDataReg(unsigned I) const;
};
}
}
-void
-PPCFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *) const {
+void PPCFrameLowering::determineCalleeSaves(MachineFunction &MF,
+ BitVector &SavedRegs,
+ RegScavenger *RS) const {
+ TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
+
const PPCRegisterInfo *RegInfo =
static_cast<const PPCRegisterInfo *>(Subtarget.getRegisterInfo());
PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
unsigned LR = RegInfo->getRARegister();
FI->setMustSaveLR(MustSaveLR(MF, LR));
- MachineRegisterInfo &MRI = MF.getRegInfo();
- MRI.setPhysRegUnused(LR);
+ SavedRegs.reset(LR);
// Save R31 if necessary
int FPSI = FI->getFramePointerSaveIndex();
// For 32-bit SVR4, allocate the nonvolatile CR spill slot iff the
// function uses CR 2, 3, or 4.
if (!isPPC64 && !isDarwinABI &&
- (MRI.isPhysRegUsed(PPC::CR2) ||
- MRI.isPhysRegUsed(PPC::CR3) ||
- MRI.isPhysRegUsed(PPC::CR4))) {
+ (SavedRegs.test(PPC::CR2) ||
+ SavedRegs.test(PPC::CR3) ||
+ SavedRegs.test(PPC::CR4))) {
int FrameIdx = MFI->CreateFixedObject((uint64_t)4, (int64_t)-4, true);
FI->setCRSpillFrameIndex(FrameIdx);
}
bool needsFP(const MachineFunction &MF) const;
void replaceFPWithRealFP(MachineFunction &MF) const;
- void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS = nullptr) const override;
+ void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
+ RegScavenger *RS = nullptr) const override;
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
RegScavenger *RS = nullptr) const override;
void addScavengingSpillSlot(MachineFunction &MF, RegScavenger *RS) const;
#endif
}
-void SparcFrameLowering::processFunctionBeforeCalleeSavedScan
- (MachineFunction &MF, RegScavenger *RS) const {
-
+void SparcFrameLowering::determineCalleeSaves(MachineFunction &MF,
+ BitVector &SavedRegs,
+ RegScavenger *RS) const {
+ TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
if (!DisableLeafProc && isLeafProc(MF)) {
SparcMachineFunctionInfo *MFI = MF.getInfo<SparcMachineFunctionInfo>();
MFI->setLeafProc(true);
bool hasReservedCallFrame(const MachineFunction &MF) const override;
bool hasFP(const MachineFunction &MF) const override;
- void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS = nullptr) const override;
+ void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
+ RegScavenger *RS = nullptr) const override;
private:
// Remap input registers to output registers for leaf procedure.
return SpillOffsetTable;
}
-void SystemZFrameLowering::
-processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS) const {
+void SystemZFrameLowering::determineCalleeSaves(MachineFunction &MF,
+ BitVector &SavedRegs,
+ RegScavenger *RS) const {
+ TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
+
MachineFrameInfo *MFFrame = MF.getFrameInfo();
- MachineRegisterInfo &MRI = MF.getRegInfo();
const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
bool HasFP = hasFP(MF);
SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>();
// argument register R6D.
if (IsVarArg)
for (unsigned I = MFI->getVarArgsFirstGPR(); I < SystemZ::NumArgGPRs; ++I)
- MRI.setPhysRegUsed(SystemZ::ArgGPRs[I]);
+ SavedRegs.set(SystemZ::ArgGPRs[I]);
// If the function requires a frame pointer, record that the hard
// frame pointer will be clobbered.
if (HasFP)
- MRI.setPhysRegUsed(SystemZ::R11D);
+ SavedRegs.set(SystemZ::R11D);
// If the function calls other functions, record that the return
// address register will be clobbered.
if (MFFrame->hasCalls())
- MRI.setPhysRegUsed(SystemZ::R14D);
+ SavedRegs.set(SystemZ::R14D);
// If we are saving GPRs other than the stack pointer, we might as well
// save and restore the stack pointer at the same time, via STMG and LMG.
const MCPhysReg *CSRegs = TRI->getCalleeSavedRegs(&MF);
for (unsigned I = 0; CSRegs[I]; ++I) {
unsigned Reg = CSRegs[I];
- if (SystemZ::GR64BitRegClass.contains(Reg) && MRI.isPhysRegUsed(Reg)) {
- MRI.setPhysRegUsed(SystemZ::R15D);
+ if (SystemZ::GR64BitRegClass.contains(Reg) && SavedRegs.test(Reg)) {
+ SavedRegs.set(SystemZ::R15D);
break;
}
}
bool isFPCloseToIncomingSP() const override { return false; }
const SpillSlot *getCalleeSavedSpillSlots(unsigned &NumEntries) const
override;
- void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS) const override;
+ void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
+ RegScavenger *RS) const override;
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
const std::vector<CalleeSavedInfo> &CSI,
return true;
}
-void
-X86FrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS) const {
+void X86FrameLowering::determineCalleeSaves(MachineFunction &MF,
+ BitVector &SavedRegs,
+ RegScavenger *RS) const {
+ TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
+
MachineFrameInfo *MFI = MF.getFrameInfo();
X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
// Spill the BasePtr if it's used.
if (TRI->hasBasePointer(MF))
- MF.getRegInfo().setPhysRegUsed(TRI->getBaseRegister());
+ SavedRegs.set(TRI->getBaseRegister());
}
static bool
void adjustForHiPEPrologue(MachineFunction &MF,
MachineBasicBlock &PrologueMBB) const override;
- void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS = nullptr) const override;
+ void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
+ RegScavenger *RS = nullptr) const override;
bool
assignCalleeSavedSpillSlots(MachineFunction &MF,
MBB.erase(I);
}
-void XCoreFrameLowering::
-processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS) const {
+void XCoreFrameLowering::determineCalleeSaves(MachineFunction &MF,
+ BitVector &SavedRegs,
+ RegScavenger *RS) const {
+ TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
+
XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
- bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR);
+ const MachineRegisterInfo &MRI = MF.getRegInfo();
+ bool LRUsed = MRI.isPhysRegModified(XCore::LR);
if (!LRUsed && !MF.getFunction()->isVarArg() &&
MF.getFrameInfo()->estimateStackSize(MF))
if (LRUsed) {
// We will handle the LR in the prologue/epilogue
// and allocate space on the stack ourselves.
- MF.getRegInfo().setPhysRegUnused(XCore::LR);
+ SavedRegs.reset(XCore::LR);
XFI->createLRSpillSlot(MF);
}
bool hasFP(const MachineFunction &MF) const override;
- void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS = nullptr) const override;
+ void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
+ RegScavenger *RS = nullptr) const override;
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
RegScavenger *RS = nullptr) const override;
define i8* @rt0(i32 %x) nounwind readnone {
entry:
; CHECK-LABEL: rt0:
-; CHECK: {r7, lr}
; CHECK: mov r0, lr
%0 = tail call i8* @llvm.returnaddress(i32 0)
ret i8* %0
define i8* @rt2() nounwind readnone {
entry:
; CHECK-LABEL: rt2:
-; CHECK: {r7, lr}
; CHECK: ldr r[[R0:[0-9]+]], [r7]
-; CHECK: ldr r0, [r0]
-; CHECK: ldr r0, [r0, #4]
+; CHECK: ldr r0, [r[[R0]]]
+; CHECK: ldr r0, [r[[R0]], #4]
%0 = tail call i8* @llvm.returnaddress(i32 2)
ret i8* %0
}