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(
327 bool translateCast(
unsigned Opcode,
const User &U,
338 return translateCompare(U, MIRBuilder);
342 bool translateFCmp(
const User &U, MachineIRBuilder &MIRBuilder) {
343 return translateCompare(U, MIRBuilder);
348 void finishPendingPhis();
352 bool translateUnaryOp(
unsigned Opcode,
const User &U,
353 MachineIRBuilder &MIRBuilder);
357 bool translateBinaryOp(
unsigned Opcode,
const User &U,
358 MachineIRBuilder &MIRBuilder);
363 bool shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases);
367 void emitBranchForMergedCondition(
const Value *
Cond, MachineBasicBlock *
TBB,
368 MachineBasicBlock *FBB,
369 MachineBasicBlock *CurBB,
370 MachineBasicBlock *SwitchBB,
371 BranchProbability TProb,
372 BranchProbability FProb,
bool InvertCond);
375 void findMergedConditions(
const Value *
Cond, MachineBasicBlock *
TBB,
376 MachineBasicBlock *FBB, MachineBasicBlock *CurBB,
377 MachineBasicBlock *SwitchBB,
379 BranchProbability FProb,
bool InvertCond);
383 bool translateBr(
const User &U, MachineIRBuilder &MIRBuilder);
386 bool emitJumpTableHeader(SwitchCG::JumpTable &JT,
387 SwitchCG::JumpTableHeader &JTH,
388 MachineBasicBlock *HeaderBB);
389 void emitJumpTable(SwitchCG::JumpTable &JT, MachineBasicBlock *
MBB);
391 void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB,
392 MachineIRBuilder &MIB);
396 void emitBitTestHeader(SwitchCG::BitTestBlock &BTB,
397 MachineBasicBlock *SwitchMBB);
399 void emitBitTestCase(SwitchCG::BitTestBlock &BB, MachineBasicBlock *NextMBB,
401 SwitchCG::BitTestCase &
B, MachineBasicBlock *SwitchBB);
404 const SwitchCG::SwitchWorkListItem &W,
Value *
Cond,
405 MachineBasicBlock *SwitchMBB, MachineIRBuilder &MIB);
407 bool lowerJumpTableWorkItem(
408 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
409 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
412 MachineBasicBlock *Fallthrough,
bool FallthroughUnreachable);
415 MachineBasicBlock *Fallthrough,
416 bool FallthroughUnreachable,
417 BranchProbability UnhandledProbs,
418 MachineBasicBlock *CurMBB,
419 MachineIRBuilder &MIB,
420 MachineBasicBlock *SwitchMBB);
422 bool lowerBitTestWorkItem(
423 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
424 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
426 BranchProbability DefaultProb, BranchProbability UnhandledProbs,
428 bool FallthroughUnreachable);
430 bool lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W,
Value *
Cond,
431 MachineBasicBlock *SwitchMBB,
432 MachineBasicBlock *DefaultMBB,
433 MachineIRBuilder &MIB);
435 bool translateSwitch(
const User &U, MachineIRBuilder &MIRBuilder);
438 bool translateIndirectBr(
const User &U, MachineIRBuilder &MIRBuilder);
440 bool translateExtractValue(
const User &U, MachineIRBuilder &MIRBuilder);
442 bool translateInsertValue(
const User &U, MachineIRBuilder &MIRBuilder);
444 bool translateSelect(
const User &U, MachineIRBuilder &MIRBuilder);
446 bool translateGetElementPtr(
const User &U, MachineIRBuilder &MIRBuilder);
448 bool translateAlloca(
const User &U, MachineIRBuilder &MIRBuilder);
454 bool translateRet(
const User &U, MachineIRBuilder &MIRBuilder);
456 bool translateFNeg(
const User &U, MachineIRBuilder &MIRBuilder);
458 bool translateAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
459 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
461 bool translateSub(
const User &U, MachineIRBuilder &MIRBuilder) {
462 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
464 bool translateAnd(
const User &U, MachineIRBuilder &MIRBuilder) {
465 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
467 bool translateMul(
const User &U, MachineIRBuilder &MIRBuilder) {
468 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
470 bool translateOr(
const User &U, MachineIRBuilder &MIRBuilder) {
471 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
473 bool translateXor(
const User &U, MachineIRBuilder &MIRBuilder) {
474 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
477 bool translateUDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
478 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
480 bool translateSDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
481 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
483 bool translateURem(
const User &U, MachineIRBuilder &MIRBuilder) {
484 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
486 bool translateSRem(
const User &U, MachineIRBuilder &MIRBuilder) {
487 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
489 bool translateIntToPtr(
const User &U, MachineIRBuilder &MIRBuilder) {
490 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
492 bool translatePtrToInt(
const User &U, MachineIRBuilder &MIRBuilder) {
493 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
495 bool translatePtrToAddr(
const User &U, MachineIRBuilder &MIRBuilder) {
497 return translatePtrToInt(U, MIRBuilder);
499 bool translateTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
500 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
502 bool translateFPTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
503 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
505 bool translateFPExt(
const User &U, MachineIRBuilder &MIRBuilder) {
506 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
508 bool translateFPToUI(
const User &U, MachineIRBuilder &MIRBuilder) {
509 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
511 bool translateFPToSI(
const User &U, MachineIRBuilder &MIRBuilder) {
512 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
514 bool translateUIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
515 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
517 bool translateSIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
518 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
520 bool translateUnreachable(
const User &U, MachineIRBuilder &MIRBuilder);
522 bool translateSExt(
const User &U, MachineIRBuilder &MIRBuilder) {
523 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
526 bool translateZExt(
const User &U, MachineIRBuilder &MIRBuilder) {
527 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
530 bool translateShl(
const User &U, MachineIRBuilder &MIRBuilder) {
531 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
533 bool translateLShr(
const User &U, MachineIRBuilder &MIRBuilder) {
534 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
536 bool translateAShr(
const User &U, MachineIRBuilder &MIRBuilder) {
537 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
540 bool translateFAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
541 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
543 bool translateFSub(
const User &U, MachineIRBuilder &MIRBuilder) {
544 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
546 bool translateFMul(
const User &U, MachineIRBuilder &MIRBuilder) {
547 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
549 bool translateFDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
550 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
552 bool translateFRem(
const User &U, MachineIRBuilder &MIRBuilder) {
553 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
556 bool translateVAArg(
const User &U, MachineIRBuilder &MIRBuilder);
558 bool translateInsertElement(
const User &U, MachineIRBuilder &MIRBuilder);
559 bool translateInsertVector(
const User &U, MachineIRBuilder &MIRBuilder);
561 bool translateExtractElement(
const User &U, MachineIRBuilder &MIRBuilder);
562 bool translateExtractVector(
const User &U, MachineIRBuilder &MIRBuilder);
564 bool translateShuffleVector(
const User &U, MachineIRBuilder &MIRBuilder);
566 bool translateAtomicCmpXchg(
const User &U, MachineIRBuilder &MIRBuilder);
567 bool translateAtomicRMW(
const User &U, MachineIRBuilder &MIRBuilder);
568 bool translateFence(
const User &U, MachineIRBuilder &MIRBuilder);
569 bool translateFreeze(
const User &U, MachineIRBuilder &MIRBuilder);
573 bool translateResume(
const User &U, MachineIRBuilder &MIRBuilder) {
576 bool translateCleanupRet(
const User &U, MachineIRBuilder &MIRBuilder) {
579 bool translateCatchRet(
const User &U, MachineIRBuilder &MIRBuilder) {
582 bool translateCatchSwitch(
const User &U, MachineIRBuilder &MIRBuilder) {
585 bool translateAddrSpaceCast(
const User &U, MachineIRBuilder &MIRBuilder) {
586 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
588 bool translateCleanupPad(
const User &U, MachineIRBuilder &MIRBuilder) {
591 bool translateCatchPad(
const User &U, MachineIRBuilder &MIRBuilder) {
594 bool translateUserOp1(
const User &U, MachineIRBuilder &MIRBuilder) {
597 bool translateUserOp2(
const User &U, MachineIRBuilder &MIRBuilder) {
601 bool translateConvergenceControlIntrinsic(
const CallInst &CI,
603 MachineIRBuilder &MIRBuilder);
612 std::unique_ptr<MachineIRBuilder> CurBuilder;
617 std::unique_ptr<MachineIRBuilder> EntryBuilder;
620 MachineFunction *MF =
nullptr;
623 MachineRegisterInfo *MRI =
nullptr;
625 const DataLayout *DL =
nullptr;
628 const TargetPassConfig *TPC =
nullptr;
633 std::unique_ptr<OptimizationRemarkEmitter> ORE;
635 AAResults *AA =
nullptr;
636 AssumptionCache *AC =
nullptr;
637 const TargetLibraryInfo *LibInfo =
nullptr;
638 const TargetLowering *TLI =
nullptr;
639 FunctionLoweringInfo FuncInfo;
643 bool EnableOpts =
false;
647 bool HasTailCall =
false;
649 StackProtectorDescriptor SPDescriptor;
652 class GISelSwitchLowering :
public SwitchCG::SwitchLowering {
654 GISelSwitchLowering(
IRTranslator *irt, FunctionLoweringInfo &funcinfo)
656 assert(irt &&
"irt is null!");
659 void addSuccessorWithProb(
660 MachineBasicBlock *Src, MachineBasicBlock *Dst,
662 IRT->addSuccessorWithProb(Src, Dst, Prob);
665 ~GISelSwitchLowering()
override =
default;
671 std::unique_ptr<GISelSwitchLowering> SL;
677 void finalizeFunction();
682 bool finalizeBasicBlock(
const BasicBlock &BB, MachineBasicBlock &
MBB);
692 bool emitSPDescriptorParent(StackProtectorDescriptor &SPD,
693 MachineBasicBlock *ParentBB);
705 bool emitSPDescriptorFailure(StackProtectorDescriptor &SPD,
706 MachineBasicBlock *FailureBB);
715 auto Regs = getOrCreateVRegs(Val);
718 assert(Regs.size() == 1 &&
719 "attempt to get single VReg for aggregate or void");
723 Register getOrCreateConvergenceTokenVReg(
const Value &Token) {
724 assert(Token.getType()->isTokenTy());
725 auto &Regs = *VMap.getVRegs(Token);
727 assert(Regs.size() == 1 &&
728 "Expected a single register for convergence tokens.");
734 auto &
Offsets = *VMap.getOffsets(Token);
742 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
746 int getOrCreateFrameIndex(
const AllocaInst &AI);
751 Align getMemOpAlign(
const Instruction &
I);
756 MachineBasicBlock &getMBB(
const BasicBlock &BB);
762 void addMachineCFGPred(CFGEdge
Edge, MachineBasicBlock *NewPred);
769 auto RemappedEdge = MachinePreds.find(
Edge);
770 if (RemappedEdge != MachinePreds.end())
771 return RemappedEdge->second;
772 return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*
Edge.first));
777 BranchProbability getEdgeProbability(
const MachineBasicBlock *Src,
778 const MachineBasicBlock *Dst)
const;
780 void addSuccessorWithProb(
781 MachineBasicBlock *Src, MachineBasicBlock *Dst,