18#ifndef LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H
19#define LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H
42class ConstrainedFPIntrinsic;
47class MachineBasicBlock;
50class MachineRegisterInfo;
51class OptimizationRemarkEmitter;
53class TargetLibraryInfo;
54class TargetPassConfig;
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,
308 bool findUnwindDestinations(
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,
394 BranchProbability BranchProbToNext, Register
Reg,
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 translateTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
490 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
492 bool translateFPTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
493 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
495 bool translateFPExt(
const User &U, MachineIRBuilder &MIRBuilder) {
496 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
498 bool translateFPToUI(
const User &U, MachineIRBuilder &MIRBuilder) {
499 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
501 bool translateFPToSI(
const User &U, MachineIRBuilder &MIRBuilder) {
502 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
504 bool translateUIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
505 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
507 bool translateSIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
508 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
510 bool translateUnreachable(
const User &U, MachineIRBuilder &MIRBuilder);
512 bool translateSExt(
const User &U, MachineIRBuilder &MIRBuilder) {
513 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
516 bool translateZExt(
const User &U, MachineIRBuilder &MIRBuilder) {
517 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
520 bool translateShl(
const User &U, MachineIRBuilder &MIRBuilder) {
521 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
523 bool translateLShr(
const User &U, MachineIRBuilder &MIRBuilder) {
524 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
526 bool translateAShr(
const User &U, MachineIRBuilder &MIRBuilder) {
527 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
530 bool translateFAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
531 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
533 bool translateFSub(
const User &U, MachineIRBuilder &MIRBuilder) {
534 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
536 bool translateFMul(
const User &U, MachineIRBuilder &MIRBuilder) {
537 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
539 bool translateFDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
540 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
542 bool translateFRem(
const User &U, MachineIRBuilder &MIRBuilder) {
543 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
546 bool translateVAArg(
const User &U, MachineIRBuilder &MIRBuilder);
548 bool translateInsertElement(
const User &U, MachineIRBuilder &MIRBuilder);
549 bool translateInsertVector(
const User &U, MachineIRBuilder &MIRBuilder);
551 bool translateExtractElement(
const User &U, MachineIRBuilder &MIRBuilder);
552 bool translateExtractVector(
const User &U, MachineIRBuilder &MIRBuilder);
554 bool translateShuffleVector(
const User &U, MachineIRBuilder &MIRBuilder);
556 bool translateAtomicCmpXchg(
const User &U, MachineIRBuilder &MIRBuilder);
557 bool translateAtomicRMW(
const User &U, MachineIRBuilder &MIRBuilder);
558 bool translateFence(
const User &U, MachineIRBuilder &MIRBuilder);
559 bool translateFreeze(
const User &U, MachineIRBuilder &MIRBuilder);
563 bool translateResume(
const User &U, MachineIRBuilder &MIRBuilder) {
566 bool translateCleanupRet(
const User &U, MachineIRBuilder &MIRBuilder) {
569 bool translateCatchRet(
const User &U, MachineIRBuilder &MIRBuilder) {
572 bool translateCatchSwitch(
const User &U, MachineIRBuilder &MIRBuilder) {
575 bool translateAddrSpaceCast(
const User &U, MachineIRBuilder &MIRBuilder) {
576 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
578 bool translateCleanupPad(
const User &U, MachineIRBuilder &MIRBuilder) {
581 bool translateCatchPad(
const User &U, MachineIRBuilder &MIRBuilder) {
584 bool translateUserOp1(
const User &U, MachineIRBuilder &MIRBuilder) {
587 bool translateUserOp2(
const User &U, MachineIRBuilder &MIRBuilder) {
591 bool translateConvergenceControlIntrinsic(
const CallInst &CI,
593 MachineIRBuilder &MIRBuilder);
602 std::unique_ptr<MachineIRBuilder> CurBuilder;
607 std::unique_ptr<MachineIRBuilder> EntryBuilder;
610 MachineFunction *MF =
nullptr;
613 MachineRegisterInfo *MRI =
nullptr;
615 const DataLayout *DL =
nullptr;
618 const TargetPassConfig *TPC =
nullptr;
623 std::unique_ptr<OptimizationRemarkEmitter> ORE;
625 AAResults *AA =
nullptr;
626 AssumptionCache *AC =
nullptr;
627 const TargetLibraryInfo *LibInfo =
nullptr;
628 const TargetLowering *TLI =
nullptr;
629 FunctionLoweringInfo FuncInfo;
633 bool EnableOpts =
false;
637 bool HasTailCall =
false;
639 StackProtectorDescriptor SPDescriptor;
642 class GISelSwitchLowering :
public SwitchCG::SwitchLowering {
644 GISelSwitchLowering(IRTranslator *irt, FunctionLoweringInfo &funcinfo)
646 assert(irt &&
"irt is null!");
649 void addSuccessorWithProb(
650 MachineBasicBlock *Src, MachineBasicBlock *Dst,
652 IRT->addSuccessorWithProb(Src, Dst, Prob);
655 virtual ~GISelSwitchLowering() =
default;
661 std::unique_ptr<GISelSwitchLowering> SL;
667 void finalizeFunction();
672 bool finalizeBasicBlock(
const BasicBlock &BB, MachineBasicBlock &
MBB);
682 bool emitSPDescriptorParent(StackProtectorDescriptor &SPD,
683 MachineBasicBlock *ParentBB);
695 bool emitSPDescriptorFailure(StackProtectorDescriptor &SPD,
696 MachineBasicBlock *FailureBB);
702 ArrayRef<Register> getOrCreateVRegs(
const Value &Val);
704 Register getOrCreateVReg(
const Value &Val) {
705 auto Regs = getOrCreateVRegs(Val);
708 assert(Regs.size() == 1 &&
709 "attempt to get single VReg for aggregate or void");
713 Register getOrCreateConvergenceTokenVReg(
const Value &Token) {
714 assert(Token.getType()->isTokenTy());
715 auto &Regs = *VMap.getVRegs(Token);
717 assert(Regs.size() == 1 &&
718 "Expected a single register for convergence tokens.");
724 auto &
Offsets = *VMap.getOffsets(Token);
732 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
736 int getOrCreateFrameIndex(
const AllocaInst &AI);
741 Align getMemOpAlign(
const Instruction &
I);
746 MachineBasicBlock &getMBB(
const BasicBlock &BB);
752 void addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred);
758 SmallVector<MachineBasicBlock *, 1> getMachinePredBBs(CFGEdge Edge) {
759 auto RemappedEdge = MachinePreds.
find(Edge);
760 if (RemappedEdge != MachinePreds.
end())
761 return RemappedEdge->second;
762 return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*Edge.first));
767 BranchProbability getEdgeProbability(
const MachineBasicBlock *Src,
768 const MachineBasicBlock *Dst)
const;
770 void addSuccessorWithProb(
771 MachineBasicBlock *Src, MachineBasicBlock *Dst,
return AArch64::GPR64RegClass contains(Reg)
unsigned const MachineRegisterInfo * MRI
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseMap class.
This file declares the MachineIRBuilder class.
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
Represent the analysis usage information of a pass.
This class represents an incoming formal argument to a Function.
LLVM Basic Block Representation.
static BranchProbability getUnknown()
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
This class represents a function call, abstracting a target machine's calling convention.
This is an important base class in LLVM.
This is the common base class for constrained floating point intrinsics.
This class represents an Operation in the Expression.
iterator find(const_arg_type_t< KeyT > Val)
Class representing an expression and its matching format.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
IRTranslator(CodeGenOptLevel OptLevel=CodeGenOptLevel::None)
StringRef getPassName() const override
getPassName - Return a nice clean name for a pass.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
static constexpr LLT token()
Get a low-level token; just a scalar with zero bits (or no size).
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
BasicBlockListType::iterator iterator
Helper class to build MachineInstr.
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
StringRef - Represent a constant reference to a string, i.e.
SwitchLowering(FunctionLoweringInfo &funcinfo)
LLVM Value Representation.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
SmallVector< SwitchWorkListItem, 4 > SwitchWorkList
CaseClusterVector::iterator CaseClusterIt
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.
CodeGenOptLevel
Code generation optimization level.