Skip to content

Commit

Permalink
Revert "[ARM][Thumb] Command-line option to ensure AAPCS compliant Fr…
Browse files Browse the repository at this point in the history
…ame Records"

Reverting change due to test failure.

This reverts commit 6119053.
  • Loading branch information
pratlucas committed Jun 13, 2022
1 parent 8325189 commit 33b9ad6
Show file tree
Hide file tree
Showing 16 changed files with 355 additions and 1,273 deletions.
4 changes: 1 addition & 3 deletions clang/include/clang/Driver/Options.td
Expand Up @@ -3467,9 +3467,7 @@ defm aapcs_bitfield_width : BoolOption<"f", "aapcs-bitfield-width",
BothFlags<[NoXarchOption, CC1Option], " the AAPCS standard requirement stating that"
" volatile bit-field width is dictated by the field container type. (ARM only).">>,
Group<m_arm_Features_Group>;
def mframe_chain : Joined<["-"], "mframe-chain=">,
Group<m_arm_Features_Group>, Values<"none,aapcs,aapcs+leaf">,
HelpText<"Select the frame chain model used to emit frame records (Arm only).">;

def mgeneral_regs_only : Flag<["-"], "mgeneral-regs-only">, Group<m_Group>,
HelpText<"Generate code which only uses the general purpose registers (AArch64/x86 only)">;
def mfix_cmse_cve_2021_35465 : Flag<["-"], "mfix-cmse-cve-2021-35465">,
Expand Down
9 changes: 0 additions & 9 deletions clang/lib/Driver/ToolChains/Arch/ARM.cpp
Expand Up @@ -718,15 +718,6 @@ void arm::getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
}
}

// Propagate frame-chain model selection
if (Arg *A = Args.getLastArg(options::OPT_mframe_chain)) {
StringRef FrameChainOption = A->getValue();
if (FrameChainOption.startswith("aapcs"))
Features.push_back("+aapcs-frame-chain");
if (FrameChainOption == "aapcs+leaf")
Features.push_back("+aapcs-frame-chain-leaf");
}

// CMSE: Check for target 8M (for -mcmse to be applicable) is performed later.
if (Args.getLastArg(options::OPT_mcmse))
Features.push_back("+8msecext");
Expand Down
10 changes: 0 additions & 10 deletions llvm/lib/Target/ARM/ARM.td
Expand Up @@ -546,16 +546,6 @@ def FeatureFixCortexA57AES1742098 : SubtargetFeature<"fix-cortex-a57-aes-1742098
"FixCortexA57AES1742098", "true",
"Work around Cortex-A57 Erratum 1742098 / Cortex-A72 Erratum 1655431 (AES)">;

def FeatureAAPCSFrameChain : SubtargetFeature<"aapcs-frame-chain",
"CreateAAPCSFrameChain", "true",
"Create an AAPCS compliant frame chain">;

def FeatureAAPCSFrameChainLeaf : SubtargetFeature<"aapcs-frame-chain-leaf",
"CreateAAPCSFrameChainLeaf", "true",
"Create an AAPCS compliant frame chain "
"for leaf functions",
[FeatureAAPCSFrameChain]>;

//===----------------------------------------------------------------------===//
// ARM architecture class
//
Expand Down
24 changes: 10 additions & 14 deletions llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
Expand Up @@ -63,8 +63,12 @@ const MCPhysReg*
ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
const ARMSubtarget &STI = MF->getSubtarget<ARMSubtarget>();
bool UseSplitPush = STI.splitFramePushPop(*MF);
const Function &F = MF->getFunction();
const MCPhysReg *RegList =
STI.isTargetDarwin()
? CSR_iOS_SaveList
: (UseSplitPush ? CSR_AAPCS_SplitPush_SaveList : CSR_AAPCS_SaveList);

const Function &F = MF->getFunction();
if (F.getCallingConv() == CallingConv::GHC) {
// GHC set of callee saved regs is empty as all those regs are
// used for passing STG regs around
Expand All @@ -76,13 +80,13 @@ ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
} else if (F.getCallingConv() == CallingConv::SwiftTail) {
return STI.isTargetDarwin()
? CSR_iOS_SwiftTail_SaveList
: (UseSplitPush ? CSR_ATPCS_SplitPush_SwiftTail_SaveList
: (UseSplitPush ? CSR_AAPCS_SplitPush_SwiftTail_SaveList
: CSR_AAPCS_SwiftTail_SaveList);
} else if (F.hasFnAttribute("interrupt")) {
if (STI.isMClass()) {
// M-class CPUs have hardware which saves the registers needed to allow a
// function conforming to the AAPCS to function as a handler.
return UseSplitPush ? CSR_ATPCS_SplitPush_SaveList : CSR_AAPCS_SaveList;
return UseSplitPush ? CSR_AAPCS_SplitPush_SaveList : CSR_AAPCS_SaveList;
} else if (F.getFnAttribute("interrupt").getValueAsString() == "FIQ") {
// Fast interrupt mode gives the handler a private copy of R8-R14, so less
// need to be saved to restore user-mode state.
Expand All @@ -99,23 +103,15 @@ ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
if (STI.isTargetDarwin())
return CSR_iOS_SwiftError_SaveList;

return UseSplitPush ? CSR_ATPCS_SplitPush_SwiftError_SaveList :
return UseSplitPush ? CSR_AAPCS_SplitPush_SwiftError_SaveList :
CSR_AAPCS_SwiftError_SaveList;
}

if (STI.isTargetDarwin() && F.getCallingConv() == CallingConv::CXX_FAST_TLS)
return MF->getInfo<ARMFunctionInfo>()->isSplitCSR()
? CSR_iOS_CXX_TLS_PE_SaveList
: CSR_iOS_CXX_TLS_SaveList;

if (STI.isTargetDarwin())
return CSR_iOS_SaveList;

if (UseSplitPush)
return STI.createAAPCSFrameChain() ? CSR_AAPCS_SplitPush_SaveList
: CSR_ATPCS_SplitPush_SaveList;

return CSR_AAPCS_SaveList;
return RegList;
}

const MCPhysReg *ARMBaseRegisterInfo::getCalleeSavedRegsViaCopy(
Expand Down Expand Up @@ -244,7 +240,7 @@ bool ARMBaseRegisterInfo::isInlineAsmReadOnlyReg(const MachineFunction &MF,

BitVector Reserved(getNumRegs());
markSuperRegs(Reserved, ARM::PC);
if (TFI->isFPReserved(MF))
if (TFI->hasFP(MF))
markSuperRegs(Reserved, STI.getFramePointerReg());
if (hasBasePointer(MF))
markSuperRegs(Reserved, BasePtr);
Expand Down
17 changes: 4 additions & 13 deletions llvm/lib/Target/ARM/ARMCallingConv.td
Expand Up @@ -284,8 +284,8 @@ def CSR_AAPCS_SwiftTail : CalleeSavedRegs<(sub CSR_AAPCS, R10)>;
// The order of callee-saved registers needs to match the order we actually push
// them in FrameLowering, because this order is what's used by
// PrologEpilogInserter to allocate frame index slots. So when R7 is the frame
// pointer, we use this ATPCS alternative.
def CSR_ATPCS_SplitPush : CalleeSavedRegs<(add LR, R7, R6, R5, R4,
// pointer, we use this AAPCS alternative.
def CSR_AAPCS_SplitPush : CalleeSavedRegs<(add LR, R7, R6, R5, R4,
R11, R10, R9, R8,
(sequence "D%u", 15, 8))>;

Expand All @@ -294,22 +294,13 @@ def CSR_Win_SplitFP : CalleeSavedRegs<(add R10, R9, R8, R7, R6, R5, R4,
LR, R11)>;

// R8 is used to pass swifterror, remove it from CSR.
def CSR_ATPCS_SplitPush_SwiftError : CalleeSavedRegs<(sub CSR_ATPCS_SplitPush,
def CSR_AAPCS_SplitPush_SwiftError : CalleeSavedRegs<(sub CSR_AAPCS_SplitPush,
R8)>;

// R10 is used to pass swifterror, remove it from CSR.
def CSR_ATPCS_SplitPush_SwiftTail : CalleeSavedRegs<(sub CSR_ATPCS_SplitPush,
def CSR_AAPCS_SplitPush_SwiftTail : CalleeSavedRegs<(sub CSR_AAPCS_SplitPush,
R10)>;

// When enforcing an AAPCS compliant frame chain, R11 is used as the frame
// pointer even for Thumb targets, where split pushes are necessary.
// This AAPCS alternative makes sure the frame index slots match the push
// order in that case.
def CSR_AAPCS_SplitPush : CalleeSavedRegs<(add LR, R11,
R7, R6, R5, R4,
R10, R9, R8,
(sequence "D%u", 15, 8))>;

// Constructors and destructors return 'this' in the ARM C++ ABI; since 'this'
// and the pointer return value are both passed in R0 in these cases, this can
// be partially modelled by treating R0 as a callee-saved register
Expand Down
59 changes: 6 additions & 53 deletions llvm/lib/Target/ARM/ARMFrameLowering.cpp
Expand Up @@ -47,8 +47,7 @@
// | |
// |-----------------------------------|
// | |
// | prev_lr |
// | prev_fp |
// | prev_fp, prev_lr |
// | (a.k.a. "frame record") |
// | |
// |- - - - - - - - - - - - - - - - - -| <- fp (r7 or r11)
Expand Down Expand Up @@ -212,12 +211,6 @@ bool ARMFrameLowering::hasFP(const MachineFunction &MF) const {
MFI.isFrameAddressTaken());
}

/// isFPReserved - Return true if the frame pointer register should be
/// considered a reserved register on the scope of the specified function.
bool ARMFrameLowering::isFPReserved(const MachineFunction &MF) const {
return hasFP(MF) || MF.getSubtarget<ARMSubtarget>().createAAPCSFrameChain();
}

/// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
/// not required, we reserve argument space for call sites in the function
/// immediately on entry to the current function. This eliminates the need for
Expand Down Expand Up @@ -1040,9 +1033,6 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
// into spill area 1, including the FP in R11. In either case, it
// is in area one and the adjustment needs to take place just after
// that push.
// FIXME: The above is not necessary true when PACBTI is enabled.
// AAPCS requires use of R11, and PACBTI gets in the way of regular pushes,
// so FP ends up on area two.
MachineBasicBlock::iterator AfterPush;
if (HasFP) {
AfterPush = std::next(GPRCS1Push);
Expand Down Expand Up @@ -2206,34 +2196,6 @@ bool ARMFrameLowering::enableShrinkWrapping(const MachineFunction &MF) const {
return true;
}

static bool requiresAAPCSFrameRecord(const MachineFunction &MF) {
const auto &Subtarget = MF.getSubtarget<ARMSubtarget>();
return Subtarget.createAAPCSFrameChainLeaf() ||
(Subtarget.createAAPCSFrameChain() && MF.getFrameInfo().hasCalls());
}

// Thumb1 may require a spill when storing to a frame index through FP, for
// cases where FP is a high register (R11). This scans the function for cases
// where this may happen.
static bool canSpillOnFrameIndexAccess(const MachineFunction &MF,
const TargetFrameLowering &TFI) {
const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
if (!AFI->isThumb1OnlyFunction())
return false;

for (const auto &MBB : MF)
for (const auto &MI : MBB)
if (MI.getOpcode() == ARM::tSTRspi || MI.getOpcode() == ARM::tSTRi)
for (const auto &Op : MI.operands())
if (Op.isFI()) {
Register Reg;
TFI.getFrameIndexReference(MF, Op.getIndex(), Reg);
if (ARM::hGPRRegClass.contains(Reg) && Reg != ARM::SP)
return true;
}
return false;
}

void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
BitVector &SavedRegs,
RegScavenger *RS) const {
Expand All @@ -2242,7 +2204,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
// to take advantage the eliminateFrameIndex machinery. This also ensures it
// is spilled in the order specified by getCalleeSavedRegs() to make it easier
// to combine multiple loads / stores.
bool CanEliminateFrame = !(requiresAAPCSFrameRecord(MF) && hasFP(MF));
bool CanEliminateFrame = true;
bool CS1Spilled = false;
bool LRSpilled = false;
unsigned NumGPRSpills = 0;
Expand Down Expand Up @@ -2437,11 +2399,6 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
// Functions with VLAs or extremely large call frames are rare, and
// if a function is allocating more than 1KB of stack, an extra 4-byte
// slot probably isn't relevant.
//
// A special case is the scenario where r11 is used as FP, where accesses
// to a frame index will require its value to be moved into a low reg.
// This is handled later on, once we are able to determine if we have any
// fp-relative accesses.
if (RegInfo->hasBasePointer(MF))
EstimatedRSStackSizeLimit = (1U << 5) * 4;
else
Expand Down Expand Up @@ -2488,9 +2445,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
SavedRegs.set(FramePtr);
// If the frame pointer is required by the ABI, also spill LR so that we
// emit a complete frame record.
if ((requiresAAPCSFrameRecord(MF) ||
MF.getTarget().Options.DisableFramePointerElim(MF)) &&
!LRSpilled) {
if (MF.getTarget().Options.DisableFramePointerElim(MF) && !LRSpilled) {
SavedRegs.set(ARM::LR);
LRSpilled = true;
NumGPRSpills++;
Expand Down Expand Up @@ -2572,7 +2527,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
}

// r7 can be used if it is not being used as the frame pointer.
if (!HasFP || FramePtr != ARM::R7) {
if (!HasFP) {
if (SavedRegs.test(ARM::R7)) {
--RegDeficit;
LLVM_DEBUG(dbgs() << "%r7 is saved low register, RegDeficit = "
Expand Down Expand Up @@ -2693,10 +2648,8 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
// to materialize a stack offset. If so, either spill one additional
// callee-saved register or reserve a special spill slot to facilitate
// register scavenging. Thumb1 needs a spill slot for stack pointer
// adjustments and for frame index accesses when FP is high register,
// even when the frame itself is small.
if (!ExtraCSSpill &&
(BigFrameOffsets || canSpillOnFrameIndexAccess(MF, *this))) {
// adjustments also, even when the frame itself is small.
if (BigFrameOffsets && !ExtraCSSpill) {
// If any non-reserved CS register isn't spilled, just spill one or two
// extra. That should take care of it!
unsigned NumExtras = TargetAlign.value() / 4;
Expand Down
1 change: 0 additions & 1 deletion llvm/lib/Target/ARM/ARMFrameLowering.h
Expand Up @@ -46,7 +46,6 @@ class ARMFrameLowering : public TargetFrameLowering {
bool enableCalleeSaveSkip(const MachineFunction &MF) const override;

bool hasFP(const MachineFunction &MF) const override;
bool isFPReserved(const MachineFunction &MF) const;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override;
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
Expand Down
3 changes: 0 additions & 3 deletions llvm/lib/Target/ARM/ARMMachineFunctionInfo.h
Expand Up @@ -86,7 +86,6 @@ class ARMFunctionInfo : public MachineFunctionInfo {
/// GPRCS1Size, GPRCS2Size, DPRCSSize - Sizes of callee saved register spills
/// areas.
unsigned FPCXTSaveSize = 0;
unsigned FRSaveSize = 0;
unsigned GPRCS1Size = 0;
unsigned GPRCS2Size = 0;
unsigned DPRCSAlignGapSize = 0;
Expand Down Expand Up @@ -204,14 +203,12 @@ class ARMFunctionInfo : public MachineFunctionInfo {
void setDPRCalleeSavedAreaOffset(unsigned o) { DPRCSOffset = o; }

unsigned getFPCXTSaveAreaSize() const { return FPCXTSaveSize; }
unsigned getFrameRecordSavedAreaSize() const { return FRSaveSize; }
unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size; }
unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size; }
unsigned getDPRCalleeSavedGapSize() const { return DPRCSAlignGapSize; }
unsigned getDPRCalleeSavedAreaSize() const { return DPRCSSize; }

void setFPCXTSaveAreaSize(unsigned s) { FPCXTSaveSize = s; }
void setFrameRecordSavedAreaSize(unsigned s) { FRSaveSize = s; }
void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; }
void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; }
void setDPRCalleeSavedGapSize(unsigned s) { DPRCSAlignGapSize = s; }
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/Target/ARM/ARMSubtarget.h
Expand Up @@ -430,8 +430,7 @@ class ARMSubtarget : public ARMGenSubtargetInfo {
}

MCPhysReg getFramePointerReg() const {
if (isTargetDarwin() ||
(!isTargetWindows() && isThumb() && !createAAPCSFrameChain()))
if (isTargetDarwin() || (!isTargetWindows() && isThumb()))
return ARM::R7;
return ARM::R11;
}
Expand Down

0 comments on commit 33b9ad6

Please sign in to comment.