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,
321 bool translateCast(
unsigned Opcode,
const User &U,
332 return translateCompare(U, MIRBuilder);
336 bool translateFCmp(
const User &U, MachineIRBuilder &MIRBuilder) {
337 return translateCompare(U, MIRBuilder);
342 void finishPendingPhis();
346 bool translateUnaryOp(
unsigned Opcode,
const User &U,
347 MachineIRBuilder &MIRBuilder);
351 bool translateBinaryOp(
unsigned Opcode,
const User &U,
352 MachineIRBuilder &MIRBuilder);
357 bool shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases);
361 void emitBranchForMergedCondition(
const Value *
Cond, MachineBasicBlock *
TBB,
362 MachineBasicBlock *FBB,
363 MachineBasicBlock *CurBB,
364 MachineBasicBlock *SwitchBB,
365 BranchProbability TProb,
366 BranchProbability FProb,
bool InvertCond);
369 void findMergedConditions(
const Value *
Cond, MachineBasicBlock *
TBB,
370 MachineBasicBlock *FBB, MachineBasicBlock *CurBB,
371 MachineBasicBlock *SwitchBB,
373 BranchProbability FProb,
bool InvertCond);
377 bool translateBr(
const User &U, MachineIRBuilder &MIRBuilder);
380 bool emitJumpTableHeader(SwitchCG::JumpTable &JT,
381 SwitchCG::JumpTableHeader &JTH,
382 MachineBasicBlock *HeaderBB);
383 void emitJumpTable(SwitchCG::JumpTable &JT, MachineBasicBlock *
MBB);
385 void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB,
386 MachineIRBuilder &MIB);
390 void emitBitTestHeader(SwitchCG::BitTestBlock &BTB,
391 MachineBasicBlock *SwitchMBB);
393 void emitBitTestCase(SwitchCG::BitTestBlock &BB, MachineBasicBlock *NextMBB,
395 SwitchCG::BitTestCase &
B, MachineBasicBlock *SwitchBB);
398 const SwitchCG::SwitchWorkListItem &W,
Value *
Cond,
399 MachineBasicBlock *SwitchMBB, MachineIRBuilder &MIB);
401 bool lowerJumpTableWorkItem(
402 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
403 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
406 MachineBasicBlock *Fallthrough,
bool FallthroughUnreachable);
409 MachineBasicBlock *Fallthrough,
410 bool FallthroughUnreachable,
411 BranchProbability UnhandledProbs,
412 MachineBasicBlock *CurMBB,
413 MachineIRBuilder &MIB,
414 MachineBasicBlock *SwitchMBB);
416 bool lowerBitTestWorkItem(
417 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
418 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
420 BranchProbability DefaultProb, BranchProbability UnhandledProbs,
422 bool FallthroughUnreachable);
424 bool lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W,
Value *
Cond,
425 MachineBasicBlock *SwitchMBB,
426 MachineBasicBlock *DefaultMBB,
427 MachineIRBuilder &MIB);
429 bool translateSwitch(
const User &U, MachineIRBuilder &MIRBuilder);
432 bool translateIndirectBr(
const User &U, MachineIRBuilder &MIRBuilder);
434 bool translateExtractValue(
const User &U, MachineIRBuilder &MIRBuilder);
436 bool translateInsertValue(
const User &U, MachineIRBuilder &MIRBuilder);
438 bool translateSelect(
const User &U, MachineIRBuilder &MIRBuilder);
440 bool translateGetElementPtr(
const User &U, MachineIRBuilder &MIRBuilder);
442 bool translateAlloca(
const User &U, MachineIRBuilder &MIRBuilder);
448 bool translateRet(
const User &U, MachineIRBuilder &MIRBuilder);
450 bool translateFNeg(
const User &U, MachineIRBuilder &MIRBuilder);
452 bool translateAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
453 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
455 bool translateSub(
const User &U, MachineIRBuilder &MIRBuilder) {
456 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
458 bool translateAnd(
const User &U, MachineIRBuilder &MIRBuilder) {
459 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
461 bool translateMul(
const User &U, MachineIRBuilder &MIRBuilder) {
462 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
464 bool translateOr(
const User &U, MachineIRBuilder &MIRBuilder) {
465 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
467 bool translateXor(
const User &U, MachineIRBuilder &MIRBuilder) {
468 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
471 bool translateUDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
472 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
474 bool translateSDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
475 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
477 bool translateURem(
const User &U, MachineIRBuilder &MIRBuilder) {
478 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
480 bool translateSRem(
const User &U, MachineIRBuilder &MIRBuilder) {
481 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
483 bool translateIntToPtr(
const User &U, MachineIRBuilder &MIRBuilder) {
484 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
486 bool translatePtrToInt(
const User &U, MachineIRBuilder &MIRBuilder) {
487 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
489 bool translatePtrToAddr(
const User &U, MachineIRBuilder &MIRBuilder) {
491 return translatePtrToInt(U, MIRBuilder);
493 bool translateTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
494 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
496 bool translateFPTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
497 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
499 bool translateFPExt(
const User &U, MachineIRBuilder &MIRBuilder) {
500 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
502 bool translateFPToUI(
const User &U, MachineIRBuilder &MIRBuilder) {
503 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
505 bool translateFPToSI(
const User &U, MachineIRBuilder &MIRBuilder) {
506 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
508 bool translateUIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
509 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
511 bool translateSIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
512 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
514 bool translateUnreachable(
const User &U, MachineIRBuilder &MIRBuilder);
516 bool translateSExt(
const User &U, MachineIRBuilder &MIRBuilder) {
517 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
520 bool translateZExt(
const User &U, MachineIRBuilder &MIRBuilder) {
521 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
524 bool translateShl(
const User &U, MachineIRBuilder &MIRBuilder) {
525 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
527 bool translateLShr(
const User &U, MachineIRBuilder &MIRBuilder) {
528 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
530 bool translateAShr(
const User &U, MachineIRBuilder &MIRBuilder) {
531 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
534 bool translateFAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
535 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
537 bool translateFSub(
const User &U, MachineIRBuilder &MIRBuilder) {
538 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
540 bool translateFMul(
const User &U, MachineIRBuilder &MIRBuilder) {
541 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
543 bool translateFDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
544 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
546 bool translateFRem(
const User &U, MachineIRBuilder &MIRBuilder) {
547 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
550 bool translateVAArg(
const User &U, MachineIRBuilder &MIRBuilder);
552 bool translateInsertElement(
const User &U, MachineIRBuilder &MIRBuilder);
553 bool translateInsertVector(
const User &U, MachineIRBuilder &MIRBuilder);
555 bool translateExtractElement(
const User &U, MachineIRBuilder &MIRBuilder);
556 bool translateExtractVector(
const User &U, MachineIRBuilder &MIRBuilder);
558 bool translateShuffleVector(
const User &U, MachineIRBuilder &MIRBuilder);
560 bool translateAtomicCmpXchg(
const User &U, MachineIRBuilder &MIRBuilder);
561 bool translateAtomicRMW(
const User &U, MachineIRBuilder &MIRBuilder);
562 bool translateFence(
const User &U, MachineIRBuilder &MIRBuilder);
563 bool translateFreeze(
const User &U, MachineIRBuilder &MIRBuilder);
567 bool translateResume(
const User &U, MachineIRBuilder &MIRBuilder) {
570 bool translateCleanupRet(
const User &U, MachineIRBuilder &MIRBuilder) {
573 bool translateCatchRet(
const User &U, MachineIRBuilder &MIRBuilder) {
576 bool translateCatchSwitch(
const User &U, MachineIRBuilder &MIRBuilder) {
579 bool translateAddrSpaceCast(
const User &U, MachineIRBuilder &MIRBuilder) {
580 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
582 bool translateCleanupPad(
const User &U, MachineIRBuilder &MIRBuilder) {
585 bool translateCatchPad(
const User &U, MachineIRBuilder &MIRBuilder) {
588 bool translateUserOp1(
const User &U, MachineIRBuilder &MIRBuilder) {
591 bool translateUserOp2(
const User &U, MachineIRBuilder &MIRBuilder) {
595 bool translateConvergenceControlIntrinsic(
const CallInst &CI,
597 MachineIRBuilder &MIRBuilder);
606 std::unique_ptr<MachineIRBuilder> CurBuilder;
611 std::unique_ptr<MachineIRBuilder> EntryBuilder;
614 MachineFunction *MF =
nullptr;
617 MachineRegisterInfo *MRI =
nullptr;
619 const DataLayout *DL =
nullptr;
622 const TargetPassConfig *TPC =
nullptr;
627 std::unique_ptr<OptimizationRemarkEmitter> ORE;
629 AAResults *AA =
nullptr;
630 AssumptionCache *AC =
nullptr;
631 const TargetLibraryInfo *LibInfo =
nullptr;
632 const TargetLowering *TLI =
nullptr;
633 FunctionLoweringInfo FuncInfo;
637 bool EnableOpts =
false;
641 bool HasTailCall =
false;
643 StackProtectorDescriptor SPDescriptor;
646 class GISelSwitchLowering :
public SwitchCG::SwitchLowering {
648 GISelSwitchLowering(
IRTranslator *irt, FunctionLoweringInfo &funcinfo)
650 assert(irt &&
"irt is null!");
653 void addSuccessorWithProb(
654 MachineBasicBlock *Src, MachineBasicBlock *Dst,
656 IRT->addSuccessorWithProb(Src, Dst, Prob);
659 virtual ~GISelSwitchLowering() =
default;
665 std::unique_ptr<GISelSwitchLowering> SL;
671 void finalizeFunction();
676 bool finalizeBasicBlock(
const BasicBlock &BB, MachineBasicBlock &
MBB);
686 bool emitSPDescriptorParent(StackProtectorDescriptor &SPD,
687 MachineBasicBlock *ParentBB);
699 bool emitSPDescriptorFailure(StackProtectorDescriptor &SPD,
700 MachineBasicBlock *FailureBB);
709 auto Regs = getOrCreateVRegs(Val);
712 assert(Regs.size() == 1 &&
713 "attempt to get single VReg for aggregate or void");
717 Register getOrCreateConvergenceTokenVReg(
const Value &Token) {
718 assert(Token.getType()->isTokenTy());
719 auto &Regs = *VMap.getVRegs(Token);
721 assert(Regs.size() == 1 &&
722 "Expected a single register for convergence tokens.");
728 auto &
Offsets = *VMap.getOffsets(Token);
736 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
740 int getOrCreateFrameIndex(
const AllocaInst &AI);
745 Align getMemOpAlign(
const Instruction &
I);
750 MachineBasicBlock &getMBB(
const BasicBlock &BB);
756 void addMachineCFGPred(CFGEdge
Edge, MachineBasicBlock *NewPred);
763 auto RemappedEdge = MachinePreds.find(
Edge);
764 if (RemappedEdge != MachinePreds.end())
765 return RemappedEdge->second;
766 return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*
Edge.first));
771 BranchProbability getEdgeProbability(
const MachineBasicBlock *Src,
772 const MachineBasicBlock *Dst)
const;
774 void addSuccessorWithProb(
775 MachineBasicBlock *Src, MachineBasicBlock *Dst,