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