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