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