summaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm16/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
diff options
context:
space:
mode:
authorvvvv <[email protected]>2024-02-06 20:01:22 +0300
committervvvv <[email protected]>2024-02-06 20:22:16 +0300
commit0203b7a9a40828bb2bd4c32029b79ff0ea3d1f8f (patch)
treee630d0d5bd0bd29fc8c2d2842ed2cfde781b993a /contrib/libs/llvm16/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
parentba27db76d99d12a4f1c06960b5449423218614c4 (diff)
llvm16 targets
Diffstat (limited to 'contrib/libs/llvm16/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp')
-rw-r--r--contrib/libs/llvm16/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp153
1 files changed, 153 insertions, 0 deletions
diff --git a/contrib/libs/llvm16/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp b/contrib/libs/llvm16/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
new file mode 100644
index 00000000000..961a19317d6
--- /dev/null
+++ b/contrib/libs/llvm16/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
@@ -0,0 +1,153 @@
+//=- AArch64MachineFunctionInfo.cpp - AArch64 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements AArch64-specific per-machine-function
+/// information.
+///
+//===----------------------------------------------------------------------===//
+
+#include "AArch64MachineFunctionInfo.h"
+#include "AArch64InstrInfo.h"
+#include "AArch64Subtarget.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/MC/MCAsmInfo.h"
+
+using namespace llvm;
+
+yaml::AArch64FunctionInfo::AArch64FunctionInfo(
+ const llvm::AArch64FunctionInfo &MFI)
+ : HasRedZone(MFI.hasRedZone()) {}
+
+void yaml::AArch64FunctionInfo::mappingImpl(yaml::IO &YamlIO) {
+ MappingTraits<AArch64FunctionInfo>::mapping(YamlIO, *this);
+}
+
+void AArch64FunctionInfo::initializeBaseYamlFields(
+ const yaml::AArch64FunctionInfo &YamlMFI) {
+ if (YamlMFI.HasRedZone)
+ HasRedZone = YamlMFI.HasRedZone;
+}
+
+static std::pair<bool, bool> GetSignReturnAddress(const Function &F) {
+ // The function should be signed in the following situations:
+ // - sign-return-address=all
+ // - sign-return-address=non-leaf and the functions spills the LR
+ 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};
+}
+
+static bool ShouldSignWithBKey(const Function &F, const AArch64Subtarget &STI) {
+ if (!F.hasFnAttribute("sign-return-address-key")) {
+ if (const auto *BKey = mdconst::extract_or_null<ConstantInt>(
+ F.getParent()->getModuleFlag("sign-return-address-with-bkey")))
+ return BKey->getZExtValue();
+ if (STI.getTargetTriple().isOSWindows())
+ return true;
+ return false;
+ }
+
+ const StringRef Key =
+ F.getFnAttribute("sign-return-address-key").getValueAsString();
+ assert(Key.equals_insensitive("a_key") || Key.equals_insensitive("b_key"));
+ return Key.equals_insensitive("b_key");
+}
+
+AArch64FunctionInfo::AArch64FunctionInfo(const Function &F,
+ const AArch64Subtarget *STI) {
+ // If we already know that the function doesn't have a redzone, set
+ // HasRedZone here.
+ if (F.hasFnAttribute(Attribute::NoRedZone))
+ HasRedZone = false;
+ std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F);
+ SignWithBKey = ShouldSignWithBKey(F, *STI);
+ // TODO: skip functions that have no instrumented allocas for optimization
+ IsMTETagged = F.hasFnAttribute(Attribute::SanitizeMemTag);
+
+ if (!F.hasFnAttribute("branch-target-enforcement")) {
+ if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
+ F.getParent()->getModuleFlag("branch-target-enforcement")))
+ BranchTargetEnforcement = BTE->getZExtValue();
+ return;
+ }
+
+ const StringRef BTIEnable =
+ F.getFnAttribute("branch-target-enforcement").getValueAsString();
+ assert(BTIEnable.equals_insensitive("true") ||
+ BTIEnable.equals_insensitive("false"));
+ BranchTargetEnforcement = BTIEnable.equals_insensitive("true");
+}
+
+MachineFunctionInfo *AArch64FunctionInfo::clone(
+ BumpPtrAllocator &Allocator, MachineFunction &DestMF,
+ const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)
+ const {
+ return DestMF.cloneInfo<AArch64FunctionInfo>(*this);
+}
+
+bool AArch64FunctionInfo::shouldSignReturnAddress(bool SpillsLR) const {
+ if (!SignReturnAddress)
+ return false;
+ if (SignReturnAddressAll)
+ return true;
+ return SpillsLR;
+}
+
+bool AArch64FunctionInfo::shouldSignReturnAddress(
+ const MachineFunction &MF) const {
+ return shouldSignReturnAddress(llvm::any_of(
+ MF.getFrameInfo().getCalleeSavedInfo(),
+ [](const auto &Info) { return Info.getReg() == AArch64::LR; }));
+}
+
+bool AArch64FunctionInfo::needsDwarfUnwindInfo(
+ const MachineFunction &MF) const {
+ if (!NeedsDwarfUnwindInfo)
+ NeedsDwarfUnwindInfo = MF.needsFrameMoves() &&
+ !MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
+
+ return *NeedsDwarfUnwindInfo;
+}
+
+bool AArch64FunctionInfo::needsAsyncDwarfUnwindInfo(
+ const MachineFunction &MF) const {
+ if (!NeedsAsyncDwarfUnwindInfo) {
+ const Function &F = MF.getFunction();
+ // The check got "minsize" is because epilogue unwind info is not emitted
+ // (yet) for homogeneous epilogues, outlined functions, and functions
+ // outlined from.
+ NeedsAsyncDwarfUnwindInfo = needsDwarfUnwindInfo(MF) &&
+ F.getUWTableKind() == UWTableKind::Async &&
+ !F.hasMinSize();
+ }
+ return *NeedsAsyncDwarfUnwindInfo;
+}