LLVM 24.0.0git
RISCVMachineFunctionInfo.cpp
Go to the documentation of this file.
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
14#include "llvm/IR/Module.h"
15
16using namespace llvm;
17
20 : VarArgsFrameIndex(MFI.getVarArgsFrameIndex()),
21 VarArgsSaveSize(MFI.getVarArgsSaveSize()) {}
22
29
31 const RISCVSubtarget *STI) {
32 if (const auto *CFB = mdconst::extract_or_null<ConstantInt>(
33 F.getParent()->getModuleFlag("cf-protection-branch")))
34 CFProtectionBranch = CFB->getZExtValue() != 0;
35
36 // The default stack probe size is 4096 if the function has no
37 // stack-probe-size attribute. This is a safe default because it is the
38 // smallest possible guard page size.
39 uint64_t ProbeSize = 4096;
40 if (F.hasFnAttribute("stack-probe-size"))
41 ProbeSize = F.getFnAttributeAsParsedInteger("stack-probe-size");
42 else if (const auto *PS = mdconst::extract_or_null<ConstantInt>(
43 F.getParent()->getModuleFlag("stack-probe-size")))
44 ProbeSize = PS->getZExtValue();
45 assert(int64_t(ProbeSize) > 0 && "Invalid stack probe size");
46
47 // Round down to the stack alignment.
48 uint64_t StackAlign =
50 ProbeSize = std::max(StackAlign, alignDown(ProbeSize, StackAlign));
51 StringRef ProbeKind;
52 if (F.hasFnAttribute("probe-stack"))
53 ProbeKind = F.getFnAttribute("probe-stack").getValueAsString();
54 else if (const auto *PS = dyn_cast_or_null<MDString>(
55 F.getParent()->getModuleFlag("probe-stack")))
56 ProbeKind = PS->getString();
57 if (ProbeKind.size()) {
58 StackProbeSize = ProbeSize;
59 }
60}
61
64 const MachineFunction &MF) const {
65 if (!MF.getFunction().hasFnAttribute("interrupt"))
67
68 assert(VarArgsSaveSize == 0 &&
69 "Interrupt functions should not having incoming varargs");
70
71 StringRef InterruptVal =
73
75 InterruptVal)
78 .Case("SiFive-CLIC-preemptible",
80 .Case("SiFive-CLIC-stack-swap", InterruptStackKind::SiFiveCLICStackSwap)
81 .Case("SiFive-CLIC-preemptible-stack-swap",
84}
85
89
92 // Prefer HW Shadow Stack
93 //
94 // Zicfiss is encoded using a Zimop, so that's the only extension we have to
95 // check here. MOPs will be compressed if they have the right structure to.
96 if (MF.getSubtarget<RISCVSubtarget>().hasStdExtZimop() &&
97 MF.getFunction().hasFnAttribute("hw-shadow-stack"))
99
100 // ShadowCallStack attribute is used for software shadow call stack
101 if (MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack))
103
104 // Otherwise, none
106}
107
110 // We cannot use fixed locations for the callee saved spill slots if the
111 // function uses a varargs save area.
112 // TODO: Use a separate placement for vararg registers to enable Zcmp.
113 if (VarArgsSaveSize != 0)
114 return PushPopKind::None;
115
116 // SiFive interrupts are not compatible with push/pop.
117 if (useSiFiveInterrupt(MF))
118 return PushPopKind::None;
119
120 // Zcmp is not compatible with the frame pointer convention.
121 if (MF.getSubtarget<RISCVSubtarget>().hasStdExtZcmp() &&
124
125 // Xqccmp is Zcmp but has a push order compatible with the frame-pointer
126 // convention.
127 if (MF.getSubtarget<RISCVSubtarget>().hasVendorXqccmp())
129
130 return PushPopKind::None;
131}
132
134 const MachineFunction &MF) const {
135 switch (getInterruptStackKind(MF)) {
138 // QC.C.MIENTER and QC.C.MIENTER.NEST both update FP on function entry.
139 return true;
140 default:
141 break;
142 }
143
144 switch (getPushPopKind(MF)) {
146 // When using Xqccmp, we will use `QC.CM.PUSHFP` when Frame Pointers are
147 // enabled, which will update FP.
148 return true;
149 default:
150 break;
151 }
152
153 return false;
154}
155
157 const yaml::RISCVMachineFunctionInfo &YamlMFI) {
158 VarArgsFrameIndex = YamlMFI.VarArgsFrameIndex;
159 VarArgsSaveSize = YamlMFI.VarArgsSaveSize;
160}
161
163 SExt32Registers.push_back(Reg);
164}
165
167 return is_contained(SExt32Registers, Reg);
168}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:54
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition Function.cpp:769
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:734
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
bool disableFramePointerElim() const
Returns true if frame pointer elimination should be disabled for this function.
Ty * cloneInfo(const Ty &Old)
RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private RISCV-...
bool hasImplicitFPUpdates(const MachineFunction &MF) const
void initializeBaseYamlFields(const yaml::RISCVMachineFunctionInfo &YamlMFI)
InterruptStackKind getInterruptStackKind(const MachineFunction &MF) const
bool useSiFiveInterrupt(const MachineFunction &MF) const
MachineFunctionInfo * clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, const DenseMap< MachineBasicBlock *, MachineBasicBlock * > &Src2DstMBB) const override
Make a functionally equivalent copy of this MachineFunctionInfo in MF.
PushPopKind getPushPopKind(const MachineFunction &MF) const
RISCVMachineFunctionInfo(const Function &F, const RISCVSubtarget *STI)
ShadowStackKind getShadowStackKind(const MachineFunction &MF) const
const RISCVFrameLowering * getFrameLowering() const override
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Align getTransientStackAlign() const
getTransientStackAlignment - This method returns the number of bytes to which the stack pointer must ...
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract_or_null(Y &&MD)
Extract a Value from Metadata, allowing null.
Definition Metadata.h:694
This is an optimization pass for GlobalISel generic memory operations.
constexpr T alignDown(U Value, V Align, W Skew=0)
Returns the largest unsigned integer less than or equal to Value and is Skew mod Align.
Definition MathExtras.h:541
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:391
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:82
MachineFunctionInfo - This class can be derived from and used by targets to hold private target-speci...
This class should be specialized by any type that needs to be converted to/from a YAML mapping.
Definition YAMLTraits.h:63
void mappingImpl(yaml::IO &YamlIO) override