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 150b57cec5SDimitry Andric void ARMFunctionInfo::anchor() {} 160b57cec5SDimitry Andric 175f757f3fSDimitry Andric yaml::ARMFunctionInfo::ARMFunctionInfo(const llvm::ARMFunctionInfo &MFI) 185f757f3fSDimitry Andric : LRSpilled(MFI.isLRSpilled()) {} 195f757f3fSDimitry Andric 205f757f3fSDimitry Andric void yaml::ARMFunctionInfo::mappingImpl(yaml::IO &YamlIO) { 215f757f3fSDimitry Andric MappingTraits<ARMFunctionInfo>::mapping(YamlIO, *this); 225f757f3fSDimitry Andric } 235f757f3fSDimitry Andric 245f757f3fSDimitry Andric void ARMFunctionInfo::initializeBaseYamlFields( 255f757f3fSDimitry Andric const yaml::ARMFunctionInfo &YamlMFI) { 265f757f3fSDimitry Andric LRSpilled = YamlMFI.LRSpilled; 275f757f3fSDimitry Andric } 285f757f3fSDimitry Andric 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. 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 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 * 6681ad6265SDimitry 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