/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- llvm/CodeGen/GlobalISel/CallLowering.h - Call lowering ---*- C++ -*-===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | /// |
10 | | /// \file |
11 | | /// This file describes how to lower LLVM calls to machine code calls. |
12 | | /// |
13 | | //===----------------------------------------------------------------------===// |
14 | | |
15 | | #ifndef LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H |
16 | | #define LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H |
17 | | |
18 | | #include "llvm/ADT/ArrayRef.h" |
19 | | #include "llvm/CodeGen/CallingConvLower.h" |
20 | | #include "llvm/CodeGen/MachineValueType.h" |
21 | | #include "llvm/IR/CallSite.h" |
22 | | #include "llvm/IR/CallingConv.h" |
23 | | #include "llvm/Support/ErrorHandling.h" |
24 | | #include "llvm/Target/TargetCallingConv.h" |
25 | | #include <cstdint> |
26 | | #include <functional> |
27 | | |
28 | | namespace llvm { |
29 | | |
30 | | class DataLayout; |
31 | | class Function; |
32 | | class MachineIRBuilder; |
33 | | class MachineOperand; |
34 | | struct MachinePointerInfo; |
35 | | class MachineRegisterInfo; |
36 | | class TargetLowering; |
37 | | class Type; |
38 | | class Value; |
39 | | |
40 | | class CallLowering { |
41 | | const TargetLowering *TLI; |
42 | | |
43 | | public: |
44 | | struct ArgInfo { |
45 | | unsigned Reg; |
46 | | Type *Ty; |
47 | | ISD::ArgFlagsTy Flags; |
48 | | bool IsFixed; |
49 | | |
50 | | ArgInfo(unsigned Reg, Type *Ty, ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy{}, |
51 | | bool IsFixed = true) |
52 | 8.86M | : Reg(Reg), Ty(Ty), Flags(Flags), IsFixed(IsFixed) {} |
53 | | }; |
54 | | |
55 | | /// Argument handling is mostly uniform between the four places that |
56 | | /// make these decisions: function formal arguments, call |
57 | | /// instruction args, call instruction returns and function |
58 | | /// returns. However, once a decision has been made on where an |
59 | | /// arugment should go, exactly what happens can vary slightly. This |
60 | | /// class abstracts the differences. |
61 | | struct ValueHandler { |
62 | | ValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, |
63 | | CCAssignFn *AssignFn) |
64 | 2.44M | : MIRBuilder(MIRBuilder), MRI(MRI), AssignFn(AssignFn) {} |
65 | | |
66 | 2.44M | virtual ~ValueHandler() = default; |
67 | | |
68 | | /// Materialize a VReg containing the address of the specified |
69 | | /// stack-based object. This is either based on a FrameIndex or |
70 | | /// direct SP manipulation, depending on the context. \p MPO |
71 | | /// should be initialized to an appropriate description of the |
72 | | /// address created. |
73 | | virtual unsigned getStackAddress(uint64_t Size, int64_t Offset, |
74 | | MachinePointerInfo &MPO) = 0; |
75 | | |
76 | | /// The specified value has been assigned to a physical register, |
77 | | /// handle the appropriate COPY (either to or from) and mark any |
78 | | /// relevant uses/defines as needed. |
79 | | virtual void assignValueToReg(unsigned ValVReg, unsigned PhysReg, |
80 | | CCValAssign &VA) = 0; |
81 | | |
82 | | /// The specified value has been assigned to a stack |
83 | | /// location. Load or store it there, with appropriate extension |
84 | | /// if necessary. |
85 | | virtual void assignValueToAddress(unsigned ValVReg, unsigned Addr, |
86 | | uint64_t Size, MachinePointerInfo &MPO, |
87 | | CCValAssign &VA) = 0; |
88 | | |
89 | | /// Handle custom values, which may be passed into one or more of \p VAs. |
90 | | /// \return The number of \p VAs that have been assigned after the first |
91 | | /// one, and which should therefore be skipped from further |
92 | | /// processing. |
93 | | virtual unsigned assignCustomValue(const ArgInfo &Arg, |
94 | 0 | ArrayRef<CCValAssign> VAs) { |
95 | 0 | // This is not a pure virtual method because not all targets need to worry |
96 | 0 | // about custom values. |
97 | 0 | llvm_unreachable("Custom values not supported"); |
98 | 0 | } |
99 | | |
100 | | unsigned extendRegister(unsigned ValReg, CCValAssign &VA); |
101 | | |
102 | | virtual bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT, |
103 | | CCValAssign::LocInfo LocInfo, const ArgInfo &Info, |
104 | 1.33M | CCState &State) { |
105 | 1.33M | return AssignFn(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State); |
106 | 1.33M | } |
107 | | |
108 | | MachineIRBuilder &MIRBuilder; |
109 | | MachineRegisterInfo &MRI; |
110 | | CCAssignFn *AssignFn; |
111 | | }; |
112 | | |
113 | | protected: |
114 | | /// Getter for generic TargetLowering class. |
115 | 2 | const TargetLowering *getTLI() const { |
116 | 2 | return TLI; |
117 | 2 | } |
118 | | |
119 | | /// Getter for target specific TargetLowering class. |
120 | | template <class XXXTargetLowering> |
121 | 5.88M | const XXXTargetLowering *getTLI() const { |
122 | 5.88M | return static_cast<const XXXTargetLowering *>(TLI); |
123 | 5.88M | } llvm::AArch64TargetLowering const* llvm::CallLowering::getTLI<llvm::AArch64TargetLowering>() const Line | Count | Source | 121 | 5.88M | const XXXTargetLowering *getTLI() const { | 122 | 5.88M | return static_cast<const XXXTargetLowering *>(TLI); | 123 | 5.88M | } |
llvm::AMDGPUTargetLowering const* llvm::CallLowering::getTLI<llvm::AMDGPUTargetLowering>() const Line | Count | Source | 121 | 20 | const XXXTargetLowering *getTLI() const { | 122 | 20 | return static_cast<const XXXTargetLowering *>(TLI); | 123 | 20 | } |
llvm::ARMTargetLowering const* llvm::CallLowering::getTLI<llvm::ARMTargetLowering>() const Line | Count | Source | 121 | 2.02k | const XXXTargetLowering *getTLI() const { | 122 | 2.02k | return static_cast<const XXXTargetLowering *>(TLI); | 123 | 2.02k | } |
llvm::X86TargetLowering const* llvm::CallLowering::getTLI<llvm::X86TargetLowering>() const Line | Count | Source | 121 | 1.06k | const XXXTargetLowering *getTLI() const { | 122 | 1.06k | return static_cast<const XXXTargetLowering *>(TLI); | 123 | 1.06k | } |
|
124 | | |
125 | | template <typename FuncInfoTy> |
126 | | void setArgFlags(ArgInfo &Arg, unsigned OpNum, const DataLayout &DL, |
127 | | const FuncInfoTy &FuncInfo) const; |
128 | | |
129 | | /// Invoke Handler::assignArg on each of the given \p Args and then use |
130 | | /// \p Callback to move them to the assigned locations. |
131 | | /// |
132 | | /// \return True if everything has succeeded, false otherwise. |
133 | | bool handleAssignments(MachineIRBuilder &MIRBuilder, ArrayRef<ArgInfo> Args, |
134 | | ValueHandler &Callback) const; |
135 | | |
136 | | public: |
137 | 31.5k | CallLowering(const TargetLowering *TLI) : TLI(TLI) {} |
138 | 15.1k | virtual ~CallLowering() = default; |
139 | | |
140 | | /// This hook must be implemented to lower outgoing return values, described |
141 | | /// by \p Val, into the specified virtual register \p VReg. |
142 | | /// This hook is used by GlobalISel. |
143 | | /// |
144 | | /// \return True if the lowering succeeds, false otherwise. |
145 | | virtual bool lowerReturn(MachineIRBuilder &MIRBuilder, |
146 | 0 | const Value *Val, unsigned VReg) const { |
147 | 0 | return false; |
148 | 0 | } |
149 | | |
150 | | /// This hook must be implemented to lower the incoming (formal) |
151 | | /// arguments, described by \p Args, for GlobalISel. Each argument |
152 | | /// must end up in the related virtual register described by VRegs. |
153 | | /// In other words, the first argument should end up in VRegs[0], |
154 | | /// the second in VRegs[1], and so on. |
155 | | /// \p MIRBuilder is set to the proper insertion for the argument |
156 | | /// lowering. |
157 | | /// |
158 | | /// \return True if the lowering succeeded, false otherwise. |
159 | | virtual bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, |
160 | | const Function &F, |
161 | 0 | ArrayRef<unsigned> VRegs) const { |
162 | 0 | return false; |
163 | 0 | } |
164 | | |
165 | | /// This hook must be implemented to lower the given call instruction, |
166 | | /// including argument and return value marshalling. |
167 | | /// |
168 | | /// \p CallConv is the calling convention to be used for the call. |
169 | | /// |
170 | | /// \p Callee is the destination of the call. It should be either a register, |
171 | | /// globaladdress, or externalsymbol. |
172 | | /// |
173 | | /// \p ResTy is the type returned by the function |
174 | | /// |
175 | | /// \p ResReg is the generic virtual register that the returned |
176 | | /// value should be lowered into. |
177 | | /// |
178 | | /// \p ArgTys is a list of the types each member of \p ArgRegs has; used by |
179 | | /// the target to decide which register/stack slot should be allocated. |
180 | | /// |
181 | | /// \p ArgRegs is a list of virtual registers containing each argument that |
182 | | /// needs to be passed. |
183 | | /// |
184 | | /// \return true if the lowering succeeded, false otherwise. |
185 | | virtual bool lowerCall(MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv, |
186 | | const MachineOperand &Callee, const ArgInfo &OrigRet, |
187 | 0 | ArrayRef<ArgInfo> OrigArgs) const { |
188 | 0 | return false; |
189 | 0 | } |
190 | | |
191 | | /// Lower the given call instruction, including argument and return value |
192 | | /// marshalling. |
193 | | /// |
194 | | /// \p CI is the call/invoke instruction. |
195 | | /// |
196 | | /// \p ResReg is a register where the call's return value should be stored (or |
197 | | /// 0 if there is no return value). |
198 | | /// |
199 | | /// \p ArgRegs is a list of virtual registers containing each argument that |
200 | | /// needs to be passed. |
201 | | /// |
202 | | /// \p GetCalleeReg is a callback to materialize a register for the callee if |
203 | | /// the target determines it cannot jump to the destination based purely on \p |
204 | | /// CI. This might be because \p CI is indirect, or because of the limited |
205 | | /// range of an immediate jump. |
206 | | /// |
207 | | /// \return true if the lowering succeeded, false otherwise. |
208 | | bool lowerCall(MachineIRBuilder &MIRBuilder, ImmutableCallSite CS, |
209 | | unsigned ResReg, ArrayRef<unsigned> ArgRegs, |
210 | | std::function<unsigned()> GetCalleeReg) const; |
211 | | }; |
212 | | |
213 | | } // end namespace llvm |
214 | | |
215 | | #endif // LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H |