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