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);
320 bool translateCallBrIntrinsic(
const CallBrInst &
I,
321 MachineIRBuilder &MIRBuilder);
323 bool translateLandingPad(
const User &U, MachineIRBuilder &MIRBuilder);
327 bool translateCast(
unsigned Opcode,
const User &U,
328 MachineIRBuilder &MIRBuilder);
331 bool translatePHI(
const User &U, MachineIRBuilder &MIRBuilder);
334 bool translateCompare(
const User &U, MachineIRBuilder &MIRBuilder);
337 bool translateICmp(
const User &U, MachineIRBuilder &MIRBuilder) {
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 translateUncondBr(
const User &U, MachineIRBuilder &MIRBuilder);
384 bool translateCondBr(
const User &U, MachineIRBuilder &MIRBuilder);
387 bool emitJumpTableHeader(SwitchCG::JumpTable &JT,
388 SwitchCG::JumpTableHeader &JTH,
389 MachineBasicBlock *HeaderBB);
390 void emitJumpTable(SwitchCG::JumpTable &JT, MachineBasicBlock *
MBB);
392 void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB,
393 MachineIRBuilder &MIB);
397 void emitBitTestHeader(SwitchCG::BitTestBlock &BTB,
398 MachineBasicBlock *SwitchMBB);
400 void emitBitTestCase(SwitchCG::BitTestBlock &BB, MachineBasicBlock *NextMBB,
402 SwitchCG::BitTestCase &
B, MachineBasicBlock *SwitchBB);
405 const SwitchCG::SwitchWorkListItem &W,
Value *
Cond,
406 MachineBasicBlock *SwitchMBB, MachineIRBuilder &MIB);
408 bool lowerJumpTableWorkItem(
409 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
410 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
413 MachineBasicBlock *Fallthrough,
bool FallthroughUnreachable);
416 MachineBasicBlock *Fallthrough,
417 bool FallthroughUnreachable,
418 BranchProbability UnhandledProbs,
419 MachineBasicBlock *CurMBB,
420 MachineIRBuilder &MIB,
421 MachineBasicBlock *SwitchMBB);
423 bool lowerBitTestWorkItem(
424 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
425 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
427 BranchProbability DefaultProb, BranchProbability UnhandledProbs,
429 bool FallthroughUnreachable);
431 bool lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W,
Value *
Cond,
432 MachineBasicBlock *SwitchMBB,
433 MachineBasicBlock *DefaultMBB,
434 MachineIRBuilder &MIB);
436 bool translateSwitch(
const User &U, MachineIRBuilder &MIRBuilder);
439 bool translateIndirectBr(
const User &U, MachineIRBuilder &MIRBuilder);
441 bool translateExtractValue(
const User &U, MachineIRBuilder &MIRBuilder);
443 bool translateInsertValue(
const User &U, MachineIRBuilder &MIRBuilder);
445 bool translateSelect(
const User &U, MachineIRBuilder &MIRBuilder);
447 bool translateGetElementPtr(
const User &U, MachineIRBuilder &MIRBuilder);
449 bool translateAlloca(
const User &U, MachineIRBuilder &MIRBuilder);
455 bool translateRet(
const User &U, MachineIRBuilder &MIRBuilder);
457 bool translateFNeg(
const User &U, MachineIRBuilder &MIRBuilder);
459 bool translateAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
460 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
462 bool translateSub(
const User &U, MachineIRBuilder &MIRBuilder) {
463 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
465 bool translateAnd(
const User &U, MachineIRBuilder &MIRBuilder) {
466 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
468 bool translateMul(
const User &U, MachineIRBuilder &MIRBuilder) {
469 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
471 bool translateOr(
const User &U, MachineIRBuilder &MIRBuilder) {
472 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
474 bool translateXor(
const User &U, MachineIRBuilder &MIRBuilder) {
475 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
478 bool translateUDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
479 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
481 bool translateSDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
482 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
484 bool translateURem(
const User &U, MachineIRBuilder &MIRBuilder) {
485 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
487 bool translateSRem(
const User &U, MachineIRBuilder &MIRBuilder) {
488 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
490 bool translateIntToPtr(
const User &U, MachineIRBuilder &MIRBuilder) {
491 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
493 bool translatePtrToInt(
const User &U, MachineIRBuilder &MIRBuilder) {
494 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
496 bool translatePtrToAddr(
const User &U, MachineIRBuilder &MIRBuilder) {
498 return translatePtrToInt(U, MIRBuilder);
500 bool translateTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
501 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
503 bool translateFPTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
504 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
506 bool translateFPExt(
const User &U, MachineIRBuilder &MIRBuilder) {
507 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
509 bool translateFPToUI(
const User &U, MachineIRBuilder &MIRBuilder) {
510 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
512 bool translateFPToSI(
const User &U, MachineIRBuilder &MIRBuilder) {
513 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
515 bool translateUIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
516 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
518 bool translateSIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
519 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
521 bool translateUnreachable(
const User &U, MachineIRBuilder &MIRBuilder);
523 bool translateSExt(
const User &U, MachineIRBuilder &MIRBuilder) {
524 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
527 bool translateZExt(
const User &U, MachineIRBuilder &MIRBuilder) {
528 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
531 bool translateShl(
const User &U, MachineIRBuilder &MIRBuilder) {
532 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
534 bool translateLShr(
const User &U, MachineIRBuilder &MIRBuilder) {
535 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
537 bool translateAShr(
const User &U, MachineIRBuilder &MIRBuilder) {
538 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
541 bool translateFAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
542 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
544 bool translateFSub(
const User &U, MachineIRBuilder &MIRBuilder) {
545 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
547 bool translateFMul(
const User &U, MachineIRBuilder &MIRBuilder) {
548 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
550 bool translateFDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
551 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
553 bool translateFRem(
const User &U, MachineIRBuilder &MIRBuilder) {
554 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
557 bool translateVAArg(
const User &U, MachineIRBuilder &MIRBuilder);
559 bool translateInsertElement(
const User &U, MachineIRBuilder &MIRBuilder);
560 bool translateInsertVector(
const User &U, MachineIRBuilder &MIRBuilder);
562 bool translateExtractElement(
const User &U, MachineIRBuilder &MIRBuilder);
563 bool translateExtractVector(
const User &U, MachineIRBuilder &MIRBuilder);
565 bool translateShuffleVector(
const User &U, MachineIRBuilder &MIRBuilder);
567 bool translateAtomicCmpXchg(
const User &U, MachineIRBuilder &MIRBuilder);
568 bool translateAtomicRMW(
const User &U, MachineIRBuilder &MIRBuilder);
569 bool translateFence(
const User &U, MachineIRBuilder &MIRBuilder);
570 bool translateFreeze(
const User &U, MachineIRBuilder &MIRBuilder);
574 bool translateResume(
const User &U, MachineIRBuilder &MIRBuilder) {
577 bool translateCleanupRet(
const User &U, MachineIRBuilder &MIRBuilder) {
580 bool translateCatchRet(
const User &U, MachineIRBuilder &MIRBuilder) {
583 bool translateCatchSwitch(
const User &U, MachineIRBuilder &MIRBuilder) {
586 bool translateAddrSpaceCast(
const User &U, MachineIRBuilder &MIRBuilder) {
587 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
589 bool translateCleanupPad(
const User &U, MachineIRBuilder &MIRBuilder) {
592 bool translateCatchPad(
const User &U, MachineIRBuilder &MIRBuilder) {
595 bool translateUserOp1(
const User &U, MachineIRBuilder &MIRBuilder) {
598 bool translateUserOp2(
const User &U, MachineIRBuilder &MIRBuilder) {
602 bool translateConvergenceControlIntrinsic(
const CallInst &CI,
604 MachineIRBuilder &MIRBuilder);
613 std::unique_ptr<MachineIRBuilder> CurBuilder;
618 std::unique_ptr<MachineIRBuilder> EntryBuilder;
621 MachineFunction *MF =
nullptr;
624 MachineRegisterInfo *MRI =
nullptr;
626 const DataLayout *DL =
nullptr;
629 const TargetPassConfig *TPC =
nullptr;
634 std::unique_ptr<OptimizationRemarkEmitter> ORE;
636 AAResults *AA =
nullptr;
637 AssumptionCache *AC =
nullptr;
638 const TargetLibraryInfo *LibInfo =
nullptr;
639 const LibcallLoweringInfo *Libcalls =
nullptr;
640 const TargetLowering *TLI =
nullptr;
641 FunctionLoweringInfo FuncInfo;
645 bool EnableOpts =
false;
649 bool HasTailCall =
false;
651 StackProtectorDescriptor SPDescriptor;
654 class GISelSwitchLowering :
public SwitchCG::SwitchLowering {
656 GISelSwitchLowering(
IRTranslator *irt, FunctionLoweringInfo &funcinfo)
658 assert(irt &&
"irt is null!");
661 void addSuccessorWithProb(
662 MachineBasicBlock *Src, MachineBasicBlock *Dst,
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);
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.");
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);
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,