75 class ValueToVRegInfo {
77 ValueToVRegInfo() =
default;
82 using const_vreg_iterator =
84 using const_offset_iterator =
87 inline const_vreg_iterator vregs_end()
const {
return ValToVRegs.end(); }
89 VRegListT *getVRegs(
const Value &V) {
90 auto It = ValToVRegs.find(&V);
91 if (It != ValToVRegs.end())
94 return insertVRegs(V);
97 OffsetListT *getOffsets(
const Value &V) {
98 auto It = TypeToOffsets.find(V.getType());
99 if (It != TypeToOffsets.end())
102 return insertOffsets(V);
105 const_vreg_iterator findVRegs(
const Value &V)
const {
106 return ValToVRegs.find(&V);
109 bool contains(
const Value &V)
const {
return ValToVRegs.contains(&V); }
113 TypeToOffsets.clear();
114 VRegAlloc.DestroyAll();
115 OffsetAlloc.DestroyAll();
119 VRegListT *insertVRegs(
const Value &V) {
120 assert(!ValToVRegs.contains(&V) &&
"Value already exists");
124 auto *VRegList =
new (VRegAlloc.Allocate()) VRegListT();
125 ValToVRegs[&V] = VRegList;
129 OffsetListT *insertOffsets(
const Value &V) {
130 assert(!TypeToOffsets.contains(V.getType()) &&
"Type already exists");
132 auto *OffsetList =
new (OffsetAlloc.Allocate()) OffsetListT();
133 TypeToOffsets[V.getType()] = OffsetList;
147 ValueToVRegInfo VMap;
154 using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>;
210 void translateDbgValueRecord(
Value *V,
bool HasArgList,
218 void translateDbgDeclareRecord(
Value *
Address,
bool HasArgList,
224 bool translateCopy(
const User &U,
const Value &V,
248 bool translateVectorInterleave2Intrinsic(
const CallInst &CI,
250 bool translateVectorDeinterleave2Intrinsic(
const CallInst &CI,
255 bool translateOverflowIntrinsic(
const CallInst &CI,
unsigned Op,
257 bool translateFixedPointIntrinsic(
unsigned Op,
const CallInst &CI,
279 std::optional<MCRegister> getArgPhysReg(
Argument &Arg);
285 bool translateIfEntryValueArgument(
bool isDeclare,
Value *Arg,
300 bool translateIntrinsic(
313 const BasicBlock *EHPadBB, BranchProbability Prob,
314 SmallVectorImpl<std::pair<MachineBasicBlock *, BranchProbability>>
317 bool translateInvoke(
const User &U, MachineIRBuilder &MIRBuilder);
319 bool translateCallBr(
const User &U, MachineIRBuilder &MIRBuilder);
321 bool translateLandingPad(
const User &U, MachineIRBuilder &MIRBuilder);
325 bool translateCast(
unsigned Opcode,
const User &U,
326 MachineIRBuilder &MIRBuilder);
329 bool translatePHI(
const User &U, MachineIRBuilder &MIRBuilder);
332 bool translateCompare(
const User &U, MachineIRBuilder &MIRBuilder);
335 bool translateICmp(
const User &U, MachineIRBuilder &MIRBuilder) {
336 return translateCompare(U, MIRBuilder);
340 bool translateFCmp(
const User &U, MachineIRBuilder &MIRBuilder) {
341 return translateCompare(U, MIRBuilder);
346 void finishPendingPhis();
350 bool translateUnaryOp(
unsigned Opcode,
const User &U,
351 MachineIRBuilder &MIRBuilder);
355 bool translateBinaryOp(
unsigned Opcode,
const User &U,
356 MachineIRBuilder &MIRBuilder);
361 bool shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases);
365 void emitBranchForMergedCondition(
const Value *
Cond, MachineBasicBlock *
TBB,
366 MachineBasicBlock *FBB,
367 MachineBasicBlock *CurBB,
368 MachineBasicBlock *SwitchBB,
369 BranchProbability TProb,
370 BranchProbability FProb,
bool InvertCond);
373 void findMergedConditions(
const Value *
Cond, MachineBasicBlock *
TBB,
374 MachineBasicBlock *FBB, MachineBasicBlock *CurBB,
375 MachineBasicBlock *SwitchBB,
376 Instruction::BinaryOps
Opc, BranchProbability TProb,
377 BranchProbability FProb,
bool InvertCond);
381 bool translateUncondBr(
const User &U, MachineIRBuilder &MIRBuilder);
382 bool translateCondBr(
const User &U, MachineIRBuilder &MIRBuilder);
385 bool emitJumpTableHeader(SwitchCG::JumpTable &JT,
386 SwitchCG::JumpTableHeader &JTH,
387 MachineBasicBlock *HeaderBB);
388 void emitJumpTable(SwitchCG::JumpTable &JT, MachineBasicBlock *
MBB);
390 void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB,
391 MachineIRBuilder &MIB);
395 void emitBitTestHeader(SwitchCG::BitTestBlock &BTB,
396 MachineBasicBlock *SwitchMBB);
398 void emitBitTestCase(SwitchCG::BitTestBlock &BB, MachineBasicBlock *NextMBB,
400 SwitchCG::BitTestCase &
B, MachineBasicBlock *SwitchBB);
402 void splitWorkItem(SwitchCG::SwitchWorkList &WorkList,
403 const SwitchCG::SwitchWorkListItem &W,
Value *
Cond,
404 MachineBasicBlock *SwitchMBB, MachineIRBuilder &MIB);
406 bool lowerJumpTableWorkItem(
407 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
408 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
409 MachineIRBuilder &MIB, MachineFunction::iterator BBI,
410 BranchProbability UnhandledProbs, SwitchCG::CaseClusterIt
I,
411 MachineBasicBlock *Fallthrough,
bool FallthroughUnreachable);
413 bool lowerSwitchRangeWorkItem(SwitchCG::CaseClusterIt
I,
Value *
Cond,
414 MachineBasicBlock *Fallthrough,
415 bool FallthroughUnreachable,
416 BranchProbability UnhandledProbs,
417 MachineBasicBlock *CurMBB,
418 MachineIRBuilder &MIB,
419 MachineBasicBlock *SwitchMBB);
421 bool lowerBitTestWorkItem(
422 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
423 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
424 MachineIRBuilder &MIB, MachineFunction::iterator BBI,
425 BranchProbability DefaultProb, BranchProbability UnhandledProbs,
426 SwitchCG::CaseClusterIt
I, MachineBasicBlock *Fallthrough,
427 bool FallthroughUnreachable);
429 bool lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W,
Value *
Cond,
430 MachineBasicBlock *SwitchMBB,
431 MachineBasicBlock *DefaultMBB,
432 MachineIRBuilder &MIB);
434 bool translateSwitch(
const User &U, MachineIRBuilder &MIRBuilder);
437 bool translateIndirectBr(
const User &U, MachineIRBuilder &MIRBuilder);
439 bool translateExtractValue(
const User &U, MachineIRBuilder &MIRBuilder);
441 bool translateInsertValue(
const User &U, MachineIRBuilder &MIRBuilder);
443 bool translateSelect(
const User &U, MachineIRBuilder &MIRBuilder);
445 bool translateGetElementPtr(
const User &U, MachineIRBuilder &MIRBuilder);
447 bool translateAlloca(
const User &U, MachineIRBuilder &MIRBuilder);
453 bool translateRet(
const User &U, MachineIRBuilder &MIRBuilder);
455 bool translateFNeg(
const User &U, MachineIRBuilder &MIRBuilder);
457 bool translateAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
458 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
460 bool translateSub(
const User &U, MachineIRBuilder &MIRBuilder) {
461 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
463 bool translateAnd(
const User &U, MachineIRBuilder &MIRBuilder) {
464 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
466 bool translateMul(
const User &U, MachineIRBuilder &MIRBuilder) {
467 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
469 bool translateOr(
const User &U, MachineIRBuilder &MIRBuilder) {
470 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
472 bool translateXor(
const User &U, MachineIRBuilder &MIRBuilder) {
473 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
476 bool translateUDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
477 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
479 bool translateSDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
480 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
482 bool translateURem(
const User &U, MachineIRBuilder &MIRBuilder) {
483 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
485 bool translateSRem(
const User &U, MachineIRBuilder &MIRBuilder) {
486 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
488 bool translateIntToPtr(
const User &U, MachineIRBuilder &MIRBuilder) {
489 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
491 bool translatePtrToInt(
const User &U, MachineIRBuilder &MIRBuilder) {
492 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
494 bool translatePtrToAddr(
const User &U, MachineIRBuilder &MIRBuilder) {
496 return translatePtrToInt(U, MIRBuilder);
498 bool translateTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
499 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
501 bool translateFPTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
502 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
504 bool translateFPExt(
const User &U, MachineIRBuilder &MIRBuilder) {
505 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
507 bool translateFPToUI(
const User &U, MachineIRBuilder &MIRBuilder) {
508 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
510 bool translateFPToSI(
const User &U, MachineIRBuilder &MIRBuilder) {
511 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
513 bool translateUIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
514 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
516 bool translateSIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
517 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
519 bool translateUnreachable(
const User &U, MachineIRBuilder &MIRBuilder);
521 bool translateSExt(
const User &U, MachineIRBuilder &MIRBuilder) {
522 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
525 bool translateZExt(
const User &U, MachineIRBuilder &MIRBuilder) {
526 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
529 bool translateShl(
const User &U, MachineIRBuilder &MIRBuilder) {
530 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
532 bool translateLShr(
const User &U, MachineIRBuilder &MIRBuilder) {
533 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
535 bool translateAShr(
const User &U, MachineIRBuilder &MIRBuilder) {
536 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
539 bool translateFAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
540 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
542 bool translateFSub(
const User &U, MachineIRBuilder &MIRBuilder) {
543 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
545 bool translateFMul(
const User &U, MachineIRBuilder &MIRBuilder) {
546 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
548 bool translateFDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
549 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
551 bool translateFRem(
const User &U, MachineIRBuilder &MIRBuilder) {
552 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
555 bool translateVAArg(
const User &U, MachineIRBuilder &MIRBuilder);
557 bool translateInsertElement(
const User &U, MachineIRBuilder &MIRBuilder);
558 bool translateInsertVector(
const User &U, MachineIRBuilder &MIRBuilder);
560 bool translateExtractElement(
const User &U, MachineIRBuilder &MIRBuilder);
561 bool translateExtractVector(
const User &U, MachineIRBuilder &MIRBuilder);
563 bool translateShuffleVector(
const User &U, MachineIRBuilder &MIRBuilder);
565 bool translateAtomicCmpXchg(
const User &U, MachineIRBuilder &MIRBuilder);
566 bool translateAtomicRMW(
const User &U, MachineIRBuilder &MIRBuilder);
567 bool translateFence(
const User &U, MachineIRBuilder &MIRBuilder);
568 bool translateFreeze(
const User &U, MachineIRBuilder &MIRBuilder);
572 bool translateResume(
const User &U, MachineIRBuilder &MIRBuilder) {
575 bool translateCleanupRet(
const User &U, MachineIRBuilder &MIRBuilder) {
578 bool translateCatchRet(
const User &U, MachineIRBuilder &MIRBuilder) {
581 bool translateCatchSwitch(
const User &U, MachineIRBuilder &MIRBuilder) {
584 bool translateAddrSpaceCast(
const User &U, MachineIRBuilder &MIRBuilder) {
585 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
587 bool translateCleanupPad(
const User &U, MachineIRBuilder &MIRBuilder) {
590 bool translateCatchPad(
const User &U, MachineIRBuilder &MIRBuilder) {
593 bool translateUserOp1(
const User &U, MachineIRBuilder &MIRBuilder) {
596 bool translateUserOp2(
const User &U, MachineIRBuilder &MIRBuilder) {
600 bool translateConvergenceControlIntrinsic(
const CallInst &CI,
602 MachineIRBuilder &MIRBuilder);
611 std::unique_ptr<MachineIRBuilder> CurBuilder;
616 std::unique_ptr<MachineIRBuilder> EntryBuilder;
622 MachineRegisterInfo *MRI =
nullptr;
624 const DataLayout *
DL =
nullptr;
627 const TargetPassConfig *TPC =
nullptr;
632 std::unique_ptr<OptimizationRemarkEmitter> ORE;
634 AAResults *AA =
nullptr;
635 AssumptionCache *AC =
nullptr;
636 const TargetLibraryInfo *LibInfo =
nullptr;
637 const LibcallLoweringInfo *Libcalls =
nullptr;
638 const TargetLowering *TLI =
nullptr;
639 FunctionLoweringInfo FuncInfo;
643 bool EnableOpts =
false;
647 bool HasTailCall =
false;
649 StackProtectorDescriptor SPDescriptor;
651 bool mayTranslateUserTypes(
const User &U)
const;
654 class GISelSwitchLowering :
public SwitchCG::SwitchLowering {
656 GISelSwitchLowering(IRTranslator *irt, FunctionLoweringInfo &funcinfo)
657 : SwitchLowering(funcinfo), IRT(irt) {
658 assert(irt &&
"irt is null!");
661 void addSuccessorWithProb(
662 MachineBasicBlock *Src, MachineBasicBlock *Dst,
663 BranchProbability Prob = BranchProbability::getUnknown())
override {
664 IRT->addSuccessorWithProb(Src, Dst, Prob);
667 ~GISelSwitchLowering()
override =
default;
673 std::unique_ptr<GISelSwitchLowering> SL;
679 void finalizeFunction();
684 bool finalizeBasicBlock(
const BasicBlock &BB, MachineBasicBlock &
MBB);
694 bool emitSPDescriptorParent(StackProtectorDescriptor &SPD,
695 MachineBasicBlock *ParentBB);
707 bool emitSPDescriptorFailure(StackProtectorDescriptor &SPD,
708 MachineBasicBlock *FailureBB);
714 ArrayRef<Register> getOrCreateVRegs(
const Value &Val);
717 auto Regs = getOrCreateVRegs(Val);
720 assert(Regs.size() == 1 &&
721 "attempt to get single VReg for aggregate or void");
725 Register getOrCreateConvergenceTokenVReg(
const Value &Token) {
726 assert(Token.getType()->isTokenTy());
727 auto &Regs = *VMap.getVRegs(Token);
729 assert(Regs.size() == 1 &&
730 "Expected a single register for convergence tokens.");
734 auto Reg = MRI->createGenericVirtualRegister(LLT::token());
736 auto &
Offsets = *VMap.getOffsets(Token);
744 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
748 int getOrCreateFrameIndex(
const AllocaInst &AI);
753 Align getMemOpAlign(
const Instruction &
I);
758 MachineBasicBlock &getMBB(
const BasicBlock &BB);
764 void addMachineCFGPred(CFGEdge
Edge, MachineBasicBlock *NewPred);
770 SmallVector<MachineBasicBlock *, 1> getMachinePredBBs(CFGEdge
Edge) {
771 auto RemappedEdge = MachinePreds.
find(
Edge);
772 if (RemappedEdge != MachinePreds.
end())
773 return RemappedEdge->second;
774 return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*
Edge.first));
779 BranchProbability getEdgeProbability(
const MachineBasicBlock *Src,
780 const MachineBasicBlock *Dst)
const;
782 void addSuccessorWithProb(
783 MachineBasicBlock *Src, MachineBasicBlock *Dst,
784 BranchProbability Prob = BranchProbability::getUnknown());
787 IRTranslator(CodeGenOptLevel OptLevel = CodeGenOptLevel::None);