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