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" 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric using namespace llvm; 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric void ARMFunctionInfo::anchor() {} 150b57cec5SDimitry Andric 16*5f757f3fSDimitry Andric yaml::ARMFunctionInfo::ARMFunctionInfo(const llvm::ARMFunctionInfo &MFI) 17*5f757f3fSDimitry Andric : LRSpilled(MFI.isLRSpilled()) {} 18*5f757f3fSDimitry Andric 19*5f757f3fSDimitry Andric void yaml::ARMFunctionInfo::mappingImpl(yaml::IO &YamlIO) { 20*5f757f3fSDimitry Andric MappingTraits<ARMFunctionInfo>::mapping(YamlIO, *this); 21*5f757f3fSDimitry Andric } 22*5f757f3fSDimitry Andric 23*5f757f3fSDimitry Andric void ARMFunctionInfo::initializeBaseYamlFields( 24*5f757f3fSDimitry Andric const yaml::ARMFunctionInfo &YamlMFI) { 25*5f757f3fSDimitry Andric LRSpilled = YamlMFI.LRSpilled; 26*5f757f3fSDimitry Andric } 27*5f757f3fSDimitry Andric 28bdd1243dSDimitry Andric static bool GetBranchTargetEnforcement(const Function &F, 29bdd1243dSDimitry Andric const ARMSubtarget *Subtarget) { 30bdd1243dSDimitry Andric if (!Subtarget->isMClass() || !Subtarget->hasV7Ops()) 314824e7fdSDimitry Andric return false; 324824e7fdSDimitry Andric 334824e7fdSDimitry Andric if (!F.hasFnAttribute("branch-target-enforcement")) { 344824e7fdSDimitry Andric if (const auto *BTE = mdconst::extract_or_null<ConstantInt>( 354824e7fdSDimitry Andric F.getParent()->getModuleFlag("branch-target-enforcement"))) 364824e7fdSDimitry Andric return BTE->getZExtValue(); 374824e7fdSDimitry Andric return false; 384824e7fdSDimitry Andric } 394824e7fdSDimitry Andric 404824e7fdSDimitry Andric const StringRef BTIEnable = 414824e7fdSDimitry Andric F.getFnAttribute("branch-target-enforcement").getValueAsString(); 42*5f757f3fSDimitry Andric assert(BTIEnable == "true" || BTIEnable == "false"); 43*5f757f3fSDimitry Andric return BTIEnable == "true"; 444824e7fdSDimitry Andric } 454824e7fdSDimitry Andric 464824e7fdSDimitry Andric // The pair returns values for the ARMFunctionInfo members 474824e7fdSDimitry Andric // SignReturnAddress and SignReturnAddressAll respectively. 484824e7fdSDimitry Andric static std::pair<bool, bool> GetSignReturnAddress(const Function &F) { 494824e7fdSDimitry Andric if (!F.hasFnAttribute("sign-return-address")) { 504824e7fdSDimitry Andric const Module &M = *F.getParent(); 514824e7fdSDimitry Andric if (const auto *Sign = mdconst::extract_or_null<ConstantInt>( 524824e7fdSDimitry Andric M.getModuleFlag("sign-return-address"))) { 534824e7fdSDimitry Andric if (Sign->getZExtValue()) { 544824e7fdSDimitry Andric if (const auto *All = mdconst::extract_or_null<ConstantInt>( 554824e7fdSDimitry Andric M.getModuleFlag("sign-return-address-all"))) 564824e7fdSDimitry Andric return {true, All->getZExtValue()}; 574824e7fdSDimitry Andric return {true, false}; 584824e7fdSDimitry Andric } 594824e7fdSDimitry Andric } 604824e7fdSDimitry Andric return {false, false}; 614824e7fdSDimitry Andric } 624824e7fdSDimitry Andric 634824e7fdSDimitry Andric StringRef Scope = F.getFnAttribute("sign-return-address").getValueAsString(); 644824e7fdSDimitry Andric if (Scope.equals("none")) 654824e7fdSDimitry Andric return {false, false}; 664824e7fdSDimitry Andric 674824e7fdSDimitry Andric if (Scope.equals("all")) 684824e7fdSDimitry Andric return {true, true}; 694824e7fdSDimitry Andric 704824e7fdSDimitry Andric assert(Scope.equals("non-leaf")); 714824e7fdSDimitry Andric return {true, false}; 724824e7fdSDimitry Andric } 734824e7fdSDimitry Andric 74bdd1243dSDimitry Andric ARMFunctionInfo::ARMFunctionInfo(const Function &F, 75bdd1243dSDimitry Andric const ARMSubtarget *Subtarget) 76bdd1243dSDimitry Andric : isThumb(Subtarget->isThumb()), hasThumb2(Subtarget->hasThumb2()), 77bdd1243dSDimitry Andric IsCmseNSEntry(F.hasFnAttribute("cmse_nonsecure_entry")), 78bdd1243dSDimitry Andric IsCmseNSCall(F.hasFnAttribute("cmse_nonsecure_call")), 79bdd1243dSDimitry Andric BranchTargetEnforcement(GetBranchTargetEnforcement(F, Subtarget)) { 80bdd1243dSDimitry Andric if (Subtarget->isMClass() && Subtarget->hasV7Ops()) 81bdd1243dSDimitry Andric std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F); 824824e7fdSDimitry Andric } 8381ad6265SDimitry Andric 8481ad6265SDimitry Andric MachineFunctionInfo * 8581ad6265SDimitry Andric ARMFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, 8681ad6265SDimitry Andric const DenseMap<MachineBasicBlock *, MachineBasicBlock *> 8781ad6265SDimitry Andric &Src2DstMBB) const { 8881ad6265SDimitry Andric return DestMF.cloneInfo<ARMFunctionInfo>(*this); 8981ad6265SDimitry Andric } 90