llvm-project/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp
ostannard 4888218d03
[ARM] Do not emit unwind tables when saving LR around outlined call (#69611)
In some cases, the machine outliner needs to preserve LR across an
outlined call by pushing it onto the stack. Previously, this also
generated unwind table instructions, which is incorrect because EHABI
unwind tables cannot represent different stack frames a different points
in the function, so the extra unwind info applied to the entire
function.

The outliner code already avoided generating CFI instructions, but EHABI
unwind data is generated later from the actual instructions, so we need
to avoid using the FrameSetup and FrameDestroy flags to prevent unwind
data being generated.
2023-12-14 14:46:13 +00:00

90 lines
3.2 KiB
C++

//===-- ARMMachineFunctionInfo.cpp - ARM machine function info ------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "ARMMachineFunctionInfo.h"
#include "ARMSubtarget.h"
using namespace llvm;
void ARMFunctionInfo::anchor() {}
yaml::ARMFunctionInfo::ARMFunctionInfo(const llvm::ARMFunctionInfo &MFI)
: LRSpilled(MFI.isLRSpilled()) {}
void yaml::ARMFunctionInfo::mappingImpl(yaml::IO &YamlIO) {
MappingTraits<ARMFunctionInfo>::mapping(YamlIO, *this);
}
void ARMFunctionInfo::initializeBaseYamlFields(
const yaml::ARMFunctionInfo &YamlMFI) {
LRSpilled = YamlMFI.LRSpilled;
}
static bool GetBranchTargetEnforcement(const Function &F,
const ARMSubtarget *Subtarget) {
if (!Subtarget->isMClass() || !Subtarget->hasV7Ops())
return false;
if (!F.hasFnAttribute("branch-target-enforcement")) {
if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
F.getParent()->getModuleFlag("branch-target-enforcement")))
return BTE->getZExtValue();
return false;
}
const StringRef BTIEnable =
F.getFnAttribute("branch-target-enforcement").getValueAsString();
assert(BTIEnable == "true" || BTIEnable == "false");
return BTIEnable == "true";
}
// The pair returns values for the ARMFunctionInfo members
// SignReturnAddress and SignReturnAddressAll respectively.
static std::pair<bool, bool> GetSignReturnAddress(const Function &F) {
if (!F.hasFnAttribute("sign-return-address")) {
const Module &M = *F.getParent();
if (const auto *Sign = mdconst::extract_or_null<ConstantInt>(
M.getModuleFlag("sign-return-address"))) {
if (Sign->getZExtValue()) {
if (const auto *All = mdconst::extract_or_null<ConstantInt>(
M.getModuleFlag("sign-return-address-all")))
return {true, All->getZExtValue()};
return {true, false};
}
}
return {false, false};
}
StringRef Scope = F.getFnAttribute("sign-return-address").getValueAsString();
if (Scope.equals("none"))
return {false, false};
if (Scope.equals("all"))
return {true, true};
assert(Scope.equals("non-leaf"));
return {true, false};
}
ARMFunctionInfo::ARMFunctionInfo(const Function &F,
const ARMSubtarget *Subtarget)
: isThumb(Subtarget->isThumb()), hasThumb2(Subtarget->hasThumb2()),
IsCmseNSEntry(F.hasFnAttribute("cmse_nonsecure_entry")),
IsCmseNSCall(F.hasFnAttribute("cmse_nonsecure_call")),
BranchTargetEnforcement(GetBranchTargetEnforcement(F, Subtarget)) {
if (Subtarget->isMClass() && Subtarget->hasV7Ops())
std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F);
}
MachineFunctionInfo *
ARMFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
const DenseMap<MachineBasicBlock *, MachineBasicBlock *>
&Src2DstMBB) const {
return DestMF.cloneInfo<ARMFunctionInfo>(*this);
}