10b57cec5SDimitry Andric //===-- ARMMachineFunctionInfo.cpp - ARM machine function info ------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "ARMMachineFunctionInfo.h"
100b57cec5SDimitry Andric #include "ARMSubtarget.h"
11*0fca6ea1SDimitry Andric #include "llvm/IR/Module.h"
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric using namespace llvm;
140b57cec5SDimitry Andric
anchor()150b57cec5SDimitry Andric void ARMFunctionInfo::anchor() {}
160b57cec5SDimitry Andric
ARMFunctionInfo(const llvm::ARMFunctionInfo & MFI)175f757f3fSDimitry Andric yaml::ARMFunctionInfo::ARMFunctionInfo(const llvm::ARMFunctionInfo &MFI)
185f757f3fSDimitry Andric : LRSpilled(MFI.isLRSpilled()) {}
195f757f3fSDimitry Andric
mappingImpl(yaml::IO & YamlIO)205f757f3fSDimitry Andric void yaml::ARMFunctionInfo::mappingImpl(yaml::IO &YamlIO) {
215f757f3fSDimitry Andric MappingTraits<ARMFunctionInfo>::mapping(YamlIO, *this);
225f757f3fSDimitry Andric }
235f757f3fSDimitry Andric
initializeBaseYamlFields(const yaml::ARMFunctionInfo & YamlMFI)245f757f3fSDimitry Andric void ARMFunctionInfo::initializeBaseYamlFields(
255f757f3fSDimitry Andric const yaml::ARMFunctionInfo &YamlMFI) {
265f757f3fSDimitry Andric LRSpilled = YamlMFI.LRSpilled;
275f757f3fSDimitry Andric }
285f757f3fSDimitry Andric
GetBranchTargetEnforcement(const Function & F,const ARMSubtarget * Subtarget)29bdd1243dSDimitry Andric static bool GetBranchTargetEnforcement(const Function &F,
30bdd1243dSDimitry Andric const ARMSubtarget *Subtarget) {
31bdd1243dSDimitry Andric if (!Subtarget->isMClass() || !Subtarget->hasV7Ops())
324824e7fdSDimitry Andric return false;
334824e7fdSDimitry Andric
34*0fca6ea1SDimitry Andric return F.hasFnAttribute("branch-target-enforcement");
354824e7fdSDimitry Andric }
364824e7fdSDimitry Andric
374824e7fdSDimitry Andric // The pair returns values for the ARMFunctionInfo members
384824e7fdSDimitry Andric // SignReturnAddress and SignReturnAddressAll respectively.
GetSignReturnAddress(const Function & F)394824e7fdSDimitry Andric static std::pair<bool, bool> GetSignReturnAddress(const Function &F) {
404824e7fdSDimitry Andric if (!F.hasFnAttribute("sign-return-address")) {
414824e7fdSDimitry Andric return {false, false};
424824e7fdSDimitry Andric }
434824e7fdSDimitry Andric
444824e7fdSDimitry Andric StringRef Scope = F.getFnAttribute("sign-return-address").getValueAsString();
45*0fca6ea1SDimitry Andric if (Scope == "none")
464824e7fdSDimitry Andric return {false, false};
474824e7fdSDimitry Andric
48*0fca6ea1SDimitry Andric if (Scope == "all")
494824e7fdSDimitry Andric return {true, true};
504824e7fdSDimitry Andric
51*0fca6ea1SDimitry Andric assert(Scope == "non-leaf");
524824e7fdSDimitry Andric return {true, false};
534824e7fdSDimitry Andric }
544824e7fdSDimitry Andric
ARMFunctionInfo(const Function & F,const ARMSubtarget * Subtarget)55bdd1243dSDimitry Andric ARMFunctionInfo::ARMFunctionInfo(const Function &F,
56bdd1243dSDimitry Andric const ARMSubtarget *Subtarget)
57bdd1243dSDimitry Andric : isThumb(Subtarget->isThumb()), hasThumb2(Subtarget->hasThumb2()),
58bdd1243dSDimitry Andric IsCmseNSEntry(F.hasFnAttribute("cmse_nonsecure_entry")),
59bdd1243dSDimitry Andric IsCmseNSCall(F.hasFnAttribute("cmse_nonsecure_call")),
60bdd1243dSDimitry Andric BranchTargetEnforcement(GetBranchTargetEnforcement(F, Subtarget)) {
61bdd1243dSDimitry Andric if (Subtarget->isMClass() && Subtarget->hasV7Ops())
62bdd1243dSDimitry Andric std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F);
634824e7fdSDimitry Andric }
6481ad6265SDimitry Andric
6581ad6265SDimitry Andric MachineFunctionInfo *
clone(BumpPtrAllocator & Allocator,MachineFunction & DestMF,const DenseMap<MachineBasicBlock *,MachineBasicBlock * > & Src2DstMBB) const6681ad6265SDimitry Andric ARMFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
6781ad6265SDimitry Andric const DenseMap<MachineBasicBlock *, MachineBasicBlock *>
6881ad6265SDimitry Andric &Src2DstMBB) const {
6981ad6265SDimitry Andric return DestMF.cloneInfo<ARMFunctionInfo>(*this);
7081ad6265SDimitry Andric }
71