xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
1 //=- RISCVMachineFunctionInfo.cpp - RISC-V machine function info --*- C++ -*-=//
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 // This file declares RISCV-specific per-machine-function information.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "RISCVMachineFunctionInfo.h"
14 #include "llvm/IR/Module.h"
15 
16 using namespace llvm;
17 
18 yaml::RISCVMachineFunctionInfo::RISCVMachineFunctionInfo(
19     const llvm::RISCVMachineFunctionInfo &MFI)
20     : VarArgsFrameIndex(MFI.getVarArgsFrameIndex()),
21       VarArgsSaveSize(MFI.getVarArgsSaveSize()) {}
22 
23 MachineFunctionInfo *RISCVMachineFunctionInfo::clone(
24     BumpPtrAllocator &Allocator, MachineFunction &DestMF,
25     const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)
26     const {
27   return DestMF.cloneInfo<RISCVMachineFunctionInfo>(*this);
28 }
29 
30 RISCVMachineFunctionInfo::RISCVMachineFunctionInfo(const Function &F,
31                                                    const RISCVSubtarget *STI) {
32 
33   // The default stack probe size is 4096 if the function has no
34   // stack-probe-size attribute. This is a safe default because it is the
35   // smallest possible guard page size.
36   uint64_t ProbeSize = 4096;
37   if (F.hasFnAttribute("stack-probe-size"))
38     ProbeSize = F.getFnAttributeAsParsedInteger("stack-probe-size");
39   else if (const auto *PS = mdconst::extract_or_null<ConstantInt>(
40                F.getParent()->getModuleFlag("stack-probe-size")))
41     ProbeSize = PS->getZExtValue();
42   assert(int64_t(ProbeSize) > 0 && "Invalid stack probe size");
43 
44   // Round down to the stack alignment.
45   uint64_t StackAlign =
46       STI->getFrameLowering()->getTransientStackAlign().value();
47   ProbeSize = std::max(StackAlign, alignDown(ProbeSize, StackAlign));
48   StringRef ProbeKind;
49   if (F.hasFnAttribute("probe-stack"))
50     ProbeKind = F.getFnAttribute("probe-stack").getValueAsString();
51   else if (const auto *PS = dyn_cast_or_null<MDString>(
52                F.getParent()->getModuleFlag("probe-stack")))
53     ProbeKind = PS->getString();
54   if (ProbeKind.size()) {
55     StackProbeSize = ProbeSize;
56   }
57 }
58 
59 RISCVMachineFunctionInfo::InterruptStackKind
60 RISCVMachineFunctionInfo::getInterruptStackKind(
61     const MachineFunction &MF) const {
62   if (!MF.getFunction().hasFnAttribute("interrupt"))
63     return InterruptStackKind::None;
64 
65   assert(VarArgsSaveSize == 0 &&
66          "Interrupt functions should not having incoming varargs");
67 
68   StringRef InterruptVal =
69       MF.getFunction().getFnAttribute("interrupt").getValueAsString();
70 
71   return StringSwitch<RISCVMachineFunctionInfo::InterruptStackKind>(
72              InterruptVal)
73       .Case("qci-nest", InterruptStackKind::QCINest)
74       .Case("qci-nonest", InterruptStackKind::QCINoNest)
75       .Case("SiFive-CLIC-preemptible",
76             InterruptStackKind::SiFiveCLICPreemptible)
77       .Case("SiFive-CLIC-stack-swap", InterruptStackKind::SiFiveCLICStackSwap)
78       .Case("SiFive-CLIC-preemptible-stack-swap",
79             InterruptStackKind::SiFiveCLICPreemptibleStackSwap)
80       .Default(InterruptStackKind::None);
81 }
82 
83 void yaml::RISCVMachineFunctionInfo::mappingImpl(yaml::IO &YamlIO) {
84   MappingTraits<RISCVMachineFunctionInfo>::mapping(YamlIO, *this);
85 }
86 
87 RISCVMachineFunctionInfo::PushPopKind
88 RISCVMachineFunctionInfo::getPushPopKind(const MachineFunction &MF) const {
89   // We cannot use fixed locations for the callee saved spill slots if the
90   // function uses a varargs save area.
91   // TODO: Use a separate placement for vararg registers to enable Zcmp.
92   if (VarArgsSaveSize != 0)
93     return PushPopKind::None;
94 
95   // SiFive interrupts are not compatible with push/pop.
96   if (useSiFiveInterrupt(MF))
97     return PushPopKind::None;
98 
99   // Zcmp is not compatible with the frame pointer convention.
100   if (MF.getSubtarget<RISCVSubtarget>().hasStdExtZcmp() &&
101       !MF.getTarget().Options.DisableFramePointerElim(MF))
102     return PushPopKind::StdExtZcmp;
103 
104   // Xqccmp is Zcmp but has a push order compatible with the frame-pointer
105   // convention.
106   if (MF.getSubtarget<RISCVSubtarget>().hasVendorXqccmp())
107     return PushPopKind::VendorXqccmp;
108 
109   return PushPopKind::None;
110 }
111 
112 bool RISCVMachineFunctionInfo::hasImplicitFPUpdates(
113     const MachineFunction &MF) const {
114   switch (getInterruptStackKind(MF)) {
115   case InterruptStackKind::QCINest:
116   case InterruptStackKind::QCINoNest:
117     // QC.C.MIENTER and QC.C.MIENTER.NEST both update FP on function entry.
118     return true;
119   default:
120     break;
121   }
122 
123   switch (getPushPopKind(MF)) {
124   case PushPopKind::VendorXqccmp:
125     // When using Xqccmp, we will use `QC.CM.PUSHFP` when Frame Pointers are
126     // enabled, which will update FP.
127     return true;
128   default:
129     break;
130   }
131 
132   return false;
133 }
134 
135 void RISCVMachineFunctionInfo::initializeBaseYamlFields(
136     const yaml::RISCVMachineFunctionInfo &YamlMFI) {
137   VarArgsFrameIndex = YamlMFI.VarArgsFrameIndex;
138   VarArgsSaveSize = YamlMFI.VarArgsSaveSize;
139 }
140 
141 void RISCVMachineFunctionInfo::addSExt32Register(Register Reg) {
142   SExt32Registers.push_back(Reg);
143 }
144 
145 bool RISCVMachineFunctionInfo::isSExt32Register(Register Reg) const {
146   return is_contained(SExt32Registers, Reg);
147 }
148