LLVM 17.0.0git
CallingConvLower.cpp
Go to the documentation of this file.
1//===-- CallingConvLower.cpp - Calling Conventions ------------------------===//
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 implements the CCState class, used for lowering and implementing
10// calling conventions.
11//
12//===----------------------------------------------------------------------===//
13
21#include "llvm/Support/Debug.h"
25
26using namespace llvm;
27
30 : CallingConv(CC), IsVarArg(isVarArg), MF(mf),
31 TRI(*MF.getSubtarget().getRegisterInfo()), Locs(locs), Context(C) {
32 // No stack is used.
33 StackOffset = 0;
34
36 UsedRegs.resize((TRI.getNumRegs()+31)/32);
37}
38
39/// Allocate space on the stack large enough to pass an argument by value.
40/// The size and alignment information of the argument is encoded in
41/// its parameter attribute.
42void CCState::HandleByVal(unsigned ValNo, MVT ValVT, MVT LocVT,
43 CCValAssign::LocInfo LocInfo, int MinSize,
44 Align MinAlign, ISD::ArgFlagsTy ArgFlags) {
45 Align Alignment = ArgFlags.getNonZeroByValAlign();
46 unsigned Size = ArgFlags.getByValSize();
47 if (MinSize > (int)Size)
48 Size = MinSize;
49 if (MinAlign > Alignment)
50 Alignment = MinAlign;
51 ensureMaxAlignment(Alignment);
52 MF.getSubtarget().getTargetLowering()->HandleByVal(this, Size, Alignment);
54 unsigned Offset = AllocateStack(Size, Alignment);
55 addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
56}
57
58/// Mark a register and all of its aliases as allocated.
59void CCState::MarkAllocated(MCPhysReg Reg) {
60 for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI)
61 UsedRegs[*AI / 32] |= 1 << (*AI & 31);
62}
63
64void CCState::MarkUnallocated(MCPhysReg Reg) {
65 for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI)
66 UsedRegs[*AI / 32] &= ~(1 << (*AI & 31));
67}
68
70 if (!isAllocated(Reg))
71 return false;
72
73 for (auto const &ValAssign : Locs)
74 if (ValAssign.isRegLoc() && TRI.regsOverlap(ValAssign.getLocReg(), Reg))
75 return false;
76 return true;
77}
78
79/// Analyze an array of argument values,
80/// incorporating info about the formals into this state.
81void
83 CCAssignFn Fn) {
84 unsigned NumArgs = Ins.size();
85
86 for (unsigned i = 0; i != NumArgs; ++i) {
87 MVT ArgVT = Ins[i].VT;
88 ISD::ArgFlagsTy ArgFlags = Ins[i].Flags;
89 if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this))
90 report_fatal_error("unable to allocate function argument #" + Twine(i));
91 }
92}
93
94/// Analyze the return values of a function, returning true if the return can
95/// be performed without sret-demotion and false otherwise.
97 CCAssignFn Fn) {
98 // Determine which register each value should be copied into.
99 for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
100 MVT VT = Outs[i].VT;
101 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
102 if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this))
103 return false;
104 }
105 return true;
106}
107
108/// Analyze the returned values of a return,
109/// incorporating info about the result values into this state.
111 CCAssignFn Fn) {
112 // Determine which register each value should be copied into.
113 for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
114 MVT VT = Outs[i].VT;
115 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
116 if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this))
117 report_fatal_error("unable to allocate function return #" + Twine(i));
118 }
119}
120
121/// Analyze the outgoing arguments to a call,
122/// incorporating info about the passed values into this state.
124 CCAssignFn Fn) {
125 unsigned NumOps = Outs.size();
126 for (unsigned i = 0; i != NumOps; ++i) {
127 MVT ArgVT = Outs[i].VT;
128 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
129 if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) {
130#ifndef NDEBUG
131 dbgs() << "Call operand #" << i << " has unhandled type "
132 << ArgVT << '\n';
133#endif
134 llvm_unreachable(nullptr);
135 }
136 }
137}
138
139/// Same as above except it takes vectors of types and argument flags.
142 CCAssignFn Fn) {
143 unsigned NumOps = ArgVTs.size();
144 for (unsigned i = 0; i != NumOps; ++i) {
145 MVT ArgVT = ArgVTs[i];
146 ISD::ArgFlagsTy ArgFlags = Flags[i];
147 if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) {
148#ifndef NDEBUG
149 dbgs() << "Call operand #" << i << " has unhandled type "
150 << ArgVT << '\n';
151#endif
152 llvm_unreachable(nullptr);
153 }
154 }
155}
156
157/// Analyze the return values of a call, incorporating info about the passed
158/// values into this state.
160 CCAssignFn Fn) {
161 for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
162 MVT VT = Ins[i].VT;
163 ISD::ArgFlagsTy Flags = Ins[i].Flags;
164 if (Fn(i, VT, VT, CCValAssign::Full, Flags, *this)) {
165#ifndef NDEBUG
166 dbgs() << "Call result #" << i << " has unhandled type "
167 << VT << '\n';
168#endif
169 llvm_unreachable(nullptr);
170 }
171 }
172}
173
174/// Same as above except it's specialized for calls that produce a single value.
176 if (Fn(0, VT, VT, CCValAssign::Full, ISD::ArgFlagsTy(), *this)) {
177#ifndef NDEBUG
178 dbgs() << "Call result has unhandled type "
179 << VT << '\n';
180#endif
181 llvm_unreachable(nullptr);
182 }
183}
184
186 if (!AnalyzingMustTailForwardedRegs)
187 MF.getFrameInfo().ensureMaxAlignment(Alignment);
188}
189
191 if (VT.isVector())
192 return true; // Assume -msse-regparm might be in effect.
193 if (!VT.isInteger())
194 return false;
196}
197
199 MVT VT, CCAssignFn Fn) {
200 unsigned SavedStackOffset = StackOffset;
201 Align SavedMaxStackArgAlign = MaxStackArgAlign;
202 unsigned NumLocs = Locs.size();
203
204 // Set the 'inreg' flag if it is used for this calling convention.
206 if (isValueTypeInRegForCC(CallingConv, VT))
207 Flags.setInReg();
208
209 // Allocate something of this value type repeatedly until we get assigned a
210 // location in memory.
211 bool HaveRegParm;
212 do {
213 if (Fn(0, VT, VT, CCValAssign::Full, Flags, *this)) {
214#ifndef NDEBUG
215 dbgs() << "Call has unhandled type " << VT
216 << " while computing remaining regparms\n";
217#endif
218 llvm_unreachable(nullptr);
219 }
220 HaveRegParm = Locs.back().isRegLoc();
221 } while (HaveRegParm);
222
223 // Copy all the registers from the value locations we added.
224 assert(NumLocs < Locs.size() && "CC assignment failed to add location");
225 for (unsigned I = NumLocs, E = Locs.size(); I != E; ++I)
226 if (Locs[I].isRegLoc())
227 Regs.push_back(MCPhysReg(Locs[I].getLocReg()));
228
229 // Clear the assigned values and stack memory. We leave the registers marked
230 // as allocated so that future queries don't return the same registers, i.e.
231 // when i64 and f64 are both passed in GPRs.
232 StackOffset = SavedStackOffset;
233 MaxStackArgAlign = SavedMaxStackArgAlign;
234 Locs.truncate(NumLocs);
235}
236
239 CCAssignFn Fn) {
240 // Oftentimes calling conventions will not user register parameters for
241 // variadic functions, so we need to assume we're not variadic so that we get
242 // all the registers that might be used in a non-variadic call.
243 SaveAndRestore SavedVarArg(IsVarArg, false);
244 SaveAndRestore SavedMustTail(AnalyzingMustTailForwardedRegs, true);
245
246 for (MVT RegVT : RegParmTypes) {
247 SmallVector<MCPhysReg, 8> RemainingRegs;
248 getRemainingRegParmsForType(RemainingRegs, RegVT, Fn);
250 const TargetRegisterClass *RC = TL->getRegClassFor(RegVT);
251 for (MCPhysReg PReg : RemainingRegs) {
252 Register VReg = MF.addLiveIn(PReg, RC);
253 Forwards.push_back(ForwardedRegister(VReg, PReg, RegVT));
254 }
255 }
256}
257
259 CallingConv::ID CallerCC, MachineFunction &MF,
260 LLVMContext &C,
262 CCAssignFn CalleeFn, CCAssignFn CallerFn) {
263 if (CalleeCC == CallerCC)
264 return true;
266 CCState CCInfo1(CalleeCC, false, MF, RVLocs1, C);
267 CCInfo1.AnalyzeCallResult(Ins, CalleeFn);
268
270 CCState CCInfo2(CallerCC, false, MF, RVLocs2, C);
271 CCInfo2.AnalyzeCallResult(Ins, CallerFn);
272
273 auto AreCompatible = [](const CCValAssign &Loc1, const CCValAssign &Loc2) {
274 assert(!Loc1.isPendingLoc() && !Loc2.isPendingLoc() &&
275 "The location must have been decided by now");
276 // Must fill the same part of their locations.
277 if (Loc1.getLocInfo() != Loc2.getLocInfo())
278 return false;
279 // Must both be in the same registers, or both in memory at the same offset.
280 if (Loc1.isRegLoc() && Loc2.isRegLoc())
281 return Loc1.getLocReg() == Loc2.getLocReg();
282 if (Loc1.isMemLoc() && Loc2.isMemLoc())
283 return Loc1.getLocMemOffset() == Loc2.getLocMemOffset();
284 llvm_unreachable("Unknown location kind");
285 };
286
287 return std::equal(RVLocs1.begin(), RVLocs1.end(), RVLocs2.begin(),
288 RVLocs2.end(), AreCompatible);
289}
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool isValueTypeInRegForCC(CallingConv::ID CC, MVT VT)
uint64_t Size
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
LLVMContext & Context
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file provides utility classes that use RAII to save and restore values.
This file describes how to lower LLVM code to machine code.
@ Flags
Definition: TextStubV5.cpp:93
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
CCState - This class holds information needed while lowering arguments and return values.
void HandleByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, int MinSize, Align MinAlign, ISD::ArgFlagsTy ArgFlags)
Allocate space on the stack large enough to pass an argument by value.
void analyzeMustTailForwardedRegisters(SmallVectorImpl< ForwardedRegister > &Forwards, ArrayRef< MVT > RegParmTypes, CCAssignFn Fn)
Compute the set of registers that need to be preserved and forwarded to any musttail calls.
static bool resultsCompatible(CallingConv::ID CalleeCC, CallingConv::ID CallerCC, MachineFunction &MF, LLVMContext &C, const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn CalleeFn, CCAssignFn CallerFn)
Returns true if the results of the two calling conventions are compatible.
void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...
bool IsShadowAllocatedReg(MCRegister Reg) const
A shadow allocated register is a register that was allocated but wasn't added to the location list (L...
unsigned AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...
void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...
void getRemainingRegParmsForType(SmallVectorImpl< MCPhysReg > &Regs, MVT VT, CCAssignFn Fn)
Compute the remaining unused register parameters that would be used for the given value type.
void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...
void ensureMaxAlignment(Align Alignment)
CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, SmallVectorImpl< CCValAssign > &locs, LLVMContext &C)
bool isAllocated(MCRegister Reg) const
isAllocated - Return true if the specified register (or an alias) is allocated.
void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
void addLoc(const CCValAssign &V)
void clearByValRegsInfo()
CCValAssign - Represent assignment of one arg/retval to a location.
bool isRegLoc() const
unsigned getLocMemOffset() const
Register getLocReg() const
bool isPendingLoc() const
LocInfo getLocInfo() const
bool isMemLoc() const
static CCValAssign getMem(unsigned ValNo, MVT ValVT, unsigned Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
MCRegAliasIterator enumerates all registers aliasing Reg.
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:24
Machine Value Type.
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
void ensureMaxAlignment(Align Alignment)
Make sure the function is at least Align bytes aligned.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
void resize(size_type N)
Definition: SmallVector.h:642
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StackOffset holds a fixed and a scalable offset in bytes.
Definition: TypeSize.h:36
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual void HandleByVal(CCState *, unsigned &, Align) const
Target-specific cleanup for formal ByVal parameters.
bool regsOverlap(Register RegA, Register RegB) const
Returns true if the two registers are equal or alias each other.
virtual const TargetLowering * getTargetLowering() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ X86_VectorCall
MSVC calling convention that passes vectors and vector aggregates in SSE registers.
Definition: CallingConv.h:160
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ X86_FastCall
'fast' analog of X86_StdCall.
Definition: CallingConv.h:100
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:406
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition: MCRegister.h:21
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
constexpr uint64_t MinAlign(uint64_t A, uint64_t B)
A and B are either alignments or offsets.
Definition: MathExtras.h:439
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
Describes a register that needs to be forwarded from the prologue to a musttail call.
unsigned getByValSize() const
Align getNonZeroByValAlign() const
A utility class that uses RAII to save and restore the value of a variable.