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(
325 bool translateCast(
unsigned Opcode,
const User &U,
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,
377 BranchProbability FProb,
bool InvertCond);
381 bool translateBr(
const User &U, MachineIRBuilder &MIRBuilder);
384 bool emitJumpTableHeader(SwitchCG::JumpTable &JT,
385 SwitchCG::JumpTableHeader &JTH,
386 MachineBasicBlock *HeaderBB);
387 void emitJumpTable(SwitchCG::JumpTable &JT, MachineBasicBlock *
MBB);
389 void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB,
390 MachineIRBuilder &MIB);
394 void emitBitTestHeader(SwitchCG::BitTestBlock &BTB,
395 MachineBasicBlock *SwitchMBB);
397 void emitBitTestCase(SwitchCG::BitTestBlock &BB, MachineBasicBlock *NextMBB,
399 SwitchCG::BitTestCase &
B, MachineBasicBlock *SwitchBB);
402 const SwitchCG::SwitchWorkListItem &W,
Value *
Cond,
403 MachineBasicBlock *SwitchMBB, MachineIRBuilder &MIB);
405 bool lowerJumpTableWorkItem(
406 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
407 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
410 MachineBasicBlock *Fallthrough,
bool FallthroughUnreachable);
413 MachineBasicBlock *Fallthrough,
414 bool FallthroughUnreachable,
415 BranchProbability UnhandledProbs,
416 MachineBasicBlock *CurMBB,
417 MachineIRBuilder &MIB,
418 MachineBasicBlock *SwitchMBB);
420 bool lowerBitTestWorkItem(
421 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
422 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
424 BranchProbability DefaultProb, BranchProbability UnhandledProbs,
426 bool FallthroughUnreachable);
428 bool lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W,
Value *
Cond,
429 MachineBasicBlock *SwitchMBB,
430 MachineBasicBlock *DefaultMBB,
431 MachineIRBuilder &MIB);
433 bool translateSwitch(
const User &U, MachineIRBuilder &MIRBuilder);
436 bool translateIndirectBr(
const User &U, MachineIRBuilder &MIRBuilder);
438 bool translateExtractValue(
const User &U, MachineIRBuilder &MIRBuilder);
440 bool translateInsertValue(
const User &U, MachineIRBuilder &MIRBuilder);
442 bool translateSelect(
const User &U, MachineIRBuilder &MIRBuilder);
444 bool translateGetElementPtr(
const User &U, MachineIRBuilder &MIRBuilder);
446 bool translateAlloca(
const User &U, MachineIRBuilder &MIRBuilder);
452 bool translateRet(
const User &U, MachineIRBuilder &MIRBuilder);
454 bool translateFNeg(
const User &U, MachineIRBuilder &MIRBuilder);
456 bool translateAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
457 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
459 bool translateSub(
const User &U, MachineIRBuilder &MIRBuilder) {
460 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
462 bool translateAnd(
const User &U, MachineIRBuilder &MIRBuilder) {
463 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
465 bool translateMul(
const User &U, MachineIRBuilder &MIRBuilder) {
466 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
468 bool translateOr(
const User &U, MachineIRBuilder &MIRBuilder) {
469 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
471 bool translateXor(
const User &U, MachineIRBuilder &MIRBuilder) {
472 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
475 bool translateUDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
476 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
478 bool translateSDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
479 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
481 bool translateURem(
const User &U, MachineIRBuilder &MIRBuilder) {
482 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
484 bool translateSRem(
const User &U, MachineIRBuilder &MIRBuilder) {
485 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
487 bool translateIntToPtr(
const User &U, MachineIRBuilder &MIRBuilder) {
488 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
490 bool translatePtrToInt(
const User &U, MachineIRBuilder &MIRBuilder) {
491 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
493 bool translatePtrToAddr(
const User &U, MachineIRBuilder &MIRBuilder) {
495 return translatePtrToInt(U, MIRBuilder);
497 bool translateTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
498 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
500 bool translateFPTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
501 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
503 bool translateFPExt(
const User &U, MachineIRBuilder &MIRBuilder) {
504 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
506 bool translateFPToUI(
const User &U, MachineIRBuilder &MIRBuilder) {
507 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
509 bool translateFPToSI(
const User &U, MachineIRBuilder &MIRBuilder) {
510 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
512 bool translateUIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
513 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
515 bool translateSIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
516 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
518 bool translateUnreachable(
const User &U, MachineIRBuilder &MIRBuilder);
520 bool translateSExt(
const User &U, MachineIRBuilder &MIRBuilder) {
521 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
524 bool translateZExt(
const User &U, MachineIRBuilder &MIRBuilder) {
525 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
528 bool translateShl(
const User &U, MachineIRBuilder &MIRBuilder) {
529 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
531 bool translateLShr(
const User &U, MachineIRBuilder &MIRBuilder) {
532 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
534 bool translateAShr(
const User &U, MachineIRBuilder &MIRBuilder) {
535 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
538 bool translateFAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
539 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
541 bool translateFSub(
const User &U, MachineIRBuilder &MIRBuilder) {
542 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
544 bool translateFMul(
const User &U, MachineIRBuilder &MIRBuilder) {
545 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
547 bool translateFDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
548 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
550 bool translateFRem(
const User &U, MachineIRBuilder &MIRBuilder) {
551 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
554 bool translateVAArg(
const User &U, MachineIRBuilder &MIRBuilder);
556 bool translateInsertElement(
const User &U, MachineIRBuilder &MIRBuilder);
557 bool translateInsertVector(
const User &U, MachineIRBuilder &MIRBuilder);
559 bool translateExtractElement(
const User &U, MachineIRBuilder &MIRBuilder);
560 bool translateExtractVector(
const User &U, MachineIRBuilder &MIRBuilder);
562 bool translateShuffleVector(
const User &U, MachineIRBuilder &MIRBuilder);
564 bool translateAtomicCmpXchg(
const User &U, MachineIRBuilder &MIRBuilder);
565 bool translateAtomicRMW(
const User &U, MachineIRBuilder &MIRBuilder);
566 bool translateFence(
const User &U, MachineIRBuilder &MIRBuilder);
567 bool translateFreeze(
const User &U, MachineIRBuilder &MIRBuilder);
571 bool translateResume(
const User &U, MachineIRBuilder &MIRBuilder) {
574 bool translateCleanupRet(
const User &U, MachineIRBuilder &MIRBuilder) {
577 bool translateCatchRet(
const User &U, MachineIRBuilder &MIRBuilder) {
580 bool translateCatchSwitch(
const User &U, MachineIRBuilder &MIRBuilder) {
583 bool translateAddrSpaceCast(
const User &U, MachineIRBuilder &MIRBuilder) {
584 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
586 bool translateCleanupPad(
const User &U, MachineIRBuilder &MIRBuilder) {
589 bool translateCatchPad(
const User &U, MachineIRBuilder &MIRBuilder) {
592 bool translateUserOp1(
const User &U, MachineIRBuilder &MIRBuilder) {
595 bool translateUserOp2(
const User &U, MachineIRBuilder &MIRBuilder) {
599 bool translateConvergenceControlIntrinsic(
const CallInst &CI,
601 MachineIRBuilder &MIRBuilder);
610 std::unique_ptr<MachineIRBuilder> CurBuilder;
615 std::unique_ptr<MachineIRBuilder> EntryBuilder;
618 MachineFunction *MF =
nullptr;
621 MachineRegisterInfo *MRI =
nullptr;
623 const DataLayout *DL =
nullptr;
626 const TargetPassConfig *TPC =
nullptr;
631 std::unique_ptr<OptimizationRemarkEmitter> ORE;
633 AAResults *AA =
nullptr;
634 AssumptionCache *AC =
nullptr;
635 const TargetLibraryInfo *LibInfo =
nullptr;
636 const TargetLowering *TLI =
nullptr;
637 FunctionLoweringInfo FuncInfo;
641 bool EnableOpts =
false;
645 bool HasTailCall =
false;
647 StackProtectorDescriptor SPDescriptor;
650 class GISelSwitchLowering :
public SwitchCG::SwitchLowering {
652 GISelSwitchLowering(
IRTranslator *irt, FunctionLoweringInfo &funcinfo)
654 assert(irt &&
"irt is null!");
657 void addSuccessorWithProb(
658 MachineBasicBlock *Src, MachineBasicBlock *Dst,
660 IRT->addSuccessorWithProb(Src, Dst, Prob);
663 ~GISelSwitchLowering()
override =
default;
669 std::unique_ptr<GISelSwitchLowering> SL;
675 void finalizeFunction();
680 bool finalizeBasicBlock(
const BasicBlock &BB, MachineBasicBlock &
MBB);
690 bool emitSPDescriptorParent(StackProtectorDescriptor &SPD,
691 MachineBasicBlock *ParentBB);
703 bool emitSPDescriptorFailure(StackProtectorDescriptor &SPD,
704 MachineBasicBlock *FailureBB);
713 auto Regs = getOrCreateVRegs(Val);
716 assert(Regs.size() == 1 &&
717 "attempt to get single VReg for aggregate or void");
721 Register getOrCreateConvergenceTokenVReg(
const Value &Token) {
722 assert(Token.getType()->isTokenTy());
723 auto &Regs = *VMap.getVRegs(Token);
725 assert(Regs.size() == 1 &&
726 "Expected a single register for convergence tokens.");
732 auto &
Offsets = *VMap.getOffsets(Token);
740 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
744 int getOrCreateFrameIndex(
const AllocaInst &AI);
749 Align getMemOpAlign(
const Instruction &
I);
754 MachineBasicBlock &getMBB(
const BasicBlock &BB);
760 void addMachineCFGPred(CFGEdge
Edge, MachineBasicBlock *NewPred);
767 auto RemappedEdge = MachinePreds.find(
Edge);
768 if (RemappedEdge != MachinePreds.end())
769 return RemappedEdge->second;
770 return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*
Edge.first));
775 BranchProbability getEdgeProbability(
const MachineBasicBlock *Src,
776 const MachineBasicBlock *Dst)
const;
778 void addSuccessorWithProb(
779 MachineBasicBlock *Src, MachineBasicBlock *Dst,