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