1 //===-- ARMMachineFunctionInfo.cpp - ARM machine function info ------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "ARMMachineFunctionInfo.h" 10 #include "ARMSubtarget.h" 11 12 using namespace llvm; 13 14 void ARMFunctionInfo::anchor() {} 15 16 yaml::ARMFunctionInfo::ARMFunctionInfo(const llvm::ARMFunctionInfo &MFI) 17 : LRSpilled(MFI.isLRSpilled()) {} 18 19 void yaml::ARMFunctionInfo::mappingImpl(yaml::IO &YamlIO) { 20 MappingTraits<ARMFunctionInfo>::mapping(YamlIO, *this); 21 } 22 23 void ARMFunctionInfo::initializeBaseYamlFields( 24 const yaml::ARMFunctionInfo &YamlMFI) { 25 LRSpilled = YamlMFI.LRSpilled; 26 } 27 28 static bool GetBranchTargetEnforcement(const Function &F, 29 const ARMSubtarget *Subtarget) { 30 if (!Subtarget->isMClass() || !Subtarget->hasV7Ops()) 31 return false; 32 33 if (!F.hasFnAttribute("branch-target-enforcement")) { 34 if (const auto *BTE = mdconst::extract_or_null<ConstantInt>( 35 F.getParent()->getModuleFlag("branch-target-enforcement"))) 36 return BTE->getZExtValue(); 37 return false; 38 } 39 40 const StringRef BTIEnable = 41 F.getFnAttribute("branch-target-enforcement").getValueAsString(); 42 assert(BTIEnable == "true" || BTIEnable == "false"); 43 return BTIEnable == "true"; 44 } 45 46 // The pair returns values for the ARMFunctionInfo members 47 // SignReturnAddress and SignReturnAddressAll respectively. 48 static std::pair<bool, bool> GetSignReturnAddress(const Function &F) { 49 if (!F.hasFnAttribute("sign-return-address")) { 50 const Module &M = *F.getParent(); 51 if (const auto *Sign = mdconst::extract_or_null<ConstantInt>( 52 M.getModuleFlag("sign-return-address"))) { 53 if (Sign->getZExtValue()) { 54 if (const auto *All = mdconst::extract_or_null<ConstantInt>( 55 M.getModuleFlag("sign-return-address-all"))) 56 return {true, All->getZExtValue()}; 57 return {true, false}; 58 } 59 } 60 return {false, false}; 61 } 62 63 StringRef Scope = F.getFnAttribute("sign-return-address").getValueAsString(); 64 if (Scope.equals("none")) 65 return {false, false}; 66 67 if (Scope.equals("all")) 68 return {true, true}; 69 70 assert(Scope.equals("non-leaf")); 71 return {true, false}; 72 } 73 74 ARMFunctionInfo::ARMFunctionInfo(const Function &F, 75 const ARMSubtarget *Subtarget) 76 : isThumb(Subtarget->isThumb()), hasThumb2(Subtarget->hasThumb2()), 77 IsCmseNSEntry(F.hasFnAttribute("cmse_nonsecure_entry")), 78 IsCmseNSCall(F.hasFnAttribute("cmse_nonsecure_call")), 79 BranchTargetEnforcement(GetBranchTargetEnforcement(F, Subtarget)) { 80 if (Subtarget->isMClass() && Subtarget->hasV7Ops()) 81 std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F); 82 } 83 84 MachineFunctionInfo * 85 ARMFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, 86 const DenseMap<MachineBasicBlock *, MachineBasicBlock *> 87 &Src2DstMBB) const { 88 return DestMF.cloneInfo<ARMFunctionInfo>(*this); 89 } 90