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