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/CSEMIRBuilder.h"
25 #include "llvm/CodeGen/GlobalISel/Types.h"
26 #include "llvm/CodeGen/MachineFunctionPass.h"
27 #include "llvm/IR/Intrinsics.h"
28 #include "llvm/Support/Allocator.h"
29 #include <memory>
30 #include <utility>
31 
32 namespace llvm {
33 
34 class AllocaInst;
35 class BasicBlock;
36 class CallInst;
37 class CallLowering;
38 class Constant;
39 class DataLayout;
40 class Instruction;
41 class MachineBasicBlock;
42 class MachineFunction;
43 class MachineInstr;
44 class MachineRegisterInfo;
45 class OptimizationRemarkEmitter;
46 class PHINode;
47 class TargetPassConfig;
48 class User;
49 class Value;
50 
51 // Technically the pass should run on an hypothetical MachineModule,
52 // since it should translate Global into some sort of MachineGlobal.
53 // The MachineGlobal should ultimately just be a transfer of ownership of
54 // the interesting bits that are relevant to represent a global value.
55 // That being said, we could investigate what would it cost to just duplicate
56 // the information from the LLVM IR.
57 // The idea is that ultimately we would be able to free up the memory used
58 // by the LLVM IR as soon as the translation is over.
59 class IRTranslator : public MachineFunctionPass {
60 public:
61   static char ID;
62 
63 private:
64   /// Interface used to lower the everything related to calls.
65   const CallLowering *CLI;
66 
67   /// This class contains the mapping between the Values to vreg related data.
68   class ValueToVRegInfo {
69   public:
70     ValueToVRegInfo() = default;
71 
72     using VRegListT = SmallVector<unsigned, 1>;
73     using OffsetListT = SmallVector<uint64_t, 1>;
74 
75     using const_vreg_iterator =
76         DenseMap<const Value *, VRegListT *>::const_iterator;
77     using const_offset_iterator =
78         DenseMap<const Value *, OffsetListT *>::const_iterator;
79 
vregs_end()80     inline const_vreg_iterator vregs_end() const { return ValToVRegs.end(); }
81 
getVRegs(const Value & V)82     VRegListT *getVRegs(const Value &V) {
83       auto It = ValToVRegs.find(&V);
84       if (It != ValToVRegs.end())
85         return It->second;
86 
87       return insertVRegs(V);
88     }
89 
getOffsets(const Value & V)90     OffsetListT *getOffsets(const Value &V) {
91       auto It = TypeToOffsets.find(V.getType());
92       if (It != TypeToOffsets.end())
93         return It->second;
94 
95       return insertOffsets(V);
96     }
97 
findVRegs(const Value & V)98     const_vreg_iterator findVRegs(const Value &V) const {
99       return ValToVRegs.find(&V);
100     }
101 
contains(const Value & V)102     bool contains(const Value &V) const {
103       return ValToVRegs.find(&V) != ValToVRegs.end();
104     }
105 
reset()106     void reset() {
107       ValToVRegs.clear();
108       TypeToOffsets.clear();
109       VRegAlloc.DestroyAll();
110       OffsetAlloc.DestroyAll();
111     }
112 
113   private:
insertVRegs(const Value & V)114     VRegListT *insertVRegs(const Value &V) {
115       assert(ValToVRegs.find(&V) == ValToVRegs.end() && "Value already exists");
116 
117       // We placement new using our fast allocator since we never try to free
118       // the vectors until translation is finished.
119       auto *VRegList = new (VRegAlloc.Allocate()) VRegListT();
120       ValToVRegs[&V] = VRegList;
121       return VRegList;
122     }
123 
insertOffsets(const Value & V)124     OffsetListT *insertOffsets(const Value &V) {
125       assert(TypeToOffsets.find(V.getType()) == TypeToOffsets.end() &&
126              "Type already exists");
127 
128       auto *OffsetList = new (OffsetAlloc.Allocate()) OffsetListT();
129       TypeToOffsets[V.getType()] = OffsetList;
130       return OffsetList;
131     }
132     SpecificBumpPtrAllocator<VRegListT> VRegAlloc;
133     SpecificBumpPtrAllocator<OffsetListT> OffsetAlloc;
134 
135     // We store pointers to vectors here since references may be invalidated
136     // while we hold them if we stored the vectors directly.
137     DenseMap<const Value *, VRegListT*> ValToVRegs;
138     DenseMap<const Type *, OffsetListT*> TypeToOffsets;
139   };
140 
141   /// Mapping of the values of the current LLVM IR function to the related
142   /// virtual registers and offsets.
143   ValueToVRegInfo VMap;
144 
145   // N.b. it's not completely obvious that this will be sufficient for every
146   // LLVM IR construct (with "invoke" being the obvious candidate to mess up our
147   // lives.
148   DenseMap<const BasicBlock *, MachineBasicBlock *> BBToMBB;
149 
150   // One BasicBlock can be translated to multiple MachineBasicBlocks.  For such
151   // BasicBlocks translated to multiple MachineBasicBlocks, MachinePreds retains
152   // a mapping between the edges arriving at the BasicBlock to the corresponding
153   // created MachineBasicBlocks. Some BasicBlocks that get translated to a
154   // single MachineBasicBlock may also end up in this Map.
155   using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>;
156   DenseMap<CFGEdge, SmallVector<MachineBasicBlock *, 1>> MachinePreds;
157 
158   // List of stubbed PHI instructions, for values and basic blocks to be filled
159   // in once all MachineBasicBlocks have been created.
160   SmallVector<std::pair<const PHINode *, SmallVector<MachineInstr *, 1>>, 4>
161       PendingPHIs;
162 
163   /// Record of what frame index has been allocated to specified allocas for
164   /// this function.
165   DenseMap<const AllocaInst *, int> FrameIndices;
166 
167   /// \name Methods for translating form LLVM IR to MachineInstr.
168   /// \see ::translate for general information on the translate methods.
169   /// @{
170 
171   /// Translate \p Inst into its corresponding MachineInstr instruction(s).
172   /// Insert the newly translated instruction(s) right where the CurBuilder
173   /// is set.
174   ///
175   /// The general algorithm is:
176   /// 1. Look for a virtual register for each operand or
177   ///    create one.
178   /// 2 Update the VMap accordingly.
179   /// 2.alt. For constant arguments, if they are compile time constants,
180   ///   produce an immediate in the right operand and do not touch
181   ///   ValToReg. Actually we will go with a virtual register for each
182   ///   constants because it may be expensive to actually materialize the
183   ///   constant. Moreover, if the constant spans on several instructions,
184   ///   CSE may not catch them.
185   ///   => Update ValToVReg and remember that we saw a constant in Constants.
186   ///   We will materialize all the constants in finalize.
187   /// Note: we would need to do something so that we can recognize such operand
188   ///       as constants.
189   /// 3. Create the generic instruction.
190   ///
191   /// \return true if the translation succeeded.
192   bool translate(const Instruction &Inst);
193 
194   /// Materialize \p C into virtual-register \p Reg. The generic instructions
195   /// performing this materialization will be inserted into the entry block of
196   /// the function.
197   ///
198   /// \return true if the materialization succeeded.
199   bool translate(const Constant &C, unsigned Reg);
200 
201   /// Translate an LLVM bitcast into generic IR. Either a COPY or a G_BITCAST is
202   /// emitted.
203   bool translateBitCast(const User &U, MachineIRBuilder &MIRBuilder);
204 
205   /// Translate an LLVM load instruction into generic IR.
206   bool translateLoad(const User &U, MachineIRBuilder &MIRBuilder);
207 
208   /// Translate an LLVM store instruction into generic IR.
209   bool translateStore(const User &U, MachineIRBuilder &MIRBuilder);
210 
211   /// Translate an LLVM string intrinsic (memcpy, memset, ...).
212   bool translateMemfunc(const CallInst &CI, MachineIRBuilder &MIRBuilder,
213                         unsigned ID);
214 
215   void getStackGuard(unsigned DstReg, MachineIRBuilder &MIRBuilder);
216 
217   bool translateOverflowIntrinsic(const CallInst &CI, unsigned Op,
218                                   MachineIRBuilder &MIRBuilder);
219 
220   bool translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
221                                MachineIRBuilder &MIRBuilder);
222 
223   bool translateInlineAsm(const CallInst &CI, MachineIRBuilder &MIRBuilder);
224 
225   // FIXME: temporary function to expose previous interface to call lowering
226   // until it is refactored.
227   /// Combines all component registers of \p V into a single scalar with size
228   /// "max(Offsets) + last size".
229   unsigned packRegs(const Value &V, MachineIRBuilder &MIRBuilder);
230 
231   void unpackRegs(const Value &V, unsigned Src, MachineIRBuilder &MIRBuilder);
232 
233   /// Returns true if the value should be split into multiple LLTs.
234   /// If \p Offsets is given then the split type's offsets will be stored in it.
235   /// If \p Offsets is not empty it will be cleared first.
236   bool valueIsSplit(const Value &V,
237                     SmallVectorImpl<uint64_t> *Offsets = nullptr);
238 
239   /// Translate call instruction.
240   /// \pre \p U is a call instruction.
241   bool translateCall(const User &U, MachineIRBuilder &MIRBuilder);
242 
243   bool translateInvoke(const User &U, MachineIRBuilder &MIRBuilder);
244 
245   bool translateLandingPad(const User &U, MachineIRBuilder &MIRBuilder);
246 
247   /// Translate one of LLVM's cast instructions into MachineInstrs, with the
248   /// given generic Opcode.
249   bool translateCast(unsigned Opcode, const User &U,
250                      MachineIRBuilder &MIRBuilder);
251 
252   /// Translate a phi instruction.
253   bool translatePHI(const User &U, MachineIRBuilder &MIRBuilder);
254 
255   /// Translate a comparison (icmp or fcmp) instruction or constant.
256   bool translateCompare(const User &U, MachineIRBuilder &MIRBuilder);
257 
258   /// Translate an integer compare instruction (or constant).
translateICmp(const User & U,MachineIRBuilder & MIRBuilder)259   bool translateICmp(const User &U, MachineIRBuilder &MIRBuilder) {
260     return translateCompare(U, MIRBuilder);
261   }
262 
263   /// Translate a floating-point compare instruction (or constant).
translateFCmp(const User & U,MachineIRBuilder & MIRBuilder)264   bool translateFCmp(const User &U, MachineIRBuilder &MIRBuilder) {
265     return translateCompare(U, MIRBuilder);
266   }
267 
268   /// Add remaining operands onto phis we've translated. Executed after all
269   /// MachineBasicBlocks for the function have been created.
270   void finishPendingPhis();
271 
272   /// Translate \p Inst into a binary operation \p Opcode.
273   /// \pre \p U is a binary operation.
274   bool translateBinaryOp(unsigned Opcode, const User &U,
275                          MachineIRBuilder &MIRBuilder);
276 
277   /// Translate branch (br) instruction.
278   /// \pre \p U is a branch instruction.
279   bool translateBr(const User &U, MachineIRBuilder &MIRBuilder);
280 
281   bool translateSwitch(const User &U, MachineIRBuilder &MIRBuilder);
282 
283   bool translateIndirectBr(const User &U, MachineIRBuilder &MIRBuilder);
284 
285   bool translateExtractValue(const User &U, MachineIRBuilder &MIRBuilder);
286 
287   bool translateInsertValue(const User &U, MachineIRBuilder &MIRBuilder);
288 
289   bool translateSelect(const User &U, MachineIRBuilder &MIRBuilder);
290 
291   bool translateGetElementPtr(const User &U, MachineIRBuilder &MIRBuilder);
292 
293   bool translateAlloca(const User &U, MachineIRBuilder &MIRBuilder);
294 
295   /// Translate return (ret) instruction.
296   /// The target needs to implement CallLowering::lowerReturn for
297   /// this to succeed.
298   /// \pre \p U is a return instruction.
299   bool translateRet(const User &U, MachineIRBuilder &MIRBuilder);
300 
301   bool translateFSub(const User &U, MachineIRBuilder &MIRBuilder);
302 
303   bool translateFNeg(const User &U, MachineIRBuilder &MIRBuilder);
304 
translateAdd(const User & U,MachineIRBuilder & MIRBuilder)305   bool translateAdd(const User &U, MachineIRBuilder &MIRBuilder) {
306     return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
307   }
translateSub(const User & U,MachineIRBuilder & MIRBuilder)308   bool translateSub(const User &U, MachineIRBuilder &MIRBuilder) {
309     return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
310   }
translateAnd(const User & U,MachineIRBuilder & MIRBuilder)311   bool translateAnd(const User &U, MachineIRBuilder &MIRBuilder) {
312     return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
313   }
translateMul(const User & U,MachineIRBuilder & MIRBuilder)314   bool translateMul(const User &U, MachineIRBuilder &MIRBuilder) {
315     return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
316   }
translateOr(const User & U,MachineIRBuilder & MIRBuilder)317   bool translateOr(const User &U, MachineIRBuilder &MIRBuilder) {
318     return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
319   }
translateXor(const User & U,MachineIRBuilder & MIRBuilder)320   bool translateXor(const User &U, MachineIRBuilder &MIRBuilder) {
321     return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
322   }
323 
translateUDiv(const User & U,MachineIRBuilder & MIRBuilder)324   bool translateUDiv(const User &U, MachineIRBuilder &MIRBuilder) {
325     return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
326   }
translateSDiv(const User & U,MachineIRBuilder & MIRBuilder)327   bool translateSDiv(const User &U, MachineIRBuilder &MIRBuilder) {
328     return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
329   }
translateURem(const User & U,MachineIRBuilder & MIRBuilder)330   bool translateURem(const User &U, MachineIRBuilder &MIRBuilder) {
331     return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
332   }
translateSRem(const User & U,MachineIRBuilder & MIRBuilder)333   bool translateSRem(const User &U, MachineIRBuilder &MIRBuilder) {
334     return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
335   }
translateIntToPtr(const User & U,MachineIRBuilder & MIRBuilder)336   bool translateIntToPtr(const User &U, MachineIRBuilder &MIRBuilder) {
337     return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
338   }
translatePtrToInt(const User & U,MachineIRBuilder & MIRBuilder)339   bool translatePtrToInt(const User &U, MachineIRBuilder &MIRBuilder) {
340     return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
341   }
translateTrunc(const User & U,MachineIRBuilder & MIRBuilder)342   bool translateTrunc(const User &U, MachineIRBuilder &MIRBuilder) {
343     return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
344   }
translateFPTrunc(const User & U,MachineIRBuilder & MIRBuilder)345   bool translateFPTrunc(const User &U, MachineIRBuilder &MIRBuilder) {
346     return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
347   }
translateFPExt(const User & U,MachineIRBuilder & MIRBuilder)348   bool translateFPExt(const User &U, MachineIRBuilder &MIRBuilder) {
349     return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
350   }
translateFPToUI(const User & U,MachineIRBuilder & MIRBuilder)351   bool translateFPToUI(const User &U, MachineIRBuilder &MIRBuilder) {
352     return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
353   }
translateFPToSI(const User & U,MachineIRBuilder & MIRBuilder)354   bool translateFPToSI(const User &U, MachineIRBuilder &MIRBuilder) {
355     return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
356   }
translateUIToFP(const User & U,MachineIRBuilder & MIRBuilder)357   bool translateUIToFP(const User &U, MachineIRBuilder &MIRBuilder) {
358     return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
359   }
translateSIToFP(const User & U,MachineIRBuilder & MIRBuilder)360   bool translateSIToFP(const User &U, MachineIRBuilder &MIRBuilder) {
361     return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
362   }
translateUnreachable(const User & U,MachineIRBuilder & MIRBuilder)363   bool translateUnreachable(const User &U, MachineIRBuilder &MIRBuilder) {
364     return true;
365   }
translateSExt(const User & U,MachineIRBuilder & MIRBuilder)366   bool translateSExt(const User &U, MachineIRBuilder &MIRBuilder) {
367     return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
368   }
369 
translateZExt(const User & U,MachineIRBuilder & MIRBuilder)370   bool translateZExt(const User &U, MachineIRBuilder &MIRBuilder) {
371     return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
372   }
373 
translateShl(const User & U,MachineIRBuilder & MIRBuilder)374   bool translateShl(const User &U, MachineIRBuilder &MIRBuilder) {
375     return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
376   }
translateLShr(const User & U,MachineIRBuilder & MIRBuilder)377   bool translateLShr(const User &U, MachineIRBuilder &MIRBuilder) {
378     return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
379   }
translateAShr(const User & U,MachineIRBuilder & MIRBuilder)380   bool translateAShr(const User &U, MachineIRBuilder &MIRBuilder) {
381     return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
382   }
383 
translateFAdd(const User & U,MachineIRBuilder & MIRBuilder)384   bool translateFAdd(const User &U, MachineIRBuilder &MIRBuilder) {
385     return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
386   }
translateFMul(const User & U,MachineIRBuilder & MIRBuilder)387   bool translateFMul(const User &U, MachineIRBuilder &MIRBuilder) {
388     return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
389   }
translateFDiv(const User & U,MachineIRBuilder & MIRBuilder)390   bool translateFDiv(const User &U, MachineIRBuilder &MIRBuilder) {
391     return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
392   }
translateFRem(const User & U,MachineIRBuilder & MIRBuilder)393   bool translateFRem(const User &U, MachineIRBuilder &MIRBuilder) {
394     return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
395   }
396 
397   bool translateVAArg(const User &U, MachineIRBuilder &MIRBuilder);
398 
399   bool translateInsertElement(const User &U, MachineIRBuilder &MIRBuilder);
400 
401   bool translateExtractElement(const User &U, MachineIRBuilder &MIRBuilder);
402 
403   bool translateShuffleVector(const User &U, MachineIRBuilder &MIRBuilder);
404 
405   bool translateAtomicCmpXchg(const User &U, MachineIRBuilder &MIRBuilder);
406   bool translateAtomicRMW(const User &U, MachineIRBuilder &MIRBuilder);
407 
408   // Stubs to keep the compiler happy while we implement the rest of the
409   // translation.
translateResume(const User & U,MachineIRBuilder & MIRBuilder)410   bool translateResume(const User &U, MachineIRBuilder &MIRBuilder) {
411     return false;
412   }
translateCleanupRet(const User & U,MachineIRBuilder & MIRBuilder)413   bool translateCleanupRet(const User &U, MachineIRBuilder &MIRBuilder) {
414     return false;
415   }
translateCatchRet(const User & U,MachineIRBuilder & MIRBuilder)416   bool translateCatchRet(const User &U, MachineIRBuilder &MIRBuilder) {
417     return false;
418   }
translateCatchSwitch(const User & U,MachineIRBuilder & MIRBuilder)419   bool translateCatchSwitch(const User &U, MachineIRBuilder &MIRBuilder) {
420     return false;
421   }
translateFence(const User & U,MachineIRBuilder & MIRBuilder)422   bool translateFence(const User &U, MachineIRBuilder &MIRBuilder) {
423     return false;
424   }
translateAddrSpaceCast(const User & U,MachineIRBuilder & MIRBuilder)425   bool translateAddrSpaceCast(const User &U, MachineIRBuilder &MIRBuilder) {
426     return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
427   }
translateCleanupPad(const User & U,MachineIRBuilder & MIRBuilder)428   bool translateCleanupPad(const User &U, MachineIRBuilder &MIRBuilder) {
429     return false;
430   }
translateCatchPad(const User & U,MachineIRBuilder & MIRBuilder)431   bool translateCatchPad(const User &U, MachineIRBuilder &MIRBuilder) {
432     return false;
433   }
translateUserOp1(const User & U,MachineIRBuilder & MIRBuilder)434   bool translateUserOp1(const User &U, MachineIRBuilder &MIRBuilder) {
435     return false;
436   }
translateUserOp2(const User & U,MachineIRBuilder & MIRBuilder)437   bool translateUserOp2(const User &U, MachineIRBuilder &MIRBuilder) {
438     return false;
439   }
440 
441   /// @}
442 
443   // Builder for machine instruction a la IRBuilder.
444   // I.e., compared to regular MIBuilder, this one also inserts the instruction
445   // in the current block, it can creates block, etc., basically a kind of
446   // IRBuilder, but for Machine IR.
447   // CSEMIRBuilder CurBuilder;
448   std::unique_ptr<MachineIRBuilder> CurBuilder;
449 
450   // Builder set to the entry block (just after ABI lowering instructions). Used
451   // as a convenient location for Constants.
452   // CSEMIRBuilder EntryBuilder;
453   std::unique_ptr<MachineIRBuilder> EntryBuilder;
454 
455   // The MachineFunction currently being translated.
456   MachineFunction *MF;
457 
458   /// MachineRegisterInfo used to create virtual registers.
459   MachineRegisterInfo *MRI = nullptr;
460 
461   const DataLayout *DL;
462 
463   /// Current target configuration. Controls how the pass handles errors.
464   const TargetPassConfig *TPC;
465 
466   /// Current optimization remark emitter. Used to report failures.
467   std::unique_ptr<OptimizationRemarkEmitter> ORE;
468 
469   // * Insert all the code needed to materialize the constants
470   // at the proper place. E.g., Entry block or dominator block
471   // of each constant depending on how fancy we want to be.
472   // * Clear the different maps.
473   void finalizeFunction();
474 
475   /// Get the VRegs that represent \p Val.
476   /// Non-aggregate types have just one corresponding VReg and the list can be
477   /// used as a single "unsigned". Aggregates get flattened. If such VRegs do
478   /// not exist, they are created.
479   ArrayRef<unsigned> getOrCreateVRegs(const Value &Val);
480 
getOrCreateVReg(const Value & Val)481   unsigned getOrCreateVReg(const Value &Val) {
482     auto Regs = getOrCreateVRegs(Val);
483     if (Regs.empty())
484       return 0;
485     assert(Regs.size() == 1 &&
486            "attempt to get single VReg for aggregate or void");
487     return Regs[0];
488   }
489 
490   /// Allocate some vregs and offsets in the VMap. Then populate just the
491   /// offsets while leaving the vregs empty.
492   ValueToVRegInfo::VRegListT &allocateVRegs(const Value &Val);
493 
494   /// Get the frame index that represents \p Val.
495   /// If such VReg does not exist, it is created.
496   int getOrCreateFrameIndex(const AllocaInst &AI);
497 
498   /// Get the alignment of the given memory operation instruction. This will
499   /// either be the explicitly specified value or the ABI-required alignment for
500   /// the type being accessed (according to the Module's DataLayout).
501   unsigned getMemOpAlignment(const Instruction &I);
502 
503   /// Get the MachineBasicBlock that represents \p BB. Specifically, the block
504   /// returned will be the head of the translated block (suitable for branch
505   /// destinations).
506   MachineBasicBlock &getMBB(const BasicBlock &BB);
507 
508   /// Record \p NewPred as a Machine predecessor to `Edge.second`, corresponding
509   /// to `Edge.first` at the IR level. This is used when IRTranslation creates
510   /// multiple MachineBasicBlocks for a given IR block and the CFG is no longer
511   /// represented simply by the IR-level CFG.
512   void addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred);
513 
514   /// Returns the Machine IR predecessors for the given IR CFG edge. Usually
515   /// this is just the single MachineBasicBlock corresponding to the predecessor
516   /// in the IR. More complex lowering can result in multiple MachineBasicBlocks
517   /// preceding the original though (e.g. switch instructions).
getMachinePredBBs(CFGEdge Edge)518   SmallVector<MachineBasicBlock *, 1> getMachinePredBBs(CFGEdge Edge) {
519     auto RemappedEdge = MachinePreds.find(Edge);
520     if (RemappedEdge != MachinePreds.end())
521       return RemappedEdge->second;
522     return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*Edge.first));
523   }
524 
525 public:
526   // Ctor, nothing fancy.
527   IRTranslator();
528 
getPassName()529   StringRef getPassName() const override { return "IRTranslator"; }
530 
531   void getAnalysisUsage(AnalysisUsage &AU) const override;
532 
533   // Algo:
534   //   CallLowering = MF.subtarget.getCallLowering()
535   //   F = MF.getParent()
536   //   MIRBuilder.reset(MF)
537   //   getMBB(F.getEntryBB())
538   //   CallLowering->translateArguments(MIRBuilder, F, ValToVReg)
539   //   for each bb in F
540   //     getMBB(bb)
541   //     for each inst in bb
542   //       if (!translate(MIRBuilder, inst, ValToVReg, ConstantToSequence))
543   //         report_fatal_error("Don't know how to translate input");
544   //   finalize()
545   bool runOnMachineFunction(MachineFunction &MF) override;
546 };
547 
548 } // end namespace llvm
549 
550 #endif // LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H
551