xref: /freebsd/contrib/llvm-project/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
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 
164824e7fdSDimitry Andric static bool GetBranchTargetEnforcement(MachineFunction &MF) {
174824e7fdSDimitry Andric   const auto &Subtarget = MF.getSubtarget<ARMSubtarget>();
184824e7fdSDimitry Andric   if (!Subtarget.isMClass() || !Subtarget.hasV7Ops())
194824e7fdSDimitry Andric     return false;
204824e7fdSDimitry Andric 
214824e7fdSDimitry Andric   const Function &F = MF.getFunction();
224824e7fdSDimitry Andric   if (!F.hasFnAttribute("branch-target-enforcement")) {
234824e7fdSDimitry Andric     if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
244824e7fdSDimitry Andric             F.getParent()->getModuleFlag("branch-target-enforcement")))
254824e7fdSDimitry Andric       return BTE->getZExtValue();
264824e7fdSDimitry Andric     return false;
274824e7fdSDimitry Andric   }
284824e7fdSDimitry Andric 
294824e7fdSDimitry Andric   const StringRef BTIEnable =
304824e7fdSDimitry Andric       F.getFnAttribute("branch-target-enforcement").getValueAsString();
314824e7fdSDimitry Andric   assert(BTIEnable.equals_insensitive("true") ||
324824e7fdSDimitry Andric          BTIEnable.equals_insensitive("false"));
334824e7fdSDimitry Andric   return BTIEnable.equals_insensitive("true");
344824e7fdSDimitry Andric }
354824e7fdSDimitry Andric 
364824e7fdSDimitry Andric // The pair returns values for the ARMFunctionInfo members
374824e7fdSDimitry Andric // SignReturnAddress and SignReturnAddressAll respectively.
384824e7fdSDimitry Andric static std::pair<bool, bool> GetSignReturnAddress(const Function &F) {
394824e7fdSDimitry Andric   if (!F.hasFnAttribute("sign-return-address")) {
404824e7fdSDimitry Andric     const Module &M = *F.getParent();
414824e7fdSDimitry Andric     if (const auto *Sign = mdconst::extract_or_null<ConstantInt>(
424824e7fdSDimitry Andric             M.getModuleFlag("sign-return-address"))) {
434824e7fdSDimitry Andric       if (Sign->getZExtValue()) {
444824e7fdSDimitry Andric         if (const auto *All = mdconst::extract_or_null<ConstantInt>(
454824e7fdSDimitry Andric                 M.getModuleFlag("sign-return-address-all")))
464824e7fdSDimitry Andric           return {true, All->getZExtValue()};
474824e7fdSDimitry Andric         return {true, false};
484824e7fdSDimitry Andric       }
494824e7fdSDimitry Andric     }
504824e7fdSDimitry Andric     return {false, false};
514824e7fdSDimitry Andric   }
524824e7fdSDimitry Andric 
534824e7fdSDimitry Andric   StringRef Scope = F.getFnAttribute("sign-return-address").getValueAsString();
544824e7fdSDimitry Andric   if (Scope.equals("none"))
554824e7fdSDimitry Andric     return {false, false};
564824e7fdSDimitry Andric 
574824e7fdSDimitry Andric   if (Scope.equals("all"))
584824e7fdSDimitry Andric     return {true, true};
594824e7fdSDimitry Andric 
604824e7fdSDimitry Andric   assert(Scope.equals("non-leaf"));
614824e7fdSDimitry Andric   return {true, false};
624824e7fdSDimitry Andric }
634824e7fdSDimitry Andric 
640b57cec5SDimitry Andric ARMFunctionInfo::ARMFunctionInfo(MachineFunction &MF)
650b57cec5SDimitry Andric     : isThumb(MF.getSubtarget<ARMSubtarget>().isThumb()),
665ffd83dbSDimitry Andric       hasThumb2(MF.getSubtarget<ARMSubtarget>().hasThumb2()),
675ffd83dbSDimitry Andric       IsCmseNSEntry(MF.getFunction().hasFnAttribute("cmse_nonsecure_entry")),
684824e7fdSDimitry Andric       IsCmseNSCall(MF.getFunction().hasFnAttribute("cmse_nonsecure_call")),
694824e7fdSDimitry Andric       BranchTargetEnforcement(GetBranchTargetEnforcement(MF)) {
704824e7fdSDimitry Andric 
714824e7fdSDimitry Andric   const auto &Subtarget = MF.getSubtarget<ARMSubtarget>();
724824e7fdSDimitry Andric   if (Subtarget.isMClass() && Subtarget.hasV7Ops())
734824e7fdSDimitry Andric     std::tie(SignReturnAddress, SignReturnAddressAll) =
744824e7fdSDimitry Andric         GetSignReturnAddress(MF.getFunction());
754824e7fdSDimitry Andric }
76*81ad6265SDimitry Andric 
77*81ad6265SDimitry Andric MachineFunctionInfo *
78*81ad6265SDimitry Andric ARMFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
79*81ad6265SDimitry Andric                        const DenseMap<MachineBasicBlock *, MachineBasicBlock *>
80*81ad6265SDimitry Andric                            &Src2DstMBB) const {
81*81ad6265SDimitry Andric   return DestMF.cloneInfo<ARMFunctionInfo>(*this);
82*81ad6265SDimitry Andric }
83