/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- llvm/CodeGen/GlobalISel/IRTranslator.h - IRTranslator ----*- 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 | | /// \file |
10 | | /// This file declares the IRTranslator pass. |
11 | | /// This pass is responsible for translating LLVM IR into MachineInstr. |
12 | | /// It uses target hooks to lower the ABI but aside from that, the pass |
13 | | /// generated code is generic. This is the default translator used for |
14 | | /// GlobalISel. |
15 | | /// |
16 | | /// \todo Replace the comments with actual doxygen comments. |
17 | | //===----------------------------------------------------------------------===// |
18 | | |
19 | | #ifndef LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H |
20 | | #define LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H |
21 | | |
22 | | #include "llvm/ADT/DenseMap.h" |
23 | | #include "llvm/ADT/SmallVector.h" |
24 | | #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" |
25 | | #include "llvm/CodeGen/GlobalISel/Types.h" |
26 | | #include "llvm/CodeGen/MachineFunctionPass.h" |
27 | | #include "llvm/IR/Intrinsics.h" |
28 | | #include <memory> |
29 | | #include <utility> |
30 | | |
31 | | namespace llvm { |
32 | | |
33 | | class AllocaInst; |
34 | | class BasicBlock; |
35 | | class CallInst; |
36 | | class CallLowering; |
37 | | class Constant; |
38 | | class DataLayout; |
39 | | class Instruction; |
40 | | class MachineBasicBlock; |
41 | | class MachineFunction; |
42 | | class MachineInstr; |
43 | | class MachineRegisterInfo; |
44 | | class OptimizationRemarkEmitter; |
45 | | class PHINode; |
46 | | class TargetPassConfig; |
47 | | class User; |
48 | | class Value; |
49 | | |
50 | | // Technically the pass should run on an hypothetical MachineModule, |
51 | | // since it should translate Global into some sort of MachineGlobal. |
52 | | // The MachineGlobal should ultimately just be a transfer of ownership of |
53 | | // the interesting bits that are relevant to represent a global value. |
54 | | // That being said, we could investigate what would it cost to just duplicate |
55 | | // the information from the LLVM IR. |
56 | | // The idea is that ultimately we would be able to free up the memory used |
57 | | // by the LLVM IR as soon as the translation is over. |
58 | | class IRTranslator : public MachineFunctionPass { |
59 | | public: |
60 | | static char ID; |
61 | | |
62 | | private: |
63 | | /// Interface used to lower the everything related to calls. |
64 | | const CallLowering *CLI; |
65 | | |
66 | | /// Mapping of the values of the current LLVM IR function |
67 | | /// to the related virtual registers. |
68 | | ValueToVReg ValToVReg; |
69 | | |
70 | | // N.b. it's not completely obvious that this will be sufficient for every |
71 | | // LLVM IR construct (with "invoke" being the obvious candidate to mess up our |
72 | | // lives. |
73 | | DenseMap<const BasicBlock *, MachineBasicBlock *> BBToMBB; |
74 | | |
75 | | // One BasicBlock can be translated to multiple MachineBasicBlocks. For such |
76 | | // BasicBlocks translated to multiple MachineBasicBlocks, MachinePreds retains |
77 | | // a mapping between the edges arriving at the BasicBlock to the corresponding |
78 | | // created MachineBasicBlocks. Some BasicBlocks that get translated to a |
79 | | // single MachineBasicBlock may also end up in this Map. |
80 | | using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>; |
81 | | DenseMap<CFGEdge, SmallVector<MachineBasicBlock *, 1>> MachinePreds; |
82 | | |
83 | | // List of stubbed PHI instructions, for values and basic blocks to be filled |
84 | | // in once all MachineBasicBlocks have been created. |
85 | | SmallVector<std::pair<const PHINode *, MachineInstr *>, 4> PendingPHIs; |
86 | | |
87 | | /// Record of what frame index has been allocated to specified allocas for |
88 | | /// this function. |
89 | | DenseMap<const AllocaInst *, int> FrameIndices; |
90 | | |
91 | | /// \name Methods for translating form LLVM IR to MachineInstr. |
92 | | /// \see ::translate for general information on the translate methods. |
93 | | /// @{ |
94 | | |
95 | | /// Translate \p Inst into its corresponding MachineInstr instruction(s). |
96 | | /// Insert the newly translated instruction(s) right where the CurBuilder |
97 | | /// is set. |
98 | | /// |
99 | | /// The general algorithm is: |
100 | | /// 1. Look for a virtual register for each operand or |
101 | | /// create one. |
102 | | /// 2 Update the ValToVReg accordingly. |
103 | | /// 2.alt. For constant arguments, if they are compile time constants, |
104 | | /// produce an immediate in the right operand and do not touch |
105 | | /// ValToReg. Actually we will go with a virtual register for each |
106 | | /// constants because it may be expensive to actually materialize the |
107 | | /// constant. Moreover, if the constant spans on several instructions, |
108 | | /// CSE may not catch them. |
109 | | /// => Update ValToVReg and remember that we saw a constant in Constants. |
110 | | /// We will materialize all the constants in finalize. |
111 | | /// Note: we would need to do something so that we can recognize such operand |
112 | | /// as constants. |
113 | | /// 3. Create the generic instruction. |
114 | | /// |
115 | | /// \return true if the translation succeeded. |
116 | | bool translate(const Instruction &Inst); |
117 | | |
118 | | /// Materialize \p C into virtual-register \p Reg. The generic instructions |
119 | | /// performing this materialization will be inserted into the entry block of |
120 | | /// the function. |
121 | | /// |
122 | | /// \return true if the materialization succeeded. |
123 | | bool translate(const Constant &C, unsigned Reg); |
124 | | |
125 | | /// Translate an LLVM bitcast into generic IR. Either a COPY or a G_BITCAST is |
126 | | /// emitted. |
127 | | bool translateBitCast(const User &U, MachineIRBuilder &MIRBuilder); |
128 | | |
129 | | /// Translate an LLVM load instruction into generic IR. |
130 | | bool translateLoad(const User &U, MachineIRBuilder &MIRBuilder); |
131 | | |
132 | | /// Translate an LLVM store instruction into generic IR. |
133 | | bool translateStore(const User &U, MachineIRBuilder &MIRBuilder); |
134 | | |
135 | | /// Translate an LLVM string intrinsic (memcpy, memset, ...). |
136 | | bool translateMemfunc(const CallInst &CI, MachineIRBuilder &MIRBuilder, |
137 | | unsigned Intrinsic); |
138 | | |
139 | | void getStackGuard(unsigned DstReg, MachineIRBuilder &MIRBuilder); |
140 | | |
141 | | bool translateOverflowIntrinsic(const CallInst &CI, unsigned Op, |
142 | | MachineIRBuilder &MIRBuilder); |
143 | | |
144 | | bool translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID, |
145 | | MachineIRBuilder &MIRBuilder); |
146 | | |
147 | | bool translateInlineAsm(const CallInst &CI, MachineIRBuilder &MIRBuilder); |
148 | | |
149 | | /// Translate call instruction. |
150 | | /// \pre \p U is a call instruction. |
151 | | bool translateCall(const User &U, MachineIRBuilder &MIRBuilder); |
152 | | |
153 | | bool translateInvoke(const User &U, MachineIRBuilder &MIRBuilder); |
154 | | |
155 | | bool translateLandingPad(const User &U, MachineIRBuilder &MIRBuilder); |
156 | | |
157 | | /// Translate one of LLVM's cast instructions into MachineInstrs, with the |
158 | | /// given generic Opcode. |
159 | | bool translateCast(unsigned Opcode, const User &U, |
160 | | MachineIRBuilder &MIRBuilder); |
161 | | |
162 | | /// Translate a phi instruction. |
163 | | bool translatePHI(const User &U, MachineIRBuilder &MIRBuilder); |
164 | | |
165 | | /// Translate a comparison (icmp or fcmp) instruction or constant. |
166 | | bool translateCompare(const User &U, MachineIRBuilder &MIRBuilder); |
167 | | |
168 | | /// Translate an integer compare instruction (or constant). |
169 | 953k | bool translateICmp(const User &U, MachineIRBuilder &MIRBuilder) { |
170 | 953k | return translateCompare(U, MIRBuilder); |
171 | 953k | } |
172 | | |
173 | | /// Translate a floating-point compare instruction (or constant). |
174 | 13.2k | bool translateFCmp(const User &U, MachineIRBuilder &MIRBuilder) { |
175 | 13.2k | return translateCompare(U, MIRBuilder); |
176 | 13.2k | } |
177 | | |
178 | | /// Add remaining operands onto phis we've translated. Executed after all |
179 | | /// MachineBasicBlocks for the function have been created. |
180 | | void finishPendingPhis(); |
181 | | |
182 | | /// Translate \p Inst into a binary operation \p Opcode. |
183 | | /// \pre \p U is a binary operation. |
184 | | bool translateBinaryOp(unsigned Opcode, const User &U, |
185 | | MachineIRBuilder &MIRBuilder); |
186 | | |
187 | | /// Translate branch (br) instruction. |
188 | | /// \pre \p U is a branch instruction. |
189 | | bool translateBr(const User &U, MachineIRBuilder &MIRBuilder); |
190 | | |
191 | | bool translateSwitch(const User &U, MachineIRBuilder &MIRBuilder); |
192 | | |
193 | | bool translateIndirectBr(const User &U, MachineIRBuilder &MIRBuilder); |
194 | | |
195 | | bool translateExtractValue(const User &U, MachineIRBuilder &MIRBuilder); |
196 | | |
197 | | bool translateInsertValue(const User &U, MachineIRBuilder &MIRBuilder); |
198 | | |
199 | | bool translateSelect(const User &U, MachineIRBuilder &MIRBuilder); |
200 | | |
201 | | bool translateGetElementPtr(const User &U, MachineIRBuilder &MIRBuilder); |
202 | | |
203 | | bool translateAlloca(const User &U, MachineIRBuilder &MIRBuilder); |
204 | | |
205 | | /// Translate return (ret) instruction. |
206 | | /// The target needs to implement CallLowering::lowerReturn for |
207 | | /// this to succeed. |
208 | | /// \pre \p U is a return instruction. |
209 | | bool translateRet(const User &U, MachineIRBuilder &MIRBuilder); |
210 | | |
211 | | bool translateFSub(const User &U, MachineIRBuilder &MIRBuilder); |
212 | | |
213 | 328k | bool translateAdd(const User &U, MachineIRBuilder &MIRBuilder) { |
214 | 328k | return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder); |
215 | 328k | } |
216 | 77.1k | bool translateSub(const User &U, MachineIRBuilder &MIRBuilder) { |
217 | 77.1k | return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder); |
218 | 77.1k | } |
219 | 89.8k | bool translateAnd(const User &U, MachineIRBuilder &MIRBuilder) { |
220 | 89.8k | return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder); |
221 | 89.8k | } |
222 | 77.5k | bool translateMul(const User &U, MachineIRBuilder &MIRBuilder) { |
223 | 77.5k | return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder); |
224 | 77.5k | } |
225 | 35.8k | bool translateOr(const User &U, MachineIRBuilder &MIRBuilder) { |
226 | 35.8k | return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder); |
227 | 35.8k | } |
228 | 9.38k | bool translateXor(const User &U, MachineIRBuilder &MIRBuilder) { |
229 | 9.38k | return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder); |
230 | 9.38k | } |
231 | | |
232 | 6.21k | bool translateUDiv(const User &U, MachineIRBuilder &MIRBuilder) { |
233 | 6.21k | return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder); |
234 | 6.21k | } |
235 | 3.91k | bool translateSDiv(const User &U, MachineIRBuilder &MIRBuilder) { |
236 | 3.91k | return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder); |
237 | 3.91k | } |
238 | 762 | bool translateURem(const User &U, MachineIRBuilder &MIRBuilder) { |
239 | 762 | return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder); |
240 | 762 | } |
241 | 2.01k | bool translateSRem(const User &U, MachineIRBuilder &MIRBuilder) { |
242 | 2.01k | return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder); |
243 | 2.01k | } |
244 | 24.9k | bool translateIntToPtr(const User &U, MachineIRBuilder &MIRBuilder) { |
245 | 24.9k | return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder); |
246 | 24.9k | } |
247 | 49.9k | bool translatePtrToInt(const User &U, MachineIRBuilder &MIRBuilder) { |
248 | 49.9k | return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder); |
249 | 49.9k | } |
250 | 158k | bool translateTrunc(const User &U, MachineIRBuilder &MIRBuilder) { |
251 | 158k | return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder); |
252 | 158k | } |
253 | 3.89k | bool translateFPTrunc(const User &U, MachineIRBuilder &MIRBuilder) { |
254 | 3.89k | return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder); |
255 | 3.89k | } |
256 | 12.5k | bool translateFPExt(const User &U, MachineIRBuilder &MIRBuilder) { |
257 | 12.5k | return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder); |
258 | 12.5k | } |
259 | 2.87k | bool translateFPToUI(const User &U, MachineIRBuilder &MIRBuilder) { |
260 | 2.87k | return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder); |
261 | 2.87k | } |
262 | 2.05k | bool translateFPToSI(const User &U, MachineIRBuilder &MIRBuilder) { |
263 | 2.05k | return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder); |
264 | 2.05k | } |
265 | 13.8k | bool translateUIToFP(const User &U, MachineIRBuilder &MIRBuilder) { |
266 | 13.8k | return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder); |
267 | 13.8k | } |
268 | 22.8k | bool translateSIToFP(const User &U, MachineIRBuilder &MIRBuilder) { |
269 | 22.8k | return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder); |
270 | 22.8k | } |
271 | 6.52k | bool translateUnreachable(const User &U, MachineIRBuilder &MIRBuilder) { |
272 | 6.52k | return true; |
273 | 6.52k | } |
274 | 162k | bool translateSExt(const User &U, MachineIRBuilder &MIRBuilder) { |
275 | 162k | return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder); |
276 | 162k | } |
277 | | |
278 | 92.0k | bool translateZExt(const User &U, MachineIRBuilder &MIRBuilder) { |
279 | 92.0k | return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder); |
280 | 92.0k | } |
281 | | |
282 | 50.4k | bool translateShl(const User &U, MachineIRBuilder &MIRBuilder) { |
283 | 50.4k | return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder); |
284 | 50.4k | } |
285 | 34.1k | bool translateLShr(const User &U, MachineIRBuilder &MIRBuilder) { |
286 | 34.1k | return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder); |
287 | 34.1k | } |
288 | 12.2k | bool translateAShr(const User &U, MachineIRBuilder &MIRBuilder) { |
289 | 12.2k | return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder); |
290 | 12.2k | } |
291 | | |
292 | 26.0k | bool translateFAdd(const User &U, MachineIRBuilder &MIRBuilder) { |
293 | 26.0k | return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder); |
294 | 26.0k | } |
295 | 22.0k | bool translateFMul(const User &U, MachineIRBuilder &MIRBuilder) { |
296 | 22.0k | return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder); |
297 | 22.0k | } |
298 | 25.1k | bool translateFDiv(const User &U, MachineIRBuilder &MIRBuilder) { |
299 | 25.1k | return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder); |
300 | 25.1k | } |
301 | 7 | bool translateFRem(const User &U, MachineIRBuilder &MIRBuilder) { |
302 | 7 | return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder); |
303 | 7 | } |
304 | | |
305 | | bool translateVAArg(const User &U, MachineIRBuilder &MIRBuilder); |
306 | | |
307 | | bool translateInsertElement(const User &U, MachineIRBuilder &MIRBuilder); |
308 | | |
309 | | bool translateExtractElement(const User &U, MachineIRBuilder &MIRBuilder); |
310 | | |
311 | | bool translateShuffleVector(const User &U, MachineIRBuilder &MIRBuilder); |
312 | | |
313 | | // Stubs to keep the compiler happy while we implement the rest of the |
314 | | // translation. |
315 | 0 | bool translateResume(const User &U, MachineIRBuilder &MIRBuilder) { |
316 | 0 | return false; |
317 | 0 | } |
318 | 0 | bool translateCleanupRet(const User &U, MachineIRBuilder &MIRBuilder) { |
319 | 0 | return false; |
320 | 0 | } |
321 | 0 | bool translateCatchRet(const User &U, MachineIRBuilder &MIRBuilder) { |
322 | 0 | return false; |
323 | 0 | } |
324 | 0 | bool translateCatchSwitch(const User &U, MachineIRBuilder &MIRBuilder) { |
325 | 0 | return false; |
326 | 0 | } |
327 | 1.39k | bool translateFence(const User &U, MachineIRBuilder &MIRBuilder) { |
328 | 1.39k | return false; |
329 | 1.39k | } |
330 | 0 | bool translateAtomicCmpXchg(const User &U, MachineIRBuilder &MIRBuilder) { |
331 | 0 | return false; |
332 | 0 | } |
333 | 0 | bool translateAtomicRMW(const User &U, MachineIRBuilder &MIRBuilder) { |
334 | 0 | return false; |
335 | 0 | } |
336 | 0 | bool translateAddrSpaceCast(const User &U, MachineIRBuilder &MIRBuilder) { |
337 | 0 | return false; |
338 | 0 | } |
339 | 0 | bool translateCleanupPad(const User &U, MachineIRBuilder &MIRBuilder) { |
340 | 0 | return false; |
341 | 0 | } |
342 | 0 | bool translateCatchPad(const User &U, MachineIRBuilder &MIRBuilder) { |
343 | 0 | return false; |
344 | 0 | } |
345 | 0 | bool translateUserOp1(const User &U, MachineIRBuilder &MIRBuilder) { |
346 | 0 | return false; |
347 | 0 | } |
348 | 0 | bool translateUserOp2(const User &U, MachineIRBuilder &MIRBuilder) { |
349 | 0 | return false; |
350 | 0 | } |
351 | | |
352 | | /// @} |
353 | | |
354 | | // Builder for machine instruction a la IRBuilder. |
355 | | // I.e., compared to regular MIBuilder, this one also inserts the instruction |
356 | | // in the current block, it can creates block, etc., basically a kind of |
357 | | // IRBuilder, but for Machine IR. |
358 | | MachineIRBuilder CurBuilder; |
359 | | |
360 | | // Builder set to the entry block (just after ABI lowering instructions). Used |
361 | | // as a convenient location for Constants. |
362 | | MachineIRBuilder EntryBuilder; |
363 | | |
364 | | // The MachineFunction currently being translated. |
365 | | MachineFunction *MF; |
366 | | |
367 | | /// MachineRegisterInfo used to create virtual registers. |
368 | | MachineRegisterInfo *MRI = nullptr; |
369 | | |
370 | | const DataLayout *DL; |
371 | | |
372 | | /// Current target configuration. Controls how the pass handles errors. |
373 | | const TargetPassConfig *TPC; |
374 | | |
375 | | /// Current optimization remark emitter. Used to report failures. |
376 | | std::unique_ptr<OptimizationRemarkEmitter> ORE; |
377 | | |
378 | | // * Insert all the code needed to materialize the constants |
379 | | // at the proper place. E.g., Entry block or dominator block |
380 | | // of each constant depending on how fancy we want to be. |
381 | | // * Clear the different maps. |
382 | | void finalizeFunction(); |
383 | | |
384 | | /// Get the VReg that represents \p Val. |
385 | | /// If such VReg does not exist, it is created. |
386 | | unsigned getOrCreateVReg(const Value &Val); |
387 | | |
388 | | /// Get the frame index that represents \p Val. |
389 | | /// If such VReg does not exist, it is created. |
390 | | int getOrCreateFrameIndex(const AllocaInst &AI); |
391 | | |
392 | | /// Get the alignment of the given memory operation instruction. This will |
393 | | /// either be the explicitly specified value or the ABI-required alignment for |
394 | | /// the type being accessed (according to the Module's DataLayout). |
395 | | unsigned getMemOpAlignment(const Instruction &I); |
396 | | |
397 | | /// Get the MachineBasicBlock that represents \p BB. Specifically, the block |
398 | | /// returned will be the head of the translated block (suitable for branch |
399 | | /// destinations). |
400 | | MachineBasicBlock &getMBB(const BasicBlock &BB); |
401 | | |
402 | | /// Record \p NewPred as a Machine predecessor to `Edge.second`, corresponding |
403 | | /// to `Edge.first` at the IR level. This is used when IRTranslation creates |
404 | | /// multiple MachineBasicBlocks for a given IR block and the CFG is no longer |
405 | | /// represented simply by the IR-level CFG. |
406 | | void addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred); |
407 | | |
408 | | /// Returns the Machine IR predecessors for the given IR CFG edge. Usually |
409 | | /// this is just the single MachineBasicBlock corresponding to the predecessor |
410 | | /// in the IR. More complex lowering can result in multiple MachineBasicBlocks |
411 | | /// preceding the original though (e.g. switch instructions). |
412 | 1.10M | SmallVector<MachineBasicBlock *, 1> getMachinePredBBs(CFGEdge Edge) { |
413 | 1.10M | auto RemappedEdge = MachinePreds.find(Edge); |
414 | 1.10M | if (RemappedEdge != MachinePreds.end()) |
415 | 10.7k | return RemappedEdge->second; |
416 | 1.09M | return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*Edge.first)); |
417 | 1.10M | } |
418 | | |
419 | | public: |
420 | | // Ctor, nothing fancy. |
421 | | IRTranslator(); |
422 | | |
423 | 5 | StringRef getPassName() const override { return "IRTranslator"; } |
424 | | |
425 | | void getAnalysisUsage(AnalysisUsage &AU) const override; |
426 | | |
427 | | // Algo: |
428 | | // CallLowering = MF.subtarget.getCallLowering() |
429 | | // F = MF.getParent() |
430 | | // MIRBuilder.reset(MF) |
431 | | // getMBB(F.getEntryBB()) |
432 | | // CallLowering->translateArguments(MIRBuilder, F, ValToVReg) |
433 | | // for each bb in F |
434 | | // getMBB(bb) |
435 | | // for each inst in bb |
436 | | // if (!translate(MIRBuilder, inst, ValToVReg, ConstantToSequence)) |
437 | | // report_fatal_error("Don't know how to translate input"); |
438 | | // finalize() |
439 | | bool runOnMachineFunction(MachineFunction &MF) override; |
440 | | }; |
441 | | |
442 | | } // end namespace llvm |
443 | | |
444 | | #endif // LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H |