mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
9d14adb9f6
This is a mechanical change. This actually also renames the similarly named methods in the SmallString class, however these methods don't seem to be used outside of the llvm subproject, so this doesn't break building of the rest of the monorepo.
117 lines
3.9 KiB
C++
117 lines
3.9 KiB
C++
//=- 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 <llvm/IR/Metadata.h>
|
|
#include <llvm/IR/Module.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.hasValue())
|
|
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) {
|
|
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();
|
|
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(MachineFunction &MF) : MF(MF) {
|
|
// If we already know that the function doesn't have a redzone, set
|
|
// HasRedZone here.
|
|
if (MF.getFunction().hasFnAttribute(Attribute::NoRedZone))
|
|
HasRedZone = false;
|
|
|
|
const Function &F = MF.getFunction();
|
|
std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F);
|
|
SignWithBKey = ShouldSignWithBKey(F);
|
|
|
|
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");
|
|
}
|
|
|
|
bool AArch64FunctionInfo::shouldSignReturnAddress(bool SpillsLR) const {
|
|
if (!SignReturnAddress)
|
|
return false;
|
|
if (SignReturnAddressAll)
|
|
return true;
|
|
return SpillsLR;
|
|
}
|
|
|
|
bool AArch64FunctionInfo::shouldSignReturnAddress() const {
|
|
return shouldSignReturnAddress(llvm::any_of(
|
|
MF.getFrameInfo().getCalleeSavedInfo(),
|
|
[](const auto &Info) { return Info.getReg() == AArch64::LR; }));
|
|
}
|