1 | //===- llvm/CodeGen/GlobalISel/CallLowering.h - Call lowering ---*- 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 | /// \file |
10 | /// This file describes how to lower LLVM calls to machine code calls. |
11 | /// |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H |
15 | #define LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H |
16 | |
17 | #include "llvm/ADT/ArrayRef.h" |
18 | #include "llvm/ADT/SmallVector.h" |
19 | #include "llvm/CodeGen/CallingConvLower.h" |
20 | #include "llvm/CodeGen/MachineOperand.h" |
21 | #include "llvm/CodeGen/TargetCallingConv.h" |
22 | #include "llvm/CodeGenTypes/LowLevelType.h" |
23 | #include "llvm/CodeGenTypes/MachineValueType.h" |
24 | #include "llvm/IR/CallingConv.h" |
25 | #include "llvm/IR/Type.h" |
26 | #include "llvm/IR/Value.h" |
27 | #include "llvm/Support/ErrorHandling.h" |
28 | #include <cstdint> |
29 | #include <functional> |
30 | |
31 | namespace llvm { |
32 | |
33 | class AttributeList; |
34 | class CallBase; |
35 | class DataLayout; |
36 | class Function; |
37 | class FunctionLoweringInfo; |
38 | class MachineIRBuilder; |
39 | class MachineFunction; |
40 | struct MachinePointerInfo; |
41 | class MachineRegisterInfo; |
42 | class TargetLowering; |
43 | |
44 | class CallLowering { |
45 | const TargetLowering *TLI; |
46 | |
47 | virtual void anchor(); |
48 | public: |
49 | struct BaseArgInfo { |
50 | Type *Ty; |
51 | SmallVector<ISD::ArgFlagsTy, 4> Flags; |
52 | bool IsFixed; |
53 | |
54 | BaseArgInfo(Type *Ty, |
55 | ArrayRef<ISD::ArgFlagsTy> Flags = ArrayRef<ISD::ArgFlagsTy>(), |
56 | bool IsFixed = true) |
57 | : Ty(Ty), Flags(Flags.begin(), Flags.end()), IsFixed(IsFixed) {} |
58 | |
59 | BaseArgInfo() : Ty(nullptr), IsFixed(false) {} |
60 | }; |
61 | |
62 | struct ArgInfo : public BaseArgInfo { |
63 | SmallVector<Register, 4> Regs; |
64 | // If the argument had to be split into multiple parts according to the |
65 | // target calling convention, then this contains the original vregs |
66 | // if the argument was an incoming arg. |
67 | SmallVector<Register, 2> OrigRegs; |
68 | |
69 | /// Optionally track the original IR value for the argument. This may not be |
70 | /// meaningful in all contexts. This should only be used on for forwarding |
71 | /// through to use for aliasing information in MachinePointerInfo for memory |
72 | /// arguments. |
73 | const Value *OrigValue = nullptr; |
74 | |
75 | /// Index original Function's argument. |
76 | unsigned OrigArgIndex; |
77 | |
78 | /// Sentinel value for implicit machine-level input arguments. |
79 | static const unsigned NoArgIndex = UINT_MAX; |
80 | |
81 | ArgInfo(ArrayRef<Register> Regs, Type *Ty, unsigned OrigIndex, |
82 | ArrayRef<ISD::ArgFlagsTy> Flags = ArrayRef<ISD::ArgFlagsTy>(), |
83 | bool IsFixed = true, const Value *OrigValue = nullptr) |
84 | : BaseArgInfo(Ty, Flags, IsFixed), Regs(Regs.begin(), Regs.end()), |
85 | OrigValue(OrigValue), OrigArgIndex(OrigIndex) { |
86 | if (!Regs.empty() && Flags.empty()) |
87 | this->Flags.push_back(Elt: ISD::ArgFlagsTy()); |
88 | // FIXME: We should have just one way of saying "no register". |
89 | assert(((Ty->isVoidTy() || Ty->isEmptyTy()) == |
90 | (Regs.empty() || Regs[0] == 0)) && |
91 | "only void types should have no register" ); |
92 | } |
93 | |
94 | ArgInfo(ArrayRef<Register> Regs, const Value &OrigValue, unsigned OrigIndex, |
95 | ArrayRef<ISD::ArgFlagsTy> Flags = ArrayRef<ISD::ArgFlagsTy>(), |
96 | bool IsFixed = true) |
97 | : ArgInfo(Regs, OrigValue.getType(), OrigIndex, Flags, IsFixed, &OrigValue) {} |
98 | |
99 | ArgInfo() = default; |
100 | }; |
101 | |
102 | struct CallLoweringInfo { |
103 | /// Calling convention to be used for the call. |
104 | CallingConv::ID CallConv = CallingConv::C; |
105 | |
106 | /// Destination of the call. It should be either a register, globaladdress, |
107 | /// or externalsymbol. |
108 | MachineOperand Callee = MachineOperand::CreateImm(Val: 0); |
109 | |
110 | /// Descriptor for the return type of the function. |
111 | ArgInfo OrigRet; |
112 | |
113 | /// List of descriptors of the arguments passed to the function. |
114 | SmallVector<ArgInfo, 32> OrigArgs; |
115 | |
116 | /// Valid if the call has a swifterror inout parameter, and contains the |
117 | /// vreg that the swifterror should be copied into after the call. |
118 | Register SwiftErrorVReg; |
119 | |
120 | /// Valid if the call is a controlled convergent operation. |
121 | Register ConvergenceCtrlToken; |
122 | |
123 | /// Original IR callsite corresponding to this call, if available. |
124 | const CallBase *CB = nullptr; |
125 | |
126 | MDNode *KnownCallees = nullptr; |
127 | |
128 | /// True if the call must be tail call optimized. |
129 | bool IsMustTailCall = false; |
130 | |
131 | /// True if the call passes all target-independent checks for tail call |
132 | /// optimization. |
133 | bool IsTailCall = false; |
134 | |
135 | /// True if the call was lowered as a tail call. This is consumed by the |
136 | /// legalizer. This allows the legalizer to lower libcalls as tail calls. |
137 | bool LoweredTailCall = false; |
138 | |
139 | /// True if the call is to a vararg function. |
140 | bool IsVarArg = false; |
141 | |
142 | /// True if the function's return value can be lowered to registers. |
143 | bool CanLowerReturn = true; |
144 | |
145 | /// VReg to hold the hidden sret parameter. |
146 | Register DemoteRegister; |
147 | |
148 | /// The stack index for sret demotion. |
149 | int DemoteStackIndex; |
150 | |
151 | /// Expected type identifier for indirect calls with a CFI check. |
152 | const ConstantInt *CFIType = nullptr; |
153 | |
154 | /// True if this call results in convergent operations. |
155 | bool IsConvergent = true; |
156 | }; |
157 | |
158 | /// Argument handling is mostly uniform between the four places that |
159 | /// make these decisions: function formal arguments, call |
160 | /// instruction args, call instruction returns and function |
161 | /// returns. However, once a decision has been made on where an |
162 | /// argument should go, exactly what happens can vary slightly. This |
163 | /// class abstracts the differences. |
164 | /// |
165 | /// ValueAssigner should not depend on any specific function state, and |
166 | /// only determine the types and locations for arguments. |
167 | struct ValueAssigner { |
168 | ValueAssigner(bool IsIncoming, CCAssignFn *AssignFn_, |
169 | CCAssignFn *AssignFnVarArg_ = nullptr) |
170 | : AssignFn(AssignFn_), AssignFnVarArg(AssignFnVarArg_), |
171 | IsIncomingArgumentHandler(IsIncoming) { |
172 | |
173 | // Some targets change the handler depending on whether the call is |
174 | // varargs or not. If |
175 | if (!AssignFnVarArg) |
176 | AssignFnVarArg = AssignFn; |
177 | } |
178 | |
179 | virtual ~ValueAssigner() = default; |
180 | |
181 | /// Returns true if the handler is dealing with incoming arguments, |
182 | /// i.e. those that move values from some physical location to vregs. |
183 | bool isIncomingArgumentHandler() const { |
184 | return IsIncomingArgumentHandler; |
185 | } |
186 | |
187 | /// Wrap call to (typically tablegenerated CCAssignFn). This may be |
188 | /// overridden to track additional state information as arguments are |
189 | /// assigned or apply target specific hacks around the legacy |
190 | /// infrastructure. |
191 | virtual bool assignArg(unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT, |
192 | CCValAssign::LocInfo LocInfo, const ArgInfo &Info, |
193 | ISD::ArgFlagsTy Flags, CCState &State) { |
194 | if (getAssignFn(IsVarArg: State.isVarArg())(ValNo, ValVT, LocVT, LocInfo, Flags, |
195 | State)) |
196 | return true; |
197 | StackSize = State.getStackSize(); |
198 | return false; |
199 | } |
200 | |
201 | /// Assignment function to use for a general call. |
202 | CCAssignFn *AssignFn; |
203 | |
204 | /// Assignment function to use for a variadic call. This is usually the same |
205 | /// as AssignFn on most targets. |
206 | CCAssignFn *AssignFnVarArg; |
207 | |
208 | /// The size of the currently allocated portion of the stack. |
209 | uint64_t StackSize = 0; |
210 | |
211 | /// Select the appropriate assignment function depending on whether this is |
212 | /// a variadic call. |
213 | CCAssignFn *getAssignFn(bool IsVarArg) const { |
214 | return IsVarArg ? AssignFnVarArg : AssignFn; |
215 | } |
216 | |
217 | private: |
218 | const bool IsIncomingArgumentHandler; |
219 | virtual void anchor(); |
220 | }; |
221 | |
222 | struct IncomingValueAssigner : public ValueAssigner { |
223 | IncomingValueAssigner(CCAssignFn *AssignFn_, |
224 | CCAssignFn *AssignFnVarArg_ = nullptr) |
225 | : ValueAssigner(true, AssignFn_, AssignFnVarArg_) {} |
226 | }; |
227 | |
228 | struct OutgoingValueAssigner : public ValueAssigner { |
229 | OutgoingValueAssigner(CCAssignFn *AssignFn_, |
230 | CCAssignFn *AssignFnVarArg_ = nullptr) |
231 | : ValueAssigner(false, AssignFn_, AssignFnVarArg_) {} |
232 | }; |
233 | |
234 | struct ValueHandler { |
235 | MachineIRBuilder &MIRBuilder; |
236 | MachineRegisterInfo &MRI; |
237 | const bool IsIncomingArgumentHandler; |
238 | |
239 | ValueHandler(bool IsIncoming, MachineIRBuilder &MIRBuilder, |
240 | MachineRegisterInfo &MRI) |
241 | : MIRBuilder(MIRBuilder), MRI(MRI), |
242 | IsIncomingArgumentHandler(IsIncoming) {} |
243 | |
244 | virtual ~ValueHandler() = default; |
245 | |
246 | /// Returns true if the handler is dealing with incoming arguments, |
247 | /// i.e. those that move values from some physical location to vregs. |
248 | bool isIncomingArgumentHandler() const { |
249 | return IsIncomingArgumentHandler; |
250 | } |
251 | |
252 | /// Materialize a VReg containing the address of the specified |
253 | /// stack-based object. This is either based on a FrameIndex or |
254 | /// direct SP manipulation, depending on the context. \p MPO |
255 | /// should be initialized to an appropriate description of the |
256 | /// address created. |
257 | virtual Register getStackAddress(uint64_t MemSize, int64_t Offset, |
258 | MachinePointerInfo &MPO, |
259 | ISD::ArgFlagsTy Flags) = 0; |
260 | |
261 | /// Return the in-memory size to write for the argument at \p VA. This may |
262 | /// be smaller than the allocated stack slot size. |
263 | /// |
264 | /// This is overridable primarily for targets to maintain compatibility with |
265 | /// hacks around the existing DAG call lowering infrastructure. |
266 | virtual LLT getStackValueStoreType(const DataLayout &DL, |
267 | const CCValAssign &VA, |
268 | ISD::ArgFlagsTy Flags) const; |
269 | |
270 | /// The specified value has been assigned to a physical register, |
271 | /// handle the appropriate COPY (either to or from) and mark any |
272 | /// relevant uses/defines as needed. |
273 | virtual void assignValueToReg(Register ValVReg, Register PhysReg, |
274 | const CCValAssign &VA) = 0; |
275 | |
276 | /// The specified value has been assigned to a stack |
277 | /// location. Load or store it there, with appropriate extension |
278 | /// if necessary. |
279 | virtual void assignValueToAddress(Register ValVReg, Register Addr, |
280 | LLT MemTy, const MachinePointerInfo &MPO, |
281 | const CCValAssign &VA) = 0; |
282 | |
283 | /// An overload which takes an ArgInfo if additional information about the |
284 | /// arg is needed. \p ValRegIndex is the index in \p Arg.Regs for the value |
285 | /// to store. |
286 | virtual void assignValueToAddress(const ArgInfo &Arg, unsigned ValRegIndex, |
287 | Register Addr, LLT MemTy, |
288 | const MachinePointerInfo &MPO, |
289 | const CCValAssign &VA) { |
290 | assignValueToAddress(ValVReg: Arg.Regs[ValRegIndex], Addr, MemTy, MPO, VA); |
291 | } |
292 | |
293 | /// Handle custom values, which may be passed into one or more of \p VAs. |
294 | /// \p If the handler wants the assignments to be delayed until after |
295 | /// mem loc assignments, then it sets \p Thunk to the thunk to do the |
296 | /// assignment. |
297 | /// \return The number of \p VAs that have been assigned including the |
298 | /// first one, and which should therefore be skipped from further |
299 | /// processing. |
300 | virtual unsigned assignCustomValue(ArgInfo &Arg, ArrayRef<CCValAssign> VAs, |
301 | std::function<void()> *Thunk = nullptr) { |
302 | // This is not a pure virtual method because not all targets need to worry |
303 | // about custom values. |
304 | llvm_unreachable("Custom values not supported" ); |
305 | } |
306 | |
307 | /// Do a memory copy of \p MemSize bytes from \p SrcPtr to \p DstPtr. This |
308 | /// is necessary for outgoing stack-passed byval arguments. |
309 | void |
310 | copyArgumentMemory(const ArgInfo &Arg, Register DstPtr, Register SrcPtr, |
311 | const MachinePointerInfo &DstPtrInfo, Align DstAlign, |
312 | const MachinePointerInfo &SrcPtrInfo, Align SrcAlign, |
313 | uint64_t MemSize, CCValAssign &VA) const; |
314 | |
315 | /// Extend a register to the location type given in VA, capped at extending |
316 | /// to at most MaxSize bits. If MaxSizeBits is 0 then no maximum is set. |
317 | Register extendRegister(Register ValReg, const CCValAssign &VA, |
318 | unsigned MaxSizeBits = 0); |
319 | }; |
320 | |
321 | /// Base class for ValueHandlers used for arguments coming into the current |
322 | /// function, or for return values received from a call. |
323 | struct IncomingValueHandler : public ValueHandler { |
324 | IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI) |
325 | : ValueHandler(/*IsIncoming*/ true, MIRBuilder, MRI) {} |
326 | |
327 | /// Insert G_ASSERT_ZEXT/G_ASSERT_SEXT or other hint instruction based on \p |
328 | /// VA, returning the new register if a hint was inserted. |
329 | Register buildExtensionHint(const CCValAssign &VA, Register SrcReg, |
330 | LLT NarrowTy); |
331 | |
332 | /// Provides a default implementation for argument handling. |
333 | void assignValueToReg(Register ValVReg, Register PhysReg, |
334 | const CCValAssign &VA) override; |
335 | }; |
336 | |
337 | /// Base class for ValueHandlers used for arguments passed to a function call, |
338 | /// or for return values. |
339 | struct OutgoingValueHandler : public ValueHandler { |
340 | OutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI) |
341 | : ValueHandler(/*IsIncoming*/ false, MIRBuilder, MRI) {} |
342 | }; |
343 | |
344 | protected: |
345 | /// Getter for generic TargetLowering class. |
346 | const TargetLowering *getTLI() const { |
347 | return TLI; |
348 | } |
349 | |
350 | /// Getter for target specific TargetLowering class. |
351 | template <class XXXTargetLowering> |
352 | const XXXTargetLowering *getTLI() const { |
353 | return static_cast<const XXXTargetLowering *>(TLI); |
354 | } |
355 | |
356 | /// \returns Flags corresponding to the attributes on the \p ArgIdx-th |
357 | /// parameter of \p Call. |
358 | ISD::ArgFlagsTy getAttributesForArgIdx(const CallBase &Call, |
359 | unsigned ArgIdx) const; |
360 | |
361 | /// \returns Flags corresponding to the attributes on the return from \p Call. |
362 | ISD::ArgFlagsTy getAttributesForReturn(const CallBase &Call) const; |
363 | |
364 | /// Adds flags to \p Flags based off of the attributes in \p Attrs. |
365 | /// \p OpIdx is the index in \p Attrs to add flags from. |
366 | void addArgFlagsFromAttributes(ISD::ArgFlagsTy &Flags, |
367 | const AttributeList &Attrs, |
368 | unsigned OpIdx) const; |
369 | |
370 | template <typename FuncInfoTy> |
371 | void setArgFlags(ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL, |
372 | const FuncInfoTy &FuncInfo) const; |
373 | |
374 | /// Break \p OrigArgInfo into one or more pieces the calling convention can |
375 | /// process, returned in \p SplitArgs. For example, this should break structs |
376 | /// down into individual fields. |
377 | /// |
378 | /// If \p Offsets is non-null, it points to a vector to be filled in |
379 | /// with the in-memory offsets of each of the individual values. |
380 | void splitToValueTypes(const ArgInfo &OrigArgInfo, |
381 | SmallVectorImpl<ArgInfo> &SplitArgs, |
382 | const DataLayout &DL, CallingConv::ID CallConv, |
383 | SmallVectorImpl<uint64_t> *Offsets = nullptr) const; |
384 | |
385 | /// Analyze the argument list in \p Args, using \p Assigner to populate \p |
386 | /// CCInfo. This will determine the types and locations to use for passed or |
387 | /// returned values. This may resize fields in \p Args if the value is split |
388 | /// across multiple registers or stack slots. |
389 | /// |
390 | /// This is independent of the function state and can be used |
391 | /// to determine how a call would pass arguments without needing to change the |
392 | /// function. This can be used to check if arguments are suitable for tail |
393 | /// call lowering. |
394 | /// |
395 | /// \return True if everything has succeeded, false otherwise. |
396 | bool determineAssignments(ValueAssigner &Assigner, |
397 | SmallVectorImpl<ArgInfo> &Args, |
398 | CCState &CCInfo) const; |
399 | |
400 | /// Invoke ValueAssigner::assignArg on each of the given \p Args and then use |
401 | /// \p Handler to move them to the assigned locations. |
402 | /// |
403 | /// \return True if everything has succeeded, false otherwise. |
404 | bool determineAndHandleAssignments( |
405 | ValueHandler &Handler, ValueAssigner &Assigner, |
406 | SmallVectorImpl<ArgInfo> &Args, MachineIRBuilder &MIRBuilder, |
407 | CallingConv::ID CallConv, bool IsVarArg, |
408 | ArrayRef<Register> ThisReturnRegs = std::nullopt) const; |
409 | |
410 | /// Use \p Handler to insert code to handle the argument/return values |
411 | /// represented by \p Args. It's expected determineAssignments previously |
412 | /// processed these arguments to populate \p CCState and \p ArgLocs. |
413 | bool |
414 | handleAssignments(ValueHandler &Handler, SmallVectorImpl<ArgInfo> &Args, |
415 | CCState &CCState, SmallVectorImpl<CCValAssign> &ArgLocs, |
416 | MachineIRBuilder &MIRBuilder, |
417 | ArrayRef<Register> ThisReturnRegs = std::nullopt) const; |
418 | |
419 | /// Check whether parameters to a call that are passed in callee saved |
420 | /// registers are the same as from the calling function. This needs to be |
421 | /// checked for tail call eligibility. |
422 | bool parametersInCSRMatch(const MachineRegisterInfo &MRI, |
423 | const uint32_t *CallerPreservedMask, |
424 | const SmallVectorImpl<CCValAssign> &ArgLocs, |
425 | const SmallVectorImpl<ArgInfo> &OutVals) const; |
426 | |
427 | /// \returns True if the calling convention for a callee and its caller pass |
428 | /// results in the same way. Typically used for tail call eligibility checks. |
429 | /// |
430 | /// \p Info is the CallLoweringInfo for the call. |
431 | /// \p MF is the MachineFunction for the caller. |
432 | /// \p InArgs contains the results of the call. |
433 | /// \p CalleeAssigner specifies the target's handling of the argument types |
434 | /// for the callee. |
435 | /// \p CallerAssigner specifies the target's handling of the |
436 | /// argument types for the caller. |
437 | bool resultsCompatible(CallLoweringInfo &Info, MachineFunction &MF, |
438 | SmallVectorImpl<ArgInfo> &InArgs, |
439 | ValueAssigner &CalleeAssigner, |
440 | ValueAssigner &CallerAssigner) const; |
441 | |
442 | public: |
443 | CallLowering(const TargetLowering *TLI) : TLI(TLI) {} |
444 | virtual ~CallLowering() = default; |
445 | |
446 | /// \return true if the target is capable of handling swifterror values that |
447 | /// have been promoted to a specified register. The extended versions of |
448 | /// lowerReturn and lowerCall should be implemented. |
449 | virtual bool supportSwiftError() const { |
450 | return false; |
451 | } |
452 | |
453 | /// Load the returned value from the stack into virtual registers in \p VRegs. |
454 | /// It uses the frame index \p FI and the start offset from \p DemoteReg. |
455 | /// The loaded data size will be determined from \p RetTy. |
456 | void insertSRetLoads(MachineIRBuilder &MIRBuilder, Type *RetTy, |
457 | ArrayRef<Register> VRegs, Register DemoteReg, |
458 | int FI) const; |
459 | |
460 | /// Store the return value given by \p VRegs into stack starting at the offset |
461 | /// specified in \p DemoteReg. |
462 | void insertSRetStores(MachineIRBuilder &MIRBuilder, Type *RetTy, |
463 | ArrayRef<Register> VRegs, Register DemoteReg) const; |
464 | |
465 | /// Insert the hidden sret ArgInfo to the beginning of \p SplitArgs. |
466 | /// This function should be called from the target specific |
467 | /// lowerFormalArguments when \p F requires the sret demotion. |
468 | void insertSRetIncomingArgument(const Function &F, |
469 | SmallVectorImpl<ArgInfo> &SplitArgs, |
470 | Register &DemoteReg, MachineRegisterInfo &MRI, |
471 | const DataLayout &DL) const; |
472 | |
473 | /// For the call-base described by \p CB, insert the hidden sret ArgInfo to |
474 | /// the OrigArgs field of \p Info. |
475 | void insertSRetOutgoingArgument(MachineIRBuilder &MIRBuilder, |
476 | const CallBase &CB, |
477 | CallLoweringInfo &Info) const; |
478 | |
479 | /// \return True if the return type described by \p Outs can be returned |
480 | /// without performing sret demotion. |
481 | bool checkReturn(CCState &CCInfo, SmallVectorImpl<BaseArgInfo> &Outs, |
482 | CCAssignFn *Fn) const; |
483 | |
484 | /// Get the type and the ArgFlags for the split components of \p RetTy as |
485 | /// returned by \c ComputeValueVTs. |
486 | void getReturnInfo(CallingConv::ID CallConv, Type *RetTy, AttributeList Attrs, |
487 | SmallVectorImpl<BaseArgInfo> &Outs, |
488 | const DataLayout &DL) const; |
489 | |
490 | /// Toplevel function to check the return type based on the target calling |
491 | /// convention. \return True if the return value of \p MF can be returned |
492 | /// without performing sret demotion. |
493 | bool checkReturnTypeForCallConv(MachineFunction &MF) const; |
494 | |
495 | /// This hook must be implemented to check whether the return values |
496 | /// described by \p Outs can fit into the return registers. If false |
497 | /// is returned, an sret-demotion is performed. |
498 | virtual bool canLowerReturn(MachineFunction &MF, CallingConv::ID CallConv, |
499 | SmallVectorImpl<BaseArgInfo> &Outs, |
500 | bool IsVarArg) const { |
501 | return true; |
502 | } |
503 | |
504 | /// This hook must be implemented to lower outgoing return values, described |
505 | /// by \p Val, into the specified virtual registers \p VRegs. |
506 | /// This hook is used by GlobalISel. |
507 | /// |
508 | /// \p FLI is required for sret demotion. |
509 | /// |
510 | /// \p SwiftErrorVReg is non-zero if the function has a swifterror parameter |
511 | /// that needs to be implicitly returned. |
512 | /// |
513 | /// \return True if the lowering succeeds, false otherwise. |
514 | virtual bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, |
515 | ArrayRef<Register> VRegs, FunctionLoweringInfo &FLI, |
516 | Register SwiftErrorVReg) const { |
517 | if (!supportSwiftError()) { |
518 | assert(SwiftErrorVReg == 0 && "attempt to use unsupported swifterror" ); |
519 | return lowerReturn(MIRBuilder, Val, VRegs, FLI); |
520 | } |
521 | return false; |
522 | } |
523 | |
524 | /// This hook behaves as the extended lowerReturn function, but for targets |
525 | /// that do not support swifterror value promotion. |
526 | virtual bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, |
527 | ArrayRef<Register> VRegs, |
528 | FunctionLoweringInfo &FLI) const { |
529 | return false; |
530 | } |
531 | |
532 | virtual bool fallBackToDAGISel(const MachineFunction &MF) const { |
533 | return false; |
534 | } |
535 | |
536 | /// This hook must be implemented to lower the incoming (formal) |
537 | /// arguments, described by \p VRegs, for GlobalISel. Each argument |
538 | /// must end up in the related virtual registers described by \p VRegs. |
539 | /// In other words, the first argument should end up in \c VRegs[0], |
540 | /// the second in \c VRegs[1], and so on. For each argument, there will be one |
541 | /// register for each non-aggregate type, as returned by \c computeValueLLTs. |
542 | /// \p MIRBuilder is set to the proper insertion for the argument |
543 | /// lowering. \p FLI is required for sret demotion. |
544 | /// |
545 | /// \return True if the lowering succeeded, false otherwise. |
546 | virtual bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, |
547 | const Function &F, |
548 | ArrayRef<ArrayRef<Register>> VRegs, |
549 | FunctionLoweringInfo &FLI) const { |
550 | return false; |
551 | } |
552 | |
553 | /// This hook must be implemented to lower the given call instruction, |
554 | /// including argument and return value marshalling. |
555 | /// |
556 | /// |
557 | /// \return true if the lowering succeeded, false otherwise. |
558 | virtual bool lowerCall(MachineIRBuilder &MIRBuilder, |
559 | CallLoweringInfo &Info) const { |
560 | return false; |
561 | } |
562 | |
563 | /// Lower the given call instruction, including argument and return value |
564 | /// marshalling. |
565 | /// |
566 | /// \p CI is the call/invoke instruction. |
567 | /// |
568 | /// \p ResRegs are the registers where the call's return value should be |
569 | /// stored (or 0 if there is no return value). There will be one register for |
570 | /// each non-aggregate type, as returned by \c computeValueLLTs. |
571 | /// |
572 | /// \p ArgRegs is a list of lists of virtual registers containing each |
573 | /// argument that needs to be passed (argument \c i should be placed in \c |
574 | /// ArgRegs[i]). For each argument, there will be one register for each |
575 | /// non-aggregate type, as returned by \c computeValueLLTs. |
576 | /// |
577 | /// \p SwiftErrorVReg is non-zero if the call has a swifterror inout |
578 | /// parameter, and contains the vreg that the swifterror should be copied into |
579 | /// after the call. |
580 | /// |
581 | /// \p GetCalleeReg is a callback to materialize a register for the callee if |
582 | /// the target determines it cannot jump to the destination based purely on \p |
583 | /// CI. This might be because \p CI is indirect, or because of the limited |
584 | /// range of an immediate jump. |
585 | /// |
586 | /// \return true if the lowering succeeded, false otherwise. |
587 | bool lowerCall(MachineIRBuilder &MIRBuilder, const CallBase &Call, |
588 | ArrayRef<Register> ResRegs, |
589 | ArrayRef<ArrayRef<Register>> ArgRegs, Register SwiftErrorVReg, |
590 | Register ConvergenceCtrlToken, |
591 | std::function<unsigned()> GetCalleeReg) const; |
592 | |
593 | /// For targets which want to use big-endian can enable it with |
594 | /// enableBigEndian() hook |
595 | virtual bool enableBigEndian() const { return false; } |
596 | |
597 | /// For targets which support the "returned" parameter attribute, returns |
598 | /// true if the given type is a valid one to use with "returned". |
599 | virtual bool isTypeIsValidForThisReturn(EVT Ty) const { return false; } |
600 | }; |
601 | |
602 | } // end namespace llvm |
603 | |
604 | #endif // LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H |
605 | |