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