Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:24

0001 //===- llvm/CodeGen/GlobalISel/IRTranslator.h - IRTranslator ----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 /// \file
0009 /// This file declares the IRTranslator pass.
0010 /// This pass is responsible for translating LLVM IR into MachineInstr.
0011 /// It uses target hooks to lower the ABI but aside from that, the pass
0012 /// generated code is generic. This is the default translator used for
0013 /// GlobalISel.
0014 ///
0015 /// \todo Replace the comments with actual doxygen comments.
0016 //===----------------------------------------------------------------------===//
0017 
0018 #ifndef LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H
0019 #define LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H
0020 
0021 #include "llvm/ADT/DenseMap.h"
0022 #include "llvm/ADT/SmallVector.h"
0023 #include "llvm/CodeGen/CodeGenCommonISel.h"
0024 #include "llvm/CodeGen/FunctionLoweringInfo.h"
0025 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
0026 #include "llvm/CodeGen/MachineFunctionPass.h"
0027 #include "llvm/CodeGen/SwiftErrorValueTracking.h"
0028 #include "llvm/CodeGen/SwitchLoweringUtils.h"
0029 #include "llvm/Support/Allocator.h"
0030 #include "llvm/Support/CodeGen.h"
0031 #include <memory>
0032 #include <utility>
0033 
0034 namespace llvm {
0035 
0036 class AllocaInst;
0037 class AssumptionCache;
0038 class BasicBlock;
0039 class CallInst;
0040 class CallLowering;
0041 class Constant;
0042 class ConstrainedFPIntrinsic;
0043 class DataLayout;
0044 class DbgDeclareInst;
0045 class DbgValueInst;
0046 class Instruction;
0047 class MachineBasicBlock;
0048 class MachineFunction;
0049 class MachineInstr;
0050 class MachineRegisterInfo;
0051 class OptimizationRemarkEmitter;
0052 class PHINode;
0053 class TargetLibraryInfo;
0054 class TargetPassConfig;
0055 class User;
0056 class Value;
0057 
0058 // Technically the pass should run on an hypothetical MachineModule,
0059 // since it should translate Global into some sort of MachineGlobal.
0060 // The MachineGlobal should ultimately just be a transfer of ownership of
0061 // the interesting bits that are relevant to represent a global value.
0062 // That being said, we could investigate what would it cost to just duplicate
0063 // the information from the LLVM IR.
0064 // The idea is that ultimately we would be able to free up the memory used
0065 // by the LLVM IR as soon as the translation is over.
0066 class IRTranslator : public MachineFunctionPass {
0067 public:
0068   static char ID;
0069 
0070 private:
0071   /// Interface used to lower the everything related to calls.
0072   const CallLowering *CLI = nullptr;
0073 
0074   /// This class contains the mapping between the Values to vreg related data.
0075   class ValueToVRegInfo {
0076   public:
0077     ValueToVRegInfo() = default;
0078 
0079     using VRegListT = SmallVector<Register, 1>;
0080     using OffsetListT = SmallVector<uint64_t, 1>;
0081 
0082     using const_vreg_iterator =
0083         DenseMap<const Value *, VRegListT *>::const_iterator;
0084     using const_offset_iterator =
0085         DenseMap<const Value *, OffsetListT *>::const_iterator;
0086 
0087     inline const_vreg_iterator vregs_end() const { return ValToVRegs.end(); }
0088 
0089     VRegListT *getVRegs(const Value &V) {
0090       auto It = ValToVRegs.find(&V);
0091       if (It != ValToVRegs.end())
0092         return It->second;
0093 
0094       return insertVRegs(V);
0095     }
0096 
0097     OffsetListT *getOffsets(const Value &V) {
0098       auto It = TypeToOffsets.find(V.getType());
0099       if (It != TypeToOffsets.end())
0100         return It->second;
0101 
0102       return insertOffsets(V);
0103     }
0104 
0105     const_vreg_iterator findVRegs(const Value &V) const {
0106       return ValToVRegs.find(&V);
0107     }
0108 
0109     bool contains(const Value &V) const { return ValToVRegs.contains(&V); }
0110 
0111     void reset() {
0112       ValToVRegs.clear();
0113       TypeToOffsets.clear();
0114       VRegAlloc.DestroyAll();
0115       OffsetAlloc.DestroyAll();
0116     }
0117 
0118   private:
0119     VRegListT *insertVRegs(const Value &V) {
0120       assert(!ValToVRegs.contains(&V) && "Value already exists");
0121 
0122       // We placement new using our fast allocator since we never try to free
0123       // the vectors until translation is finished.
0124       auto *VRegList = new (VRegAlloc.Allocate()) VRegListT();
0125       ValToVRegs[&V] = VRegList;
0126       return VRegList;
0127     }
0128 
0129     OffsetListT *insertOffsets(const Value &V) {
0130       assert(!TypeToOffsets.contains(V.getType()) && "Type already exists");
0131 
0132       auto *OffsetList = new (OffsetAlloc.Allocate()) OffsetListT();
0133       TypeToOffsets[V.getType()] = OffsetList;
0134       return OffsetList;
0135     }
0136     SpecificBumpPtrAllocator<VRegListT> VRegAlloc;
0137     SpecificBumpPtrAllocator<OffsetListT> OffsetAlloc;
0138 
0139     // We store pointers to vectors here since references may be invalidated
0140     // while we hold them if we stored the vectors directly.
0141     DenseMap<const Value *, VRegListT*> ValToVRegs;
0142     DenseMap<const Type *, OffsetListT*> TypeToOffsets;
0143   };
0144 
0145   /// Mapping of the values of the current LLVM IR function to the related
0146   /// virtual registers and offsets.
0147   ValueToVRegInfo VMap;
0148 
0149   // One BasicBlock can be translated to multiple MachineBasicBlocks.  For such
0150   // BasicBlocks translated to multiple MachineBasicBlocks, MachinePreds retains
0151   // a mapping between the edges arriving at the BasicBlock to the corresponding
0152   // created MachineBasicBlocks. Some BasicBlocks that get translated to a
0153   // single MachineBasicBlock may also end up in this Map.
0154   using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>;
0155   DenseMap<CFGEdge, SmallVector<MachineBasicBlock *, 1>> MachinePreds;
0156 
0157   // List of stubbed PHI instructions, for values and basic blocks to be filled
0158   // in once all MachineBasicBlocks have been created.
0159   SmallVector<std::pair<const PHINode *, SmallVector<MachineInstr *, 1>>, 4>
0160       PendingPHIs;
0161 
0162   /// Record of what frame index has been allocated to specified allocas for
0163   /// this function.
0164   DenseMap<const AllocaInst *, int> FrameIndices;
0165 
0166   SwiftErrorValueTracking SwiftError;
0167 
0168   /// \name Methods for translating form LLVM IR to MachineInstr.
0169   /// \see ::translate for general information on the translate methods.
0170   /// @{
0171 
0172   /// Translate \p Inst into its corresponding MachineInstr instruction(s).
0173   /// Insert the newly translated instruction(s) right where the CurBuilder
0174   /// is set.
0175   ///
0176   /// The general algorithm is:
0177   /// 1. Look for a virtual register for each operand or
0178   ///    create one.
0179   /// 2 Update the VMap accordingly.
0180   /// 2.alt. For constant arguments, if they are compile time constants,
0181   ///   produce an immediate in the right operand and do not touch
0182   ///   ValToReg. Actually we will go with a virtual register for each
0183   ///   constants because it may be expensive to actually materialize the
0184   ///   constant. Moreover, if the constant spans on several instructions,
0185   ///   CSE may not catch them.
0186   ///   => Update ValToVReg and remember that we saw a constant in Constants.
0187   ///   We will materialize all the constants in finalize.
0188   /// Note: we would need to do something so that we can recognize such operand
0189   ///       as constants.
0190   /// 3. Create the generic instruction.
0191   ///
0192   /// \return true if the translation succeeded.
0193   bool translate(const Instruction &Inst);
0194 
0195   /// Materialize \p C into virtual-register \p Reg. The generic instructions
0196   /// performing this materialization will be inserted into the entry block of
0197   /// the function.
0198   ///
0199   /// \return true if the materialization succeeded.
0200   bool translate(const Constant &C, Register Reg);
0201 
0202   /// Examine any debug-info attached to the instruction (in the form of
0203   /// DbgRecords) and translate it.
0204   void translateDbgInfo(const Instruction &Inst,
0205                           MachineIRBuilder &MIRBuilder);
0206 
0207   /// Translate a debug-info record of a dbg.value into a DBG_* instruction.
0208   /// Pass in all the contents of the record, rather than relying on how it's
0209   /// stored.
0210   void translateDbgValueRecord(Value *V, bool HasArgList,
0211                          const DILocalVariable *Variable,
0212                          const DIExpression *Expression, const DebugLoc &DL,
0213                          MachineIRBuilder &MIRBuilder);
0214 
0215   /// Translate a debug-info record of a dbg.declare into an indirect DBG_*
0216   /// instruction. Pass in all the contents of the record, rather than relying
0217   /// on how it's stored.
0218   void translateDbgDeclareRecord(Value *Address, bool HasArgList,
0219                          const DILocalVariable *Variable,
0220                          const DIExpression *Expression, const DebugLoc &DL,
0221                          MachineIRBuilder &MIRBuilder);
0222 
0223   // Translate U as a copy of V.
0224   bool translateCopy(const User &U, const Value &V,
0225                      MachineIRBuilder &MIRBuilder);
0226 
0227   /// Translate an LLVM bitcast into generic IR. Either a COPY or a G_BITCAST is
0228   /// emitted.
0229   bool translateBitCast(const User &U, MachineIRBuilder &MIRBuilder);
0230 
0231   /// Translate an LLVM load instruction into generic IR.
0232   bool translateLoad(const User &U, MachineIRBuilder &MIRBuilder);
0233 
0234   /// Translate an LLVM store instruction into generic IR.
0235   bool translateStore(const User &U, MachineIRBuilder &MIRBuilder);
0236 
0237   /// Translate an LLVM string intrinsic (memcpy, memset, ...).
0238   bool translateMemFunc(const CallInst &CI, MachineIRBuilder &MIRBuilder,
0239                         unsigned Opcode);
0240 
0241   /// Translate an LLVM trap intrinsic (trap, debugtrap, ubsantrap).
0242   bool translateTrap(const CallInst &U, MachineIRBuilder &MIRBuilder,
0243                      unsigned Opcode);
0244 
0245   // Translate @llvm.vector.interleave2 and
0246   // @llvm.vector.deinterleave2 intrinsics for fixed-width vector
0247   // types into vector shuffles.
0248   bool translateVectorInterleave2Intrinsic(const CallInst &CI,
0249                                            MachineIRBuilder &MIRBuilder);
0250   bool translateVectorDeinterleave2Intrinsic(const CallInst &CI,
0251                                              MachineIRBuilder &MIRBuilder);
0252 
0253   void getStackGuard(Register DstReg, MachineIRBuilder &MIRBuilder);
0254 
0255   bool translateOverflowIntrinsic(const CallInst &CI, unsigned Op,
0256                                   MachineIRBuilder &MIRBuilder);
0257   bool translateFixedPointIntrinsic(unsigned Op, const CallInst &CI,
0258                                     MachineIRBuilder &MIRBuilder);
0259 
0260   /// Helper function for translateSimpleIntrinsic.
0261   /// \return The generic opcode for \p IntrinsicID if \p IntrinsicID is a
0262   /// simple intrinsic (ceil, fabs, etc.). Otherwise, returns
0263   /// Intrinsic::not_intrinsic.
0264   unsigned getSimpleIntrinsicOpcode(Intrinsic::ID ID);
0265 
0266   /// Translates the intrinsics defined in getSimpleIntrinsicOpcode.
0267   /// \return true if the translation succeeded.
0268   bool translateSimpleIntrinsic(const CallInst &CI, Intrinsic::ID ID,
0269                                 MachineIRBuilder &MIRBuilder);
0270 
0271   bool translateConstrainedFPIntrinsic(const ConstrainedFPIntrinsic &FPI,
0272                                        MachineIRBuilder &MIRBuilder);
0273 
0274   bool translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
0275                                MachineIRBuilder &MIRBuilder);
0276 
0277   /// Returns the single livein physical register Arg was lowered to, if
0278   /// possible.
0279   std::optional<MCRegister> getArgPhysReg(Argument &Arg);
0280 
0281   /// If debug-info targets an Argument and its expression is an EntryValue,
0282   /// lower it as either an entry in the MF debug table (dbg.declare), or a
0283   /// DBG_VALUE targeting the corresponding livein register for that Argument
0284   /// (dbg.value).
0285   bool translateIfEntryValueArgument(bool isDeclare, Value *Arg,
0286                                      const DILocalVariable *Var,
0287                                      const DIExpression *Expr,
0288                                      const DebugLoc &DL,
0289                                      MachineIRBuilder &MIRBuilder);
0290 
0291   bool translateInlineAsm(const CallBase &CB, MachineIRBuilder &MIRBuilder);
0292 
0293   /// Common code for translating normal calls or invokes.
0294   bool translateCallBase(const CallBase &CB, MachineIRBuilder &MIRBuilder);
0295 
0296   /// Translate call instruction.
0297   /// \pre \p U is a call instruction.
0298   bool translateCall(const User &U, MachineIRBuilder &MIRBuilder);
0299 
0300   /// When an invoke or a cleanupret unwinds to the next EH pad, there are
0301   /// many places it could ultimately go. In the IR, we have a single unwind
0302   /// destination, but in the machine CFG, we enumerate all the possible blocks.
0303   /// This function skips over imaginary basic blocks that hold catchswitch
0304   /// instructions, and finds all the "real" machine
0305   /// basic block destinations. As those destinations may not be successors of
0306   /// EHPadBB, here we also calculate the edge probability to those
0307   /// destinations. The passed-in Prob is the edge probability to EHPadBB.
0308   bool findUnwindDestinations(
0309       const BasicBlock *EHPadBB, BranchProbability Prob,
0310       SmallVectorImpl<std::pair<MachineBasicBlock *, BranchProbability>>
0311           &UnwindDests);
0312 
0313   bool translateInvoke(const User &U, MachineIRBuilder &MIRBuilder);
0314 
0315   bool translateCallBr(const User &U, MachineIRBuilder &MIRBuilder);
0316 
0317   bool translateLandingPad(const User &U, MachineIRBuilder &MIRBuilder);
0318 
0319   /// Translate one of LLVM's cast instructions into MachineInstrs, with the
0320   /// given generic Opcode.
0321   bool translateCast(unsigned Opcode, const User &U,
0322                      MachineIRBuilder &MIRBuilder);
0323 
0324   /// Translate a phi instruction.
0325   bool translatePHI(const User &U, MachineIRBuilder &MIRBuilder);
0326 
0327   /// Translate a comparison (icmp or fcmp) instruction or constant.
0328   bool translateCompare(const User &U, MachineIRBuilder &MIRBuilder);
0329 
0330   /// Translate an integer compare instruction (or constant).
0331   bool translateICmp(const User &U, MachineIRBuilder &MIRBuilder) {
0332     return translateCompare(U, MIRBuilder);
0333   }
0334 
0335   /// Translate a floating-point compare instruction (or constant).
0336   bool translateFCmp(const User &U, MachineIRBuilder &MIRBuilder) {
0337     return translateCompare(U, MIRBuilder);
0338   }
0339 
0340   /// Add remaining operands onto phis we've translated. Executed after all
0341   /// MachineBasicBlocks for the function have been created.
0342   void finishPendingPhis();
0343 
0344   /// Translate \p Inst into a unary operation \p Opcode.
0345   /// \pre \p U is a unary operation.
0346   bool translateUnaryOp(unsigned Opcode, const User &U,
0347                         MachineIRBuilder &MIRBuilder);
0348 
0349   /// Translate \p Inst into a binary operation \p Opcode.
0350   /// \pre \p U is a binary operation.
0351   bool translateBinaryOp(unsigned Opcode, const User &U,
0352                          MachineIRBuilder &MIRBuilder);
0353 
0354   /// If the set of cases should be emitted as a series of branches, return
0355   /// true. If we should emit this as a bunch of and/or'd together conditions,
0356   /// return false.
0357   bool shouldEmitAsBranches(const std::vector<SwitchCG::CaseBlock> &Cases);
0358   /// Helper method for findMergedConditions.
0359   /// This function emits a branch and is used at the leaves of an OR or an
0360   /// AND operator tree.
0361   void emitBranchForMergedCondition(const Value *Cond, MachineBasicBlock *TBB,
0362                                     MachineBasicBlock *FBB,
0363                                     MachineBasicBlock *CurBB,
0364                                     MachineBasicBlock *SwitchBB,
0365                                     BranchProbability TProb,
0366                                     BranchProbability FProb, bool InvertCond);
0367   /// Used during condbr translation to find trees of conditions that can be
0368   /// optimized.
0369   void findMergedConditions(const Value *Cond, MachineBasicBlock *TBB,
0370                             MachineBasicBlock *FBB, MachineBasicBlock *CurBB,
0371                             MachineBasicBlock *SwitchBB,
0372                             Instruction::BinaryOps Opc, BranchProbability TProb,
0373                             BranchProbability FProb, bool InvertCond);
0374 
0375   /// Translate branch (br) instruction.
0376   /// \pre \p U is a branch instruction.
0377   bool translateBr(const User &U, MachineIRBuilder &MIRBuilder);
0378 
0379   // Begin switch lowering functions.
0380   bool emitJumpTableHeader(SwitchCG::JumpTable &JT,
0381                            SwitchCG::JumpTableHeader &JTH,
0382                            MachineBasicBlock *HeaderBB);
0383   void emitJumpTable(SwitchCG::JumpTable &JT, MachineBasicBlock *MBB);
0384 
0385   void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB,
0386                       MachineIRBuilder &MIB);
0387 
0388   /// Generate for the BitTest header block, which precedes each sequence of
0389   /// BitTestCases.
0390   void emitBitTestHeader(SwitchCG::BitTestBlock &BTB,
0391                          MachineBasicBlock *SwitchMBB);
0392   /// Generate code to produces one "bit test" for a given BitTestCase \p B.
0393   void emitBitTestCase(SwitchCG::BitTestBlock &BB, MachineBasicBlock *NextMBB,
0394                        BranchProbability BranchProbToNext, Register Reg,
0395                        SwitchCG::BitTestCase &B, MachineBasicBlock *SwitchBB);
0396 
0397   void splitWorkItem(SwitchCG::SwitchWorkList &WorkList,
0398                      const SwitchCG::SwitchWorkListItem &W, Value *Cond,
0399                      MachineBasicBlock *SwitchMBB, MachineIRBuilder &MIB);
0400 
0401   bool lowerJumpTableWorkItem(
0402       SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
0403       MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
0404       MachineIRBuilder &MIB, MachineFunction::iterator BBI,
0405       BranchProbability UnhandledProbs, SwitchCG::CaseClusterIt I,
0406       MachineBasicBlock *Fallthrough, bool FallthroughUnreachable);
0407 
0408   bool lowerSwitchRangeWorkItem(SwitchCG::CaseClusterIt I, Value *Cond,
0409                                 MachineBasicBlock *Fallthrough,
0410                                 bool FallthroughUnreachable,
0411                                 BranchProbability UnhandledProbs,
0412                                 MachineBasicBlock *CurMBB,
0413                                 MachineIRBuilder &MIB,
0414                                 MachineBasicBlock *SwitchMBB);
0415 
0416   bool lowerBitTestWorkItem(
0417       SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
0418       MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
0419       MachineIRBuilder &MIB, MachineFunction::iterator BBI,
0420       BranchProbability DefaultProb, BranchProbability UnhandledProbs,
0421       SwitchCG::CaseClusterIt I, MachineBasicBlock *Fallthrough,
0422       bool FallthroughUnreachable);
0423 
0424   bool lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W, Value *Cond,
0425                            MachineBasicBlock *SwitchMBB,
0426                            MachineBasicBlock *DefaultMBB,
0427                            MachineIRBuilder &MIB);
0428 
0429   bool translateSwitch(const User &U, MachineIRBuilder &MIRBuilder);
0430   // End switch lowering section.
0431 
0432   bool translateIndirectBr(const User &U, MachineIRBuilder &MIRBuilder);
0433 
0434   bool translateExtractValue(const User &U, MachineIRBuilder &MIRBuilder);
0435 
0436   bool translateInsertValue(const User &U, MachineIRBuilder &MIRBuilder);
0437 
0438   bool translateSelect(const User &U, MachineIRBuilder &MIRBuilder);
0439 
0440   bool translateGetElementPtr(const User &U, MachineIRBuilder &MIRBuilder);
0441 
0442   bool translateAlloca(const User &U, MachineIRBuilder &MIRBuilder);
0443 
0444   /// Translate return (ret) instruction.
0445   /// The target needs to implement CallLowering::lowerReturn for
0446   /// this to succeed.
0447   /// \pre \p U is a return instruction.
0448   bool translateRet(const User &U, MachineIRBuilder &MIRBuilder);
0449 
0450   bool translateFNeg(const User &U, MachineIRBuilder &MIRBuilder);
0451 
0452   bool translateAdd(const User &U, MachineIRBuilder &MIRBuilder) {
0453     return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
0454   }
0455   bool translateSub(const User &U, MachineIRBuilder &MIRBuilder) {
0456     return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
0457   }
0458   bool translateAnd(const User &U, MachineIRBuilder &MIRBuilder) {
0459     return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
0460   }
0461   bool translateMul(const User &U, MachineIRBuilder &MIRBuilder) {
0462     return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
0463   }
0464   bool translateOr(const User &U, MachineIRBuilder &MIRBuilder) {
0465     return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
0466   }
0467   bool translateXor(const User &U, MachineIRBuilder &MIRBuilder) {
0468     return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
0469   }
0470 
0471   bool translateUDiv(const User &U, MachineIRBuilder &MIRBuilder) {
0472     return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
0473   }
0474   bool translateSDiv(const User &U, MachineIRBuilder &MIRBuilder) {
0475     return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
0476   }
0477   bool translateURem(const User &U, MachineIRBuilder &MIRBuilder) {
0478     return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
0479   }
0480   bool translateSRem(const User &U, MachineIRBuilder &MIRBuilder) {
0481     return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
0482   }
0483   bool translateIntToPtr(const User &U, MachineIRBuilder &MIRBuilder) {
0484     return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
0485   }
0486   bool translatePtrToInt(const User &U, MachineIRBuilder &MIRBuilder) {
0487     return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
0488   }
0489   bool translateTrunc(const User &U, MachineIRBuilder &MIRBuilder) {
0490     return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
0491   }
0492   bool translateFPTrunc(const User &U, MachineIRBuilder &MIRBuilder) {
0493     return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
0494   }
0495   bool translateFPExt(const User &U, MachineIRBuilder &MIRBuilder) {
0496     return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
0497   }
0498   bool translateFPToUI(const User &U, MachineIRBuilder &MIRBuilder) {
0499     return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
0500   }
0501   bool translateFPToSI(const User &U, MachineIRBuilder &MIRBuilder) {
0502     return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
0503   }
0504   bool translateUIToFP(const User &U, MachineIRBuilder &MIRBuilder) {
0505     return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
0506   }
0507   bool translateSIToFP(const User &U, MachineIRBuilder &MIRBuilder) {
0508     return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
0509   }
0510   bool translateUnreachable(const User &U, MachineIRBuilder &MIRBuilder);
0511 
0512   bool translateSExt(const User &U, MachineIRBuilder &MIRBuilder) {
0513     return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
0514   }
0515 
0516   bool translateZExt(const User &U, MachineIRBuilder &MIRBuilder) {
0517     return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
0518   }
0519 
0520   bool translateShl(const User &U, MachineIRBuilder &MIRBuilder) {
0521     return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
0522   }
0523   bool translateLShr(const User &U, MachineIRBuilder &MIRBuilder) {
0524     return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
0525   }
0526   bool translateAShr(const User &U, MachineIRBuilder &MIRBuilder) {
0527     return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
0528   }
0529 
0530   bool translateFAdd(const User &U, MachineIRBuilder &MIRBuilder) {
0531     return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
0532   }
0533   bool translateFSub(const User &U, MachineIRBuilder &MIRBuilder) {
0534     return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
0535   }
0536   bool translateFMul(const User &U, MachineIRBuilder &MIRBuilder) {
0537     return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
0538   }
0539   bool translateFDiv(const User &U, MachineIRBuilder &MIRBuilder) {
0540     return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
0541   }
0542   bool translateFRem(const User &U, MachineIRBuilder &MIRBuilder) {
0543     return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
0544   }
0545 
0546   bool translateVAArg(const User &U, MachineIRBuilder &MIRBuilder);
0547 
0548   bool translateInsertElement(const User &U, MachineIRBuilder &MIRBuilder);
0549   bool translateInsertVector(const User &U, MachineIRBuilder &MIRBuilder);
0550 
0551   bool translateExtractElement(const User &U, MachineIRBuilder &MIRBuilder);
0552   bool translateExtractVector(const User &U, MachineIRBuilder &MIRBuilder);
0553 
0554   bool translateShuffleVector(const User &U, MachineIRBuilder &MIRBuilder);
0555 
0556   bool translateAtomicCmpXchg(const User &U, MachineIRBuilder &MIRBuilder);
0557   bool translateAtomicRMW(const User &U, MachineIRBuilder &MIRBuilder);
0558   bool translateFence(const User &U, MachineIRBuilder &MIRBuilder);
0559   bool translateFreeze(const User &U, MachineIRBuilder &MIRBuilder);
0560 
0561   // Stubs to keep the compiler happy while we implement the rest of the
0562   // translation.
0563   bool translateResume(const User &U, MachineIRBuilder &MIRBuilder) {
0564     return false;
0565   }
0566   bool translateCleanupRet(const User &U, MachineIRBuilder &MIRBuilder) {
0567     return false;
0568   }
0569   bool translateCatchRet(const User &U, MachineIRBuilder &MIRBuilder) {
0570     return false;
0571   }
0572   bool translateCatchSwitch(const User &U, MachineIRBuilder &MIRBuilder) {
0573     return false;
0574   }
0575   bool translateAddrSpaceCast(const User &U, MachineIRBuilder &MIRBuilder) {
0576     return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
0577   }
0578   bool translateCleanupPad(const User &U, MachineIRBuilder &MIRBuilder) {
0579     return false;
0580   }
0581   bool translateCatchPad(const User &U, MachineIRBuilder &MIRBuilder) {
0582     return false;
0583   }
0584   bool translateUserOp1(const User &U, MachineIRBuilder &MIRBuilder) {
0585     return false;
0586   }
0587   bool translateUserOp2(const User &U, MachineIRBuilder &MIRBuilder) {
0588     return false;
0589   }
0590 
0591   bool translateConvergenceControlIntrinsic(const CallInst &CI,
0592                                             Intrinsic::ID ID,
0593                                             MachineIRBuilder &MIRBuilder);
0594 
0595   /// @}
0596 
0597   // Builder for machine instruction a la IRBuilder.
0598   // I.e., compared to regular MIBuilder, this one also inserts the instruction
0599   // in the current block, it can creates block, etc., basically a kind of
0600   // IRBuilder, but for Machine IR.
0601   // CSEMIRBuilder CurBuilder;
0602   std::unique_ptr<MachineIRBuilder> CurBuilder;
0603 
0604   // Builder set to the entry block (just after ABI lowering instructions). Used
0605   // as a convenient location for Constants.
0606   // CSEMIRBuilder EntryBuilder;
0607   std::unique_ptr<MachineIRBuilder> EntryBuilder;
0608 
0609   // The MachineFunction currently being translated.
0610   MachineFunction *MF = nullptr;
0611 
0612   /// MachineRegisterInfo used to create virtual registers.
0613   MachineRegisterInfo *MRI = nullptr;
0614 
0615   const DataLayout *DL = nullptr;
0616 
0617   /// Current target configuration. Controls how the pass handles errors.
0618   const TargetPassConfig *TPC = nullptr;
0619 
0620   CodeGenOptLevel OptLevel;
0621 
0622   /// Current optimization remark emitter. Used to report failures.
0623   std::unique_ptr<OptimizationRemarkEmitter> ORE;
0624 
0625   AAResults *AA = nullptr;
0626   AssumptionCache *AC = nullptr;
0627   const TargetLibraryInfo *LibInfo = nullptr;
0628   const TargetLowering *TLI = nullptr;
0629   FunctionLoweringInfo FuncInfo;
0630 
0631   // True when either the Target Machine specifies no optimizations or the
0632   // function has the optnone attribute.
0633   bool EnableOpts = false;
0634 
0635   /// True when the block contains a tail call. This allows the IRTranslator to
0636   /// stop translating such blocks early.
0637   bool HasTailCall = false;
0638 
0639   StackProtectorDescriptor SPDescriptor;
0640 
0641   /// Switch analysis and optimization.
0642   class GISelSwitchLowering : public SwitchCG::SwitchLowering {
0643   public:
0644     GISelSwitchLowering(IRTranslator *irt, FunctionLoweringInfo &funcinfo)
0645         : SwitchLowering(funcinfo), IRT(irt) {
0646       assert(irt && "irt is null!");
0647     }
0648 
0649     void addSuccessorWithProb(
0650         MachineBasicBlock *Src, MachineBasicBlock *Dst,
0651         BranchProbability Prob = BranchProbability::getUnknown()) override {
0652       IRT->addSuccessorWithProb(Src, Dst, Prob);
0653     }
0654 
0655     virtual ~GISelSwitchLowering() = default;
0656 
0657   private:
0658     IRTranslator *IRT;
0659   };
0660 
0661   std::unique_ptr<GISelSwitchLowering> SL;
0662 
0663   // * Insert all the code needed to materialize the constants
0664   // at the proper place. E.g., Entry block or dominator block
0665   // of each constant depending on how fancy we want to be.
0666   // * Clear the different maps.
0667   void finalizeFunction();
0668 
0669   // Processing steps done per block. E.g. emitting jump tables, stack
0670   // protectors etc. Returns true if no errors, false if there was a problem
0671   // that caused an abort.
0672   bool finalizeBasicBlock(const BasicBlock &BB, MachineBasicBlock &MBB);
0673 
0674   /// Codegen a new tail for a stack protector check ParentMBB which has had its
0675   /// tail spliced into a stack protector check success bb.
0676   ///
0677   /// For a high level explanation of how this fits into the stack protector
0678   /// generation see the comment on the declaration of class
0679   /// StackProtectorDescriptor.
0680   ///
0681   /// \return true if there were no problems.
0682   bool emitSPDescriptorParent(StackProtectorDescriptor &SPD,
0683                               MachineBasicBlock *ParentBB);
0684 
0685   /// Codegen the failure basic block for a stack protector check.
0686   ///
0687   /// A failure stack protector machine basic block consists simply of a call to
0688   /// __stack_chk_fail().
0689   ///
0690   /// For a high level explanation of how this fits into the stack protector
0691   /// generation see the comment on the declaration of class
0692   /// StackProtectorDescriptor.
0693   ///
0694   /// \return true if there were no problems.
0695   bool emitSPDescriptorFailure(StackProtectorDescriptor &SPD,
0696                                MachineBasicBlock *FailureBB);
0697 
0698   /// Get the VRegs that represent \p Val.
0699   /// Non-aggregate types have just one corresponding VReg and the list can be
0700   /// used as a single "unsigned". Aggregates get flattened. If such VRegs do
0701   /// not exist, they are created.
0702   ArrayRef<Register> getOrCreateVRegs(const Value &Val);
0703 
0704   Register getOrCreateVReg(const Value &Val) {
0705     auto Regs = getOrCreateVRegs(Val);
0706     if (Regs.empty())
0707       return 0;
0708     assert(Regs.size() == 1 &&
0709            "attempt to get single VReg for aggregate or void");
0710     return Regs[0];
0711   }
0712 
0713   Register getOrCreateConvergenceTokenVReg(const Value &Token) {
0714     assert(Token.getType()->isTokenTy());
0715     auto &Regs = *VMap.getVRegs(Token);
0716     if (!Regs.empty()) {
0717       assert(Regs.size() == 1 &&
0718              "Expected a single register for convergence tokens.");
0719       return Regs[0];
0720     }
0721 
0722     auto Reg = MRI->createGenericVirtualRegister(LLT::token());
0723     Regs.push_back(Reg);
0724     auto &Offsets = *VMap.getOffsets(Token);
0725     if (Offsets.empty())
0726       Offsets.push_back(0);
0727     return Reg;
0728   }
0729 
0730   /// Allocate some vregs and offsets in the VMap. Then populate just the
0731   /// offsets while leaving the vregs empty.
0732   ValueToVRegInfo::VRegListT &allocateVRegs(const Value &Val);
0733 
0734   /// Get the frame index that represents \p Val.
0735   /// If such VReg does not exist, it is created.
0736   int getOrCreateFrameIndex(const AllocaInst &AI);
0737 
0738   /// Get the alignment of the given memory operation instruction. This will
0739   /// either be the explicitly specified value or the ABI-required alignment for
0740   /// the type being accessed (according to the Module's DataLayout).
0741   Align getMemOpAlign(const Instruction &I);
0742 
0743   /// Get the MachineBasicBlock that represents \p BB. Specifically, the block
0744   /// returned will be the head of the translated block (suitable for branch
0745   /// destinations).
0746   MachineBasicBlock &getMBB(const BasicBlock &BB);
0747 
0748   /// Record \p NewPred as a Machine predecessor to `Edge.second`, corresponding
0749   /// to `Edge.first` at the IR level. This is used when IRTranslation creates
0750   /// multiple MachineBasicBlocks for a given IR block and the CFG is no longer
0751   /// represented simply by the IR-level CFG.
0752   void addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred);
0753 
0754   /// Returns the Machine IR predecessors for the given IR CFG edge. Usually
0755   /// this is just the single MachineBasicBlock corresponding to the predecessor
0756   /// in the IR. More complex lowering can result in multiple MachineBasicBlocks
0757   /// preceding the original though (e.g. switch instructions).
0758   SmallVector<MachineBasicBlock *, 1> getMachinePredBBs(CFGEdge Edge) {
0759     auto RemappedEdge = MachinePreds.find(Edge);
0760     if (RemappedEdge != MachinePreds.end())
0761       return RemappedEdge->second;
0762     return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*Edge.first));
0763   }
0764 
0765   /// Return branch probability calculated by BranchProbabilityInfo for IR
0766   /// blocks.
0767   BranchProbability getEdgeProbability(const MachineBasicBlock *Src,
0768                                        const MachineBasicBlock *Dst) const;
0769 
0770   void addSuccessorWithProb(
0771       MachineBasicBlock *Src, MachineBasicBlock *Dst,
0772       BranchProbability Prob = BranchProbability::getUnknown());
0773 
0774 public:
0775   IRTranslator(CodeGenOptLevel OptLevel = CodeGenOptLevel::None);
0776 
0777   StringRef getPassName() const override { return "IRTranslator"; }
0778 
0779   void getAnalysisUsage(AnalysisUsage &AU) const override;
0780 
0781   // Algo:
0782   //   CallLowering = MF.subtarget.getCallLowering()
0783   //   F = MF.getParent()
0784   //   MIRBuilder.reset(MF)
0785   //   getMBB(F.getEntryBB())
0786   //   CallLowering->translateArguments(MIRBuilder, F, ValToVReg)
0787   //   for each bb in F
0788   //     getMBB(bb)
0789   //     for each inst in bb
0790   //       if (!translate(MIRBuilder, inst, ValToVReg, ConstantToSequence))
0791   //         report_fatal_error("Don't know how to translate input");
0792   //   finalize()
0793   bool runOnMachineFunction(MachineFunction &MF) override;
0794 };
0795 
0796 } // end namespace llvm
0797 
0798 #endif // LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H