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 
anchor()14 void ARMFunctionInfo::anchor() {}
15 
ARMFunctionInfo(const llvm::ARMFunctionInfo & MFI)16 yaml::ARMFunctionInfo::ARMFunctionInfo(const llvm::ARMFunctionInfo &MFI)
17     : LRSpilled(MFI.isLRSpilled()) {}
18 
mappingImpl(yaml::IO & YamlIO)19 void yaml::ARMFunctionInfo::mappingImpl(yaml::IO &YamlIO) {
20   MappingTraits<ARMFunctionInfo>::mapping(YamlIO, *this);
21 }
22 
initializeBaseYamlFields(const yaml::ARMFunctionInfo & YamlMFI)23 void ARMFunctionInfo::initializeBaseYamlFields(
24     const yaml::ARMFunctionInfo &YamlMFI) {
25   LRSpilled = YamlMFI.LRSpilled;
26 }
27 
GetBranchTargetEnforcement(const Function & F,const ARMSubtarget * Subtarget)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.
GetSignReturnAddress(const Function & F)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 
ARMFunctionInfo(const Function & F,const ARMSubtarget * Subtarget)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 *
clone(BumpPtrAllocator & Allocator,MachineFunction & DestMF,const DenseMap<MachineBasicBlock *,MachineBasicBlock * > & Src2DstMBB) const85 ARMFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
86                        const DenseMap<MachineBasicBlock *, MachineBasicBlock *>
87                            &Src2DstMBB) const {
88   return DestMF.cloneInfo<ARMFunctionInfo>(*this);
89 }
90