summaryrefslogtreecommitdiff
path: root/lib/Target/ARM/ARMFrameLowering.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
commit044eb2f6afba375a914ac9d8024f8f5142bb912e (patch)
tree1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /lib/Target/ARM/ARMFrameLowering.cpp
parenteb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff)
Notes
Diffstat (limited to 'lib/Target/ARM/ARMFrameLowering.cpp')
-rw-r--r--lib/Target/ARM/ARMFrameLowering.cpp120
1 files changed, 69 insertions, 51 deletions
diff --git a/lib/Target/ARM/ARMFrameLowering.cpp b/lib/Target/ARM/ARMFrameLowering.cpp
index 00b788a1b530..4ff864ac6ccd 100644
--- a/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/lib/Target/ARM/ARMFrameLowering.cpp
@@ -1,4 +1,4 @@
-//===-- ARMFrameLowering.cpp - ARM Frame Information ----------------------===//
+//===- ARMFrameLowering.cpp - ARM Frame Information -----------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,6 +19,7 @@
#include "ARMSubtarget.h"
#include "MCTargetDesc/ARMAddressingModes.h"
#include "MCTargetDesc/ARMBaseInfo.h"
+#include "Utils/ARMBaseInfo.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -33,12 +34,17 @@
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetOpcodes.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Function.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/CommandLine.h"
@@ -47,11 +53,8 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
@@ -200,10 +203,10 @@ static int sizeOfSPAdjustment(const MachineInstr &MI) {
static bool WindowsRequiresStackProbe(const MachineFunction &MF,
size_t StackSizeInBytes) {
const MachineFrameInfo &MFI = MF.getFrameInfo();
- const Function *F = MF.getFunction();
+ const Function &F = MF.getFunction();
unsigned StackProbeSize = (MFI.getStackProtectorIndex() > 0) ? 4080 : 4096;
- if (F->hasFnAttribute("stack-probe-size"))
- F->getFnAttribute("stack-probe-size")
+ if (F.hasFnAttribute("stack-probe-size"))
+ F.getFnAttribute("stack-probe-size")
.getValueAsString()
.getAsInteger(0, StackProbeSize);
return StackSizeInBytes >= StackProbeSize;
@@ -367,7 +370,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
// All calls are tail calls in GHC calling conv, and functions have no
// prologue/epilogue.
- if (MF.getFunction()->getCallingConv() == CallingConv::GHC)
+ if (MF.getFunction().getCallingConv() == CallingConv::GHC)
return;
StackAdjustingInsts DefCFAOffsetCandidates;
@@ -445,7 +448,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
int FramePtrOffsetInPush = 0;
if (HasFP) {
int FPOffset = MFI.getObjectOffset(FramePtrSpillFI);
- assert(getMaxFPOffset(*MF.getFunction(), *AFI) <= FPOffset &&
+ assert(getMaxFPOffset(MF.getFunction(), *AFI) <= FPOffset &&
"Max FP estimation is wrong");
FramePtrOffsetInPush = FPOffset + ArgRegsSaveSize;
AFI->setFramePtrSpillOffset(MFI.getObjectOffset(FramePtrSpillFI) +
@@ -512,7 +515,6 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
switch (TM.getCodeModel()) {
case CodeModel::Small:
case CodeModel::Medium:
- case CodeModel::Default:
case CodeModel::Kernel:
BuildMI(MBB, MBBI, dl, TII.get(ARM::tBL))
.add(predOps(ARMCC::AL))
@@ -521,7 +523,6 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
.setMIFlags(MachineInstr::FrameSetup);
break;
case CodeModel::Large:
- case CodeModel::JITDefault:
BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi32imm), ARM::R12)
.addExternalSymbol("__chkstk")
.setMIFlags(MachineInstr::FrameSetup);
@@ -765,7 +766,7 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
// All calls are tail calls in GHC calling conv, and functions have no
// prologue/epilogue.
- if (MF.getFunction()->getCallingConv() == CallingConv::GHC)
+ if (MF.getFunction().getCallingConv() == CallingConv::GHC)
return;
// First put ourselves on the first (from top) terminator instructions.
@@ -955,7 +956,8 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB,
DebugLoc DL;
- typedef std::pair<unsigned, bool> RegAndKill;
+ using RegAndKill = std::pair<unsigned, bool>;
+
SmallVector<RegAndKill, 4> Regs;
unsigned i = CSI.size();
while (i != 0) {
@@ -1021,7 +1023,7 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB,
void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI,
+ std::vector<CalleeSavedInfo> &CSI,
unsigned LdmOpc, unsigned LdrOpc,
bool isVarArg, bool NoGap,
bool(*Func)(unsigned, bool),
@@ -1051,7 +1053,8 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
unsigned LastReg = 0;
bool DeleteRet = false;
for (; i != 0; --i) {
- unsigned Reg = CSI[i-1].getReg();
+ CalleeSavedInfo &Info = CSI[i-1];
+ unsigned Reg = Info.getReg();
if (!(Func)(Reg, STI.splitFramePushPop(MF))) continue;
// The aligned reloads from area DPRCS2 are not inserted here.
@@ -1064,6 +1067,9 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
Reg = ARM::PC;
DeleteRet = true;
LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET;
+ // We 'restore' LR into PC so it is not live out of the return block:
+ // Clear Restored bit.
+ Info.setRestored(false);
} else
LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_UPD : ARM::LDMIA_UPD;
// Fold the return instruction into the LDM.
@@ -1092,9 +1098,11 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
.add(predOps(ARMCC::AL));
for (unsigned i = 0, e = Regs.size(); i < e; ++i)
MIB.addReg(Regs[i], getDefRegState(true));
- if (DeleteRet && MI != MBB.end()) {
- MIB.copyImplicitOps(*MI);
- MI->eraseFromParent();
+ if (DeleteRet) {
+ if (MI != MBB.end()) {
+ MIB.copyImplicitOps(*MI);
+ MI->eraseFromParent();
+ }
}
MI = MIB;
} else if (Regs.size() == 1) {
@@ -1283,9 +1291,11 @@ skipAlignedDPRCS2Spills(MachineBasicBlock::iterator MI,
case 7:
++MI;
assert(MI->mayStore() && "Expecting spill instruction");
+ LLVM_FALLTHROUGH;
default:
++MI;
assert(MI->mayStore() && "Expecting spill instruction");
+ LLVM_FALLTHROUGH;
case 1:
case 2:
case 4:
@@ -1421,7 +1431,7 @@ bool ARMFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
bool ARMFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI,
+ std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const {
if (CSI.empty())
return false;
@@ -1516,7 +1526,6 @@ static unsigned estimateRSStackSizeLimit(MachineFunction &MF,
// In functions that realign the stack, it can be an advantage to spill the
// 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, BitVector &SavedRegs) {
MF.getInfo<ARMFunctionInfo>()->setNumAlignedDPRCS2Regs(0);
@@ -1524,7 +1533,7 @@ checkNumAlignedDPRCS2Regs(MachineFunction &MF, BitVector &SavedRegs) {
return;
// Naked functions don't spill callee-saved registers.
- if (MF.getFunction()->hasFnAttribute(Attribute::Naked))
+ if (MF.getFunction().hasFnAttribute(Attribute::Naked))
return;
// We are planning to use NEON instructions vst1 / vld1.
@@ -1601,14 +1610,14 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
if (AFI->getArgRegsSaveSize() > 0)
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
- // enough. If there anything changes it, it'll be a spill, which implies
- // we've used all the registers and so R4 is already used, so not marking
- // it here will be OK.
+ // Spill R4 if Thumb1 epilogue has to restore SP from FP or the function
+ // requires stack alignment. We don't know for sure what the stack size
+ // will be, but for this, an estimate is good enough. If there anything
+ // changes it, it'll be a spill, which implies we've used all the registers
+ // and so R4 is already used, so not marking it here will be OK.
// FIXME: It will be better just to find spare register here.
- unsigned StackSize = MFI.estimateStackSize(MF);
- if (MFI.hasVarSizedObjects() || StackSize > 508)
+ if (MFI.hasVarSizedObjects() || RegInfo->needsStackRealignment(MF) ||
+ MFI.estimateStackSize(MF) > 508)
SavedRegs.set(ARM::R4);
}
@@ -1735,13 +1744,12 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
EstimatedStackSize += 16; // For possible paddings.
unsigned EstimatedRSStackSizeLimit = estimateRSStackSizeLimit(MF, this);
- int MaxFPOffset = getMaxFPOffset(*MF.getFunction(), *AFI);
+ int MaxFPOffset = getMaxFPOffset(MF.getFunction(), *AFI);
bool BigFrameOffsets = EstimatedStackSize >= EstimatedRSStackSizeLimit ||
MFI.hasVarSizedObjects() ||
(MFI.adjustsStack() && !canSimplifyCallFramePseudos(MF)) ||
// For large argument stacks fp relative addressed may overflow.
(HasFP && (MaxFixedOffset - MaxFPOffset) >= (int)EstimatedRSStackSizeLimit);
- bool ExtraCSSpill = false;
if (BigFrameOffsets ||
!CanEliminateFrame || RegInfo->cannotEliminateFrame(MF)) {
AFI->setHasStackFrame(true);
@@ -1766,6 +1774,10 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
CS1Spilled = true;
}
+ // This is true when we inserted a spill for an unused register that can now
+ // be used for register scavenging.
+ bool ExtraCSSpill = false;
+
if (AFI->isThumb1OnlyFunction()) {
// For Thumb1-only targets, we need some low registers when we save and
// restore the high registers (which aren't allocatable, but could be
@@ -1785,7 +1797,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
for (unsigned Reg : {ARM::R0, ARM::R1, ARM::R2, ARM::R3}) {
if (!MF.getRegInfo().isLiveIn(Reg)) {
--EntryRegDeficit;
- DEBUG(dbgs() << PrintReg(Reg, TRI)
+ DEBUG(dbgs() << printReg(Reg, TRI)
<< " is unused argument register, EntryRegDeficit = "
<< EntryRegDeficit << "\n");
}
@@ -1805,13 +1817,13 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
for (unsigned Reg : {ARM::R4, ARM::R5, ARM::R6}) {
if (SavedRegs.test(Reg)) {
--RegDeficit;
- DEBUG(dbgs() << PrintReg(Reg, TRI)
+ DEBUG(dbgs() << printReg(Reg, TRI)
<< " is saved low register, RegDeficit = " << RegDeficit
<< "\n");
} else {
AvailableRegs.push_back(Reg);
DEBUG(dbgs()
- << PrintReg(Reg, TRI)
+ << printReg(Reg, TRI)
<< " is non-saved low register, adding to AvailableRegs\n");
}
}
@@ -1820,12 +1832,12 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
if (!HasFP) {
if (SavedRegs.test(ARM::R7)) {
--RegDeficit;
- DEBUG(dbgs() << "%R7 is saved low register, RegDeficit = "
+ DEBUG(dbgs() << "%r7 is saved low register, RegDeficit = "
<< RegDeficit << "\n");
} else {
AvailableRegs.push_back(ARM::R7);
DEBUG(dbgs()
- << "%R7 is non-saved low register, adding to AvailableRegs\n");
+ << "%r7 is non-saved low register, adding to AvailableRegs\n");
}
}
@@ -1833,7 +1845,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
for (unsigned Reg : {ARM::R8, ARM::R9, ARM::R10, ARM::R11}) {
if (SavedRegs.test(Reg)) {
++RegDeficit;
- DEBUG(dbgs() << PrintReg(Reg, TRI)
+ DEBUG(dbgs() << printReg(Reg, TRI)
<< " is saved high register, RegDeficit = " << RegDeficit
<< "\n");
}
@@ -1847,11 +1859,11 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
MF.getFrameInfo().isReturnAddressTaken())) {
if (SavedRegs.test(ARM::LR)) {
--RegDeficit;
- DEBUG(dbgs() << "%LR is saved register, RegDeficit = " << RegDeficit
+ DEBUG(dbgs() << "%lr is saved register, RegDeficit = " << RegDeficit
<< "\n");
} else {
AvailableRegs.push_back(ARM::LR);
- DEBUG(dbgs() << "%LR is not saved, adding to AvailableRegs\n");
+ DEBUG(dbgs() << "%lr is not saved, adding to AvailableRegs\n");
}
}
@@ -1863,12 +1875,14 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
DEBUG(dbgs() << "Final RegDeficit = " << RegDeficit << "\n");
for (; RegDeficit > 0 && !AvailableRegs.empty(); --RegDeficit) {
unsigned Reg = AvailableRegs.pop_back_val();
- DEBUG(dbgs() << "Spilling " << PrintReg(Reg, TRI)
+ DEBUG(dbgs() << "Spilling " << printReg(Reg, TRI)
<< " to make up reg deficit\n");
SavedRegs.set(Reg);
NumGPRSpills++;
CS1Spilled = true;
- ExtraCSSpill = true;
+ assert(!MRI.isReserved(Reg) && "Should not be reserved");
+ if (!MRI.isPhysRegUsed(Reg))
+ ExtraCSSpill = true;
UnspilledCS1GPRs.erase(llvm::find(UnspilledCS1GPRs, Reg));
if (Reg == ARM::LR)
LRSpilled = true;
@@ -1887,7 +1901,8 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
UnspilledCS1GPRs.erase(LRPos);
ForceLRSpill = false;
- ExtraCSSpill = true;
+ if (!MRI.isReserved(ARM::LR) && !MRI.isPhysRegUsed(ARM::LR))
+ ExtraCSSpill = true;
}
// If stack and double are 8-byte aligned and we are spilling an odd number
@@ -1905,9 +1920,9 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
(STI.isTargetWindows() && Reg == ARM::R11) ||
isARMLowRegister(Reg) || Reg == ARM::LR) {
SavedRegs.set(Reg);
- DEBUG(dbgs() << "Spilling " << PrintReg(Reg, TRI)
+ DEBUG(dbgs() << "Spilling " << printReg(Reg, TRI)
<< " to make up alignment\n");
- if (!MRI.isReserved(Reg))
+ if (!MRI.isReserved(Reg) && !MRI.isPhysRegUsed(Reg))
ExtraCSSpill = true;
break;
}
@@ -1915,9 +1930,9 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
} else if (!UnspilledCS2GPRs.empty() && !AFI->isThumb1OnlyFunction()) {
unsigned Reg = UnspilledCS2GPRs.front();
SavedRegs.set(Reg);
- DEBUG(dbgs() << "Spilling " << PrintReg(Reg, TRI)
+ DEBUG(dbgs() << "Spilling " << printReg(Reg, TRI)
<< " to make up alignment\n");
- if (!MRI.isReserved(Reg))
+ if (!MRI.isReserved(Reg) && !MRI.isPhysRegUsed(Reg))
ExtraCSSpill = true;
}
}
@@ -1953,11 +1968,14 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
}
}
}
- if (Extras.size() && NumExtras == 0) {
- for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
- SavedRegs.set(Extras[i]);
+ if (NumExtras == 0) {
+ for (unsigned Reg : Extras) {
+ SavedRegs.set(Reg);
+ if (!MRI.isPhysRegUsed(Reg))
+ ExtraCSSpill = true;
}
- } else if (!AFI->isThumb1OnlyFunction()) {
+ }
+ if (!ExtraCSSpill && !AFI->isThumb1OnlyFunction()) {
// note: Thumb1 functions spill to R12, not the stack. Reserve a slot
// closest to SP or frame pointer.
assert(RS && "Register scavenging not provided");
@@ -2084,7 +2102,7 @@ void ARMFrameLowering::adjustForSegmentedStacks(
// Sadly, this currently doesn't support varargs, platforms other than
// android/linux. Note that thumb1/thumb2 are support for android/linux.
- if (MF.getFunction()->isVarArg())
+ if (MF.getFunction().isVarArg())
report_fatal_error("Segmented stacks do not support vararg functions.");
if (!ST->isTargetAndroid() && !ST->isTargetLinux())
report_fatal_error("Segmented stacks not supported on this platform.");
@@ -2232,7 +2250,7 @@ void ARMFrameLowering::adjustForSegmentedStacks(
if (Thumb && ST->isThumb1Only()) {
unsigned PCLabelId = ARMFI->createPICLabelUId();
ARMConstantPoolValue *NewCPV = ARMConstantPoolSymbol::Create(
- MF.getFunction()->getContext(), "__STACK_LIMIT", PCLabelId, 0);
+ MF.getFunction().getContext(), "__STACK_LIMIT", PCLabelId, 0);
MachineConstantPool *MCP = MF.getConstantPool();
unsigned CPI = MCP->getConstantPoolIndex(NewCPV, 4);