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 DbgDeclareInst; 45 class DbgValueInst; 46 class Instruction; 47 class MachineBasicBlock; 48 class MachineFunction; 49 class MachineInstr; 50 class MachineRegisterInfo; 51 class OptimizationRemarkEmitter; 52 class PHINode; 53 class TargetLibraryInfo; 54 class TargetPassConfig; 55 class User; 56 class Value; 57 58 // Technically the pass should run on an hypothetical MachineModule, 59 // since it should translate Global into some sort of MachineGlobal. 60 // The MachineGlobal should ultimately just be a transfer of ownership of 61 // the interesting bits that are relevant to represent a global value. 62 // That being said, we could investigate what would it cost to just duplicate 63 // the information from the LLVM IR. 64 // The idea is that ultimately we would be able to free up the memory used 65 // by the LLVM IR as soon as the translation is over. 66 class IRTranslator : public MachineFunctionPass { 67 public: 68 static char ID; 69 70 private: 71 /// Interface used to lower the everything related to calls. 72 const CallLowering *CLI = nullptr; 73 74 /// This class contains the mapping between the Values to vreg related data. 75 class ValueToVRegInfo { 76 public: 77 ValueToVRegInfo() = default; 78 79 using VRegListT = SmallVector<Register, 1>; 80 using OffsetListT = SmallVector<uint64_t, 1>; 81 82 using const_vreg_iterator = 83 DenseMap<const Value *, VRegListT *>::const_iterator; 84 using const_offset_iterator = 85 DenseMap<const Value *, OffsetListT *>::const_iterator; 86 vregs_end()87 inline const_vreg_iterator vregs_end() const { return ValToVRegs.end(); } 88 getVRegs(const Value & V)89 VRegListT *getVRegs(const Value &V) { 90 auto It = ValToVRegs.find(&V); 91 if (It != ValToVRegs.end()) 92 return It->second; 93 94 return insertVRegs(V); 95 } 96 getOffsets(const Value & V)97 OffsetListT *getOffsets(const Value &V) { 98 auto It = TypeToOffsets.find(V.getType()); 99 if (It != TypeToOffsets.end()) 100 return It->second; 101 102 return insertOffsets(V); 103 } 104 findVRegs(const Value & V)105 const_vreg_iterator findVRegs(const Value &V) const { 106 return ValToVRegs.find(&V); 107 } 108 contains(const Value & V)109 bool contains(const Value &V) const { return ValToVRegs.contains(&V); } 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.contains(&V) && "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.contains(V.getType()) && "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 /// Examine any debug-info attached to the instruction (in the form of 208 /// DbgRecords) and translate it. 209 void translateDbgInfo(const Instruction &Inst, 210 MachineIRBuilder &MIRBuilder); 211 212 /// Translate a debug-info record of a dbg.value into a DBG_* instruction. 213 /// Pass in all the contents of the record, rather than relying on how it's 214 /// stored. 215 void translateDbgValueRecord(Value *V, bool HasArgList, 216 const DILocalVariable *Variable, 217 const DIExpression *Expression, const DebugLoc &DL, 218 MachineIRBuilder &MIRBuilder); 219 220 /// Translate a debug-info record of a dbg.declare into an indirect DBG_* 221 /// instruction. Pass in all the contents of the record, rather than relying 222 /// on how it's stored. 223 void translateDbgDeclareRecord(Value *Address, bool HasArgList, 224 const DILocalVariable *Variable, 225 const DIExpression *Expression, const DebugLoc &DL, 226 MachineIRBuilder &MIRBuilder); 227 228 // Translate U as a copy of V. 229 bool translateCopy(const User &U, const Value &V, 230 MachineIRBuilder &MIRBuilder); 231 232 /// Translate an LLVM bitcast into generic IR. Either a COPY or a G_BITCAST is 233 /// emitted. 234 bool translateBitCast(const User &U, MachineIRBuilder &MIRBuilder); 235 236 /// Translate an LLVM load instruction into generic IR. 237 bool translateLoad(const User &U, MachineIRBuilder &MIRBuilder); 238 239 /// Translate an LLVM store instruction into generic IR. 240 bool translateStore(const User &U, MachineIRBuilder &MIRBuilder); 241 242 /// Translate an LLVM string intrinsic (memcpy, memset, ...). 243 bool translateMemFunc(const CallInst &CI, MachineIRBuilder &MIRBuilder, 244 unsigned Opcode); 245 246 void getStackGuard(Register DstReg, MachineIRBuilder &MIRBuilder); 247 248 bool translateOverflowIntrinsic(const CallInst &CI, unsigned Op, 249 MachineIRBuilder &MIRBuilder); 250 bool translateFixedPointIntrinsic(unsigned Op, const CallInst &CI, 251 MachineIRBuilder &MIRBuilder); 252 253 /// Helper function for translateSimpleIntrinsic. 254 /// \return The generic opcode for \p IntrinsicID if \p IntrinsicID is a 255 /// simple intrinsic (ceil, fabs, etc.). Otherwise, returns 256 /// Intrinsic::not_intrinsic. 257 unsigned getSimpleIntrinsicOpcode(Intrinsic::ID ID); 258 259 /// Translates the intrinsics defined in getSimpleIntrinsicOpcode. 260 /// \return true if the translation succeeded. 261 bool translateSimpleIntrinsic(const CallInst &CI, Intrinsic::ID ID, 262 MachineIRBuilder &MIRBuilder); 263 264 bool translateConstrainedFPIntrinsic(const ConstrainedFPIntrinsic &FPI, 265 MachineIRBuilder &MIRBuilder); 266 267 bool translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID, 268 MachineIRBuilder &MIRBuilder); 269 270 /// Returns the single livein physical register Arg was lowered to, if 271 /// possible. 272 std::optional<MCRegister> getArgPhysReg(Argument &Arg); 273 274 /// If debug-info targets an Argument and its expression is an EntryValue, 275 /// lower it as either an entry in the MF debug table (dbg.declare), or a 276 /// DBG_VALUE targeting the corresponding livein register for that Argument 277 /// (dbg.value). 278 bool translateIfEntryValueArgument(bool isDeclare, Value *Arg, 279 const DILocalVariable *Var, 280 const DIExpression *Expr, 281 const DebugLoc &DL, 282 MachineIRBuilder &MIRBuilder); 283 284 bool translateInlineAsm(const CallBase &CB, MachineIRBuilder &MIRBuilder); 285 286 /// Common code for translating normal calls or invokes. 287 bool translateCallBase(const CallBase &CB, MachineIRBuilder &MIRBuilder); 288 289 /// Translate call instruction. 290 /// \pre \p U is a call instruction. 291 bool translateCall(const User &U, MachineIRBuilder &MIRBuilder); 292 293 /// When an invoke or a cleanupret unwinds to the next EH pad, there are 294 /// many places it could ultimately go. In the IR, we have a single unwind 295 /// destination, but in the machine CFG, we enumerate all the possible blocks. 296 /// This function skips over imaginary basic blocks that hold catchswitch 297 /// instructions, and finds all the "real" machine 298 /// basic block destinations. As those destinations may not be successors of 299 /// EHPadBB, here we also calculate the edge probability to those 300 /// destinations. The passed-in Prob is the edge probability to EHPadBB. 301 bool findUnwindDestinations( 302 const BasicBlock *EHPadBB, BranchProbability Prob, 303 SmallVectorImpl<std::pair<MachineBasicBlock *, BranchProbability>> 304 &UnwindDests); 305 306 bool translateInvoke(const User &U, MachineIRBuilder &MIRBuilder); 307 308 bool translateCallBr(const User &U, MachineIRBuilder &MIRBuilder); 309 310 bool translateLandingPad(const User &U, MachineIRBuilder &MIRBuilder); 311 312 /// Translate one of LLVM's cast instructions into MachineInstrs, with the 313 /// given generic Opcode. 314 bool translateCast(unsigned Opcode, const User &U, 315 MachineIRBuilder &MIRBuilder); 316 317 /// Translate a phi instruction. 318 bool translatePHI(const User &U, MachineIRBuilder &MIRBuilder); 319 320 /// Translate a comparison (icmp or fcmp) instruction or constant. 321 bool translateCompare(const User &U, MachineIRBuilder &MIRBuilder); 322 323 /// Translate an integer compare instruction (or constant). translateICmp(const User & U,MachineIRBuilder & MIRBuilder)324 bool translateICmp(const User &U, MachineIRBuilder &MIRBuilder) { 325 return translateCompare(U, MIRBuilder); 326 } 327 328 /// Translate a floating-point compare instruction (or constant). translateFCmp(const User & U,MachineIRBuilder & MIRBuilder)329 bool translateFCmp(const User &U, MachineIRBuilder &MIRBuilder) { 330 return translateCompare(U, MIRBuilder); 331 } 332 333 /// Add remaining operands onto phis we've translated. Executed after all 334 /// MachineBasicBlocks for the function have been created. 335 void finishPendingPhis(); 336 337 /// Translate \p Inst into a unary operation \p Opcode. 338 /// \pre \p U is a unary operation. 339 bool translateUnaryOp(unsigned Opcode, const User &U, 340 MachineIRBuilder &MIRBuilder); 341 342 /// Translate \p Inst into a binary operation \p Opcode. 343 /// \pre \p U is a binary operation. 344 bool translateBinaryOp(unsigned Opcode, const User &U, 345 MachineIRBuilder &MIRBuilder); 346 347 /// If the set of cases should be emitted as a series of branches, return 348 /// true. If we should emit this as a bunch of and/or'd together conditions, 349 /// return false. 350 bool shouldEmitAsBranches(const std::vector<SwitchCG::CaseBlock> &Cases); 351 /// Helper method for findMergedConditions. 352 /// This function emits a branch and is used at the leaves of an OR or an 353 /// AND operator tree. 354 void emitBranchForMergedCondition(const Value *Cond, MachineBasicBlock *TBB, 355 MachineBasicBlock *FBB, 356 MachineBasicBlock *CurBB, 357 MachineBasicBlock *SwitchBB, 358 BranchProbability TProb, 359 BranchProbability FProb, bool InvertCond); 360 /// Used during condbr translation to find trees of conditions that can be 361 /// optimized. 362 void findMergedConditions(const Value *Cond, MachineBasicBlock *TBB, 363 MachineBasicBlock *FBB, MachineBasicBlock *CurBB, 364 MachineBasicBlock *SwitchBB, 365 Instruction::BinaryOps Opc, BranchProbability TProb, 366 BranchProbability FProb, bool InvertCond); 367 368 /// Translate branch (br) instruction. 369 /// \pre \p U is a branch instruction. 370 bool translateBr(const User &U, MachineIRBuilder &MIRBuilder); 371 372 // Begin switch lowering functions. 373 bool emitJumpTableHeader(SwitchCG::JumpTable &JT, 374 SwitchCG::JumpTableHeader &JTH, 375 MachineBasicBlock *HeaderBB); 376 void emitJumpTable(SwitchCG::JumpTable &JT, MachineBasicBlock *MBB); 377 378 void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB, 379 MachineIRBuilder &MIB); 380 381 /// Generate for the BitTest header block, which precedes each sequence of 382 /// BitTestCases. 383 void emitBitTestHeader(SwitchCG::BitTestBlock &BTB, 384 MachineBasicBlock *SwitchMBB); 385 /// Generate code to produces one "bit test" for a given BitTestCase \p B. 386 void emitBitTestCase(SwitchCG::BitTestBlock &BB, MachineBasicBlock *NextMBB, 387 BranchProbability BranchProbToNext, Register Reg, 388 SwitchCG::BitTestCase &B, MachineBasicBlock *SwitchBB); 389 390 void splitWorkItem(SwitchCG::SwitchWorkList &WorkList, 391 const SwitchCG::SwitchWorkListItem &W, Value *Cond, 392 MachineBasicBlock *SwitchMBB, MachineIRBuilder &MIB); 393 394 bool lowerJumpTableWorkItem( 395 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB, 396 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB, 397 MachineIRBuilder &MIB, MachineFunction::iterator BBI, 398 BranchProbability UnhandledProbs, SwitchCG::CaseClusterIt I, 399 MachineBasicBlock *Fallthrough, bool FallthroughUnreachable); 400 401 bool lowerSwitchRangeWorkItem(SwitchCG::CaseClusterIt I, Value *Cond, 402 MachineBasicBlock *Fallthrough, 403 bool FallthroughUnreachable, 404 BranchProbability UnhandledProbs, 405 MachineBasicBlock *CurMBB, 406 MachineIRBuilder &MIB, 407 MachineBasicBlock *SwitchMBB); 408 409 bool lowerBitTestWorkItem( 410 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB, 411 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB, 412 MachineIRBuilder &MIB, MachineFunction::iterator BBI, 413 BranchProbability DefaultProb, BranchProbability UnhandledProbs, 414 SwitchCG::CaseClusterIt I, MachineBasicBlock *Fallthrough, 415 bool FallthroughUnreachable); 416 417 bool lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W, Value *Cond, 418 MachineBasicBlock *SwitchMBB, 419 MachineBasicBlock *DefaultMBB, 420 MachineIRBuilder &MIB); 421 422 bool translateSwitch(const User &U, MachineIRBuilder &MIRBuilder); 423 // End switch lowering section. 424 425 bool translateIndirectBr(const User &U, MachineIRBuilder &MIRBuilder); 426 427 bool translateExtractValue(const User &U, MachineIRBuilder &MIRBuilder); 428 429 bool translateInsertValue(const User &U, MachineIRBuilder &MIRBuilder); 430 431 bool translateSelect(const User &U, MachineIRBuilder &MIRBuilder); 432 433 bool translateGetElementPtr(const User &U, MachineIRBuilder &MIRBuilder); 434 435 bool translateAlloca(const User &U, MachineIRBuilder &MIRBuilder); 436 437 /// Translate return (ret) instruction. 438 /// The target needs to implement CallLowering::lowerReturn for 439 /// this to succeed. 440 /// \pre \p U is a return instruction. 441 bool translateRet(const User &U, MachineIRBuilder &MIRBuilder); 442 443 bool translateFNeg(const User &U, MachineIRBuilder &MIRBuilder); 444 translateAdd(const User & U,MachineIRBuilder & MIRBuilder)445 bool translateAdd(const User &U, MachineIRBuilder &MIRBuilder) { 446 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder); 447 } translateSub(const User & U,MachineIRBuilder & MIRBuilder)448 bool translateSub(const User &U, MachineIRBuilder &MIRBuilder) { 449 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder); 450 } translateAnd(const User & U,MachineIRBuilder & MIRBuilder)451 bool translateAnd(const User &U, MachineIRBuilder &MIRBuilder) { 452 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder); 453 } translateMul(const User & U,MachineIRBuilder & MIRBuilder)454 bool translateMul(const User &U, MachineIRBuilder &MIRBuilder) { 455 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder); 456 } translateOr(const User & U,MachineIRBuilder & MIRBuilder)457 bool translateOr(const User &U, MachineIRBuilder &MIRBuilder) { 458 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder); 459 } translateXor(const User & U,MachineIRBuilder & MIRBuilder)460 bool translateXor(const User &U, MachineIRBuilder &MIRBuilder) { 461 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder); 462 } 463 translateUDiv(const User & U,MachineIRBuilder & MIRBuilder)464 bool translateUDiv(const User &U, MachineIRBuilder &MIRBuilder) { 465 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder); 466 } translateSDiv(const User & U,MachineIRBuilder & MIRBuilder)467 bool translateSDiv(const User &U, MachineIRBuilder &MIRBuilder) { 468 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder); 469 } translateURem(const User & U,MachineIRBuilder & MIRBuilder)470 bool translateURem(const User &U, MachineIRBuilder &MIRBuilder) { 471 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder); 472 } translateSRem(const User & U,MachineIRBuilder & MIRBuilder)473 bool translateSRem(const User &U, MachineIRBuilder &MIRBuilder) { 474 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder); 475 } translateIntToPtr(const User & U,MachineIRBuilder & MIRBuilder)476 bool translateIntToPtr(const User &U, MachineIRBuilder &MIRBuilder) { 477 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder); 478 } translatePtrToInt(const User & U,MachineIRBuilder & MIRBuilder)479 bool translatePtrToInt(const User &U, MachineIRBuilder &MIRBuilder) { 480 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder); 481 } translateTrunc(const User & U,MachineIRBuilder & MIRBuilder)482 bool translateTrunc(const User &U, MachineIRBuilder &MIRBuilder) { 483 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder); 484 } translateFPTrunc(const User & U,MachineIRBuilder & MIRBuilder)485 bool translateFPTrunc(const User &U, MachineIRBuilder &MIRBuilder) { 486 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder); 487 } translateFPExt(const User & U,MachineIRBuilder & MIRBuilder)488 bool translateFPExt(const User &U, MachineIRBuilder &MIRBuilder) { 489 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder); 490 } translateFPToUI(const User & U,MachineIRBuilder & MIRBuilder)491 bool translateFPToUI(const User &U, MachineIRBuilder &MIRBuilder) { 492 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder); 493 } translateFPToSI(const User & U,MachineIRBuilder & MIRBuilder)494 bool translateFPToSI(const User &U, MachineIRBuilder &MIRBuilder) { 495 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder); 496 } translateUIToFP(const User & U,MachineIRBuilder & MIRBuilder)497 bool translateUIToFP(const User &U, MachineIRBuilder &MIRBuilder) { 498 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder); 499 } translateSIToFP(const User & U,MachineIRBuilder & MIRBuilder)500 bool translateSIToFP(const User &U, MachineIRBuilder &MIRBuilder) { 501 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder); 502 } 503 bool translateUnreachable(const User &U, MachineIRBuilder &MIRBuilder); 504 translateSExt(const User & U,MachineIRBuilder & MIRBuilder)505 bool translateSExt(const User &U, MachineIRBuilder &MIRBuilder) { 506 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder); 507 } 508 translateZExt(const User & U,MachineIRBuilder & MIRBuilder)509 bool translateZExt(const User &U, MachineIRBuilder &MIRBuilder) { 510 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder); 511 } 512 translateShl(const User & U,MachineIRBuilder & MIRBuilder)513 bool translateShl(const User &U, MachineIRBuilder &MIRBuilder) { 514 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder); 515 } translateLShr(const User & U,MachineIRBuilder & MIRBuilder)516 bool translateLShr(const User &U, MachineIRBuilder &MIRBuilder) { 517 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder); 518 } translateAShr(const User & U,MachineIRBuilder & MIRBuilder)519 bool translateAShr(const User &U, MachineIRBuilder &MIRBuilder) { 520 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder); 521 } 522 translateFAdd(const User & U,MachineIRBuilder & MIRBuilder)523 bool translateFAdd(const User &U, MachineIRBuilder &MIRBuilder) { 524 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder); 525 } translateFSub(const User & U,MachineIRBuilder & MIRBuilder)526 bool translateFSub(const User &U, MachineIRBuilder &MIRBuilder) { 527 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder); 528 } translateFMul(const User & U,MachineIRBuilder & MIRBuilder)529 bool translateFMul(const User &U, MachineIRBuilder &MIRBuilder) { 530 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder); 531 } translateFDiv(const User & U,MachineIRBuilder & MIRBuilder)532 bool translateFDiv(const User &U, MachineIRBuilder &MIRBuilder) { 533 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder); 534 } translateFRem(const User & U,MachineIRBuilder & MIRBuilder)535 bool translateFRem(const User &U, MachineIRBuilder &MIRBuilder) { 536 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder); 537 } 538 539 bool translateVAArg(const User &U, MachineIRBuilder &MIRBuilder); 540 541 bool translateInsertElement(const User &U, MachineIRBuilder &MIRBuilder); 542 543 bool translateExtractElement(const User &U, MachineIRBuilder &MIRBuilder); 544 545 bool translateShuffleVector(const User &U, MachineIRBuilder &MIRBuilder); 546 547 bool translateAtomicCmpXchg(const User &U, MachineIRBuilder &MIRBuilder); 548 bool translateAtomicRMW(const User &U, MachineIRBuilder &MIRBuilder); 549 bool translateFence(const User &U, MachineIRBuilder &MIRBuilder); 550 bool translateFreeze(const User &U, MachineIRBuilder &MIRBuilder); 551 552 // Stubs to keep the compiler happy while we implement the rest of the 553 // translation. translateResume(const User & U,MachineIRBuilder & MIRBuilder)554 bool translateResume(const User &U, MachineIRBuilder &MIRBuilder) { 555 return false; 556 } translateCleanupRet(const User & U,MachineIRBuilder & MIRBuilder)557 bool translateCleanupRet(const User &U, MachineIRBuilder &MIRBuilder) { 558 return false; 559 } translateCatchRet(const User & U,MachineIRBuilder & MIRBuilder)560 bool translateCatchRet(const User &U, MachineIRBuilder &MIRBuilder) { 561 return false; 562 } translateCatchSwitch(const User & U,MachineIRBuilder & MIRBuilder)563 bool translateCatchSwitch(const User &U, MachineIRBuilder &MIRBuilder) { 564 return false; 565 } translateAddrSpaceCast(const User & U,MachineIRBuilder & MIRBuilder)566 bool translateAddrSpaceCast(const User &U, MachineIRBuilder &MIRBuilder) { 567 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder); 568 } translateCleanupPad(const User & U,MachineIRBuilder & MIRBuilder)569 bool translateCleanupPad(const User &U, MachineIRBuilder &MIRBuilder) { 570 return false; 571 } translateCatchPad(const User & U,MachineIRBuilder & MIRBuilder)572 bool translateCatchPad(const User &U, MachineIRBuilder &MIRBuilder) { 573 return false; 574 } translateUserOp1(const User & U,MachineIRBuilder & MIRBuilder)575 bool translateUserOp1(const User &U, MachineIRBuilder &MIRBuilder) { 576 return false; 577 } translateUserOp2(const User & U,MachineIRBuilder & MIRBuilder)578 bool translateUserOp2(const User &U, MachineIRBuilder &MIRBuilder) { 579 return false; 580 } 581 582 /// @} 583 584 // Builder for machine instruction a la IRBuilder. 585 // I.e., compared to regular MIBuilder, this one also inserts the instruction 586 // in the current block, it can creates block, etc., basically a kind of 587 // IRBuilder, but for Machine IR. 588 // CSEMIRBuilder CurBuilder; 589 std::unique_ptr<MachineIRBuilder> CurBuilder; 590 591 // Builder set to the entry block (just after ABI lowering instructions). Used 592 // as a convenient location for Constants. 593 // CSEMIRBuilder EntryBuilder; 594 std::unique_ptr<MachineIRBuilder> EntryBuilder; 595 596 // The MachineFunction currently being translated. 597 MachineFunction *MF = nullptr; 598 599 /// MachineRegisterInfo used to create virtual registers. 600 MachineRegisterInfo *MRI = nullptr; 601 602 const DataLayout *DL = nullptr; 603 604 /// Current target configuration. Controls how the pass handles errors. 605 const TargetPassConfig *TPC = nullptr; 606 607 CodeGenOptLevel OptLevel; 608 609 /// Current optimization remark emitter. Used to report failures. 610 std::unique_ptr<OptimizationRemarkEmitter> ORE; 611 612 AAResults *AA = nullptr; 613 AssumptionCache *AC = nullptr; 614 const TargetLibraryInfo *LibInfo = nullptr; 615 const TargetLowering *TLI = nullptr; 616 FunctionLoweringInfo FuncInfo; 617 618 // True when either the Target Machine specifies no optimizations or the 619 // function has the optnone attribute. 620 bool EnableOpts = false; 621 622 /// True when the block contains a tail call. This allows the IRTranslator to 623 /// stop translating such blocks early. 624 bool HasTailCall = false; 625 626 StackProtectorDescriptor SPDescriptor; 627 628 /// Switch analysis and optimization. 629 class GISelSwitchLowering : public SwitchCG::SwitchLowering { 630 public: GISelSwitchLowering(IRTranslator * irt,FunctionLoweringInfo & funcinfo)631 GISelSwitchLowering(IRTranslator *irt, FunctionLoweringInfo &funcinfo) 632 : SwitchLowering(funcinfo), IRT(irt) { 633 assert(irt && "irt is null!"); 634 } 635 636 void addSuccessorWithProb( 637 MachineBasicBlock *Src, MachineBasicBlock *Dst, 638 BranchProbability Prob = BranchProbability::getUnknown()) override { 639 IRT->addSuccessorWithProb(Src, Dst, Prob); 640 } 641 642 virtual ~GISelSwitchLowering() = default; 643 644 private: 645 IRTranslator *IRT; 646 }; 647 648 std::unique_ptr<GISelSwitchLowering> SL; 649 650 // * Insert all the code needed to materialize the constants 651 // at the proper place. E.g., Entry block or dominator block 652 // of each constant depending on how fancy we want to be. 653 // * Clear the different maps. 654 void finalizeFunction(); 655 656 // Processing steps done per block. E.g. emitting jump tables, stack 657 // protectors etc. Returns true if no errors, false if there was a problem 658 // that caused an abort. 659 bool finalizeBasicBlock(const BasicBlock &BB, MachineBasicBlock &MBB); 660 661 /// Codegen a new tail for a stack protector check ParentMBB which has had its 662 /// tail spliced into a stack protector check success bb. 663 /// 664 /// For a high level explanation of how this fits into the stack protector 665 /// generation see the comment on the declaration of class 666 /// StackProtectorDescriptor. 667 /// 668 /// \return true if there were no problems. 669 bool emitSPDescriptorParent(StackProtectorDescriptor &SPD, 670 MachineBasicBlock *ParentBB); 671 672 /// Codegen the failure basic block for a stack protector check. 673 /// 674 /// A failure stack protector machine basic block consists simply of a call to 675 /// __stack_chk_fail(). 676 /// 677 /// For a high level explanation of how this fits into the stack protector 678 /// generation see the comment on the declaration of class 679 /// StackProtectorDescriptor. 680 /// 681 /// \return true if there were no problems. 682 bool emitSPDescriptorFailure(StackProtectorDescriptor &SPD, 683 MachineBasicBlock *FailureBB); 684 685 /// Get the VRegs that represent \p Val. 686 /// Non-aggregate types have just one corresponding VReg and the list can be 687 /// used as a single "unsigned". Aggregates get flattened. If such VRegs do 688 /// not exist, they are created. 689 ArrayRef<Register> getOrCreateVRegs(const Value &Val); 690 getOrCreateVReg(const Value & Val)691 Register getOrCreateVReg(const Value &Val) { 692 auto Regs = getOrCreateVRegs(Val); 693 if (Regs.empty()) 694 return 0; 695 assert(Regs.size() == 1 && 696 "attempt to get single VReg for aggregate or void"); 697 return Regs[0]; 698 } 699 700 /// Allocate some vregs and offsets in the VMap. Then populate just the 701 /// offsets while leaving the vregs empty. 702 ValueToVRegInfo::VRegListT &allocateVRegs(const Value &Val); 703 704 /// Get the frame index that represents \p Val. 705 /// If such VReg does not exist, it is created. 706 int getOrCreateFrameIndex(const AllocaInst &AI); 707 708 /// Get the alignment of the given memory operation instruction. This will 709 /// either be the explicitly specified value or the ABI-required alignment for 710 /// the type being accessed (according to the Module's DataLayout). 711 Align getMemOpAlign(const Instruction &I); 712 713 /// Get the MachineBasicBlock that represents \p BB. Specifically, the block 714 /// returned will be the head of the translated block (suitable for branch 715 /// destinations). 716 MachineBasicBlock &getMBB(const BasicBlock &BB); 717 718 /// Record \p NewPred as a Machine predecessor to `Edge.second`, corresponding 719 /// to `Edge.first` at the IR level. This is used when IRTranslation creates 720 /// multiple MachineBasicBlocks for a given IR block and the CFG is no longer 721 /// represented simply by the IR-level CFG. 722 void addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred); 723 724 /// Returns the Machine IR predecessors for the given IR CFG edge. Usually 725 /// this is just the single MachineBasicBlock corresponding to the predecessor 726 /// in the IR. More complex lowering can result in multiple MachineBasicBlocks 727 /// preceding the original though (e.g. switch instructions). getMachinePredBBs(CFGEdge Edge)728 SmallVector<MachineBasicBlock *, 1> getMachinePredBBs(CFGEdge Edge) { 729 auto RemappedEdge = MachinePreds.find(Edge); 730 if (RemappedEdge != MachinePreds.end()) 731 return RemappedEdge->second; 732 return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*Edge.first)); 733 } 734 735 /// Return branch probability calculated by BranchProbabilityInfo for IR 736 /// blocks. 737 BranchProbability getEdgeProbability(const MachineBasicBlock *Src, 738 const MachineBasicBlock *Dst) const; 739 740 void addSuccessorWithProb( 741 MachineBasicBlock *Src, MachineBasicBlock *Dst, 742 BranchProbability Prob = BranchProbability::getUnknown()); 743 744 public: 745 IRTranslator(CodeGenOptLevel OptLevel = CodeGenOptLevel::None); 746 getPassName()747 StringRef getPassName() const override { return "IRTranslator"; } 748 749 void getAnalysisUsage(AnalysisUsage &AU) const override; 750 751 // Algo: 752 // CallLowering = MF.subtarget.getCallLowering() 753 // F = MF.getParent() 754 // MIRBuilder.reset(MF) 755 // getMBB(F.getEntryBB()) 756 // CallLowering->translateArguments(MIRBuilder, F, ValToVReg) 757 // for each bb in F 758 // getMBB(bb) 759 // for each inst in bb 760 // if (!translate(MIRBuilder, inst, ValToVReg, ConstantToSequence)) 761 // report_fatal_error("Don't know how to translate input"); 762 // finalize() 763 bool runOnMachineFunction(MachineFunction &MF) override; 764 }; 765 766 } // end namespace llvm 767 768 #endif // LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H 769