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);
550 bool translateExtractElement(
const User &U, MachineIRBuilder &MIRBuilder);
552 bool translateShuffleVector(
const User &U, MachineIRBuilder &MIRBuilder);
554 bool translateAtomicCmpXchg(
const User &U, MachineIRBuilder &MIRBuilder);
555 bool translateAtomicRMW(
const User &U, MachineIRBuilder &MIRBuilder);
556 bool translateFence(
const User &U, MachineIRBuilder &MIRBuilder);
557 bool translateFreeze(
const User &U, MachineIRBuilder &MIRBuilder);
561 bool translateResume(
const User &U, MachineIRBuilder &MIRBuilder) {
564 bool translateCleanupRet(
const User &U, MachineIRBuilder &MIRBuilder) {
567 bool translateCatchRet(
const User &U, MachineIRBuilder &MIRBuilder) {
570 bool translateCatchSwitch(
const User &U, MachineIRBuilder &MIRBuilder) {
573 bool translateAddrSpaceCast(
const User &U, MachineIRBuilder &MIRBuilder) {
574 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
576 bool translateCleanupPad(
const User &U, MachineIRBuilder &MIRBuilder) {
579 bool translateCatchPad(
const User &U, MachineIRBuilder &MIRBuilder) {
582 bool translateUserOp1(
const User &U, MachineIRBuilder &MIRBuilder) {
585 bool translateUserOp2(
const User &U, MachineIRBuilder &MIRBuilder) {
589 bool translateConvergenceControlIntrinsic(
const CallInst &CI,
591 MachineIRBuilder &MIRBuilder);
600 std::unique_ptr<MachineIRBuilder> CurBuilder;
605 std::unique_ptr<MachineIRBuilder> EntryBuilder;
608 MachineFunction *MF =
nullptr;
611 MachineRegisterInfo *MRI =
nullptr;
613 const DataLayout *DL =
nullptr;
616 const TargetPassConfig *TPC =
nullptr;
621 std::unique_ptr<OptimizationRemarkEmitter> ORE;
623 AAResults *AA =
nullptr;
624 AssumptionCache *AC =
nullptr;
625 const TargetLibraryInfo *LibInfo =
nullptr;
626 const TargetLowering *TLI =
nullptr;
627 FunctionLoweringInfo FuncInfo;
631 bool EnableOpts =
false;
635 bool HasTailCall =
false;
637 StackProtectorDescriptor SPDescriptor;
640 class GISelSwitchLowering :
public SwitchCG::SwitchLowering {
642 GISelSwitchLowering(IRTranslator *irt, FunctionLoweringInfo &funcinfo)
644 assert(irt &&
"irt is null!");
647 void addSuccessorWithProb(
648 MachineBasicBlock *Src, MachineBasicBlock *Dst,
650 IRT->addSuccessorWithProb(Src, Dst, Prob);
653 virtual ~GISelSwitchLowering() =
default;
659 std::unique_ptr<GISelSwitchLowering> SL;
665 void finalizeFunction();
670 bool finalizeBasicBlock(
const BasicBlock &BB, MachineBasicBlock &
MBB);
680 bool emitSPDescriptorParent(StackProtectorDescriptor &SPD,
681 MachineBasicBlock *ParentBB);
693 bool emitSPDescriptorFailure(StackProtectorDescriptor &SPD,
694 MachineBasicBlock *FailureBB);
700 ArrayRef<Register> getOrCreateVRegs(
const Value &Val);
702 Register getOrCreateVReg(
const Value &Val) {
703 auto Regs = getOrCreateVRegs(Val);
706 assert(Regs.size() == 1 &&
707 "attempt to get single VReg for aggregate or void");
711 Register getOrCreateConvergenceTokenVReg(
const Value &Token) {
712 assert(Token.getType()->isTokenTy());
713 auto &Regs = *VMap.getVRegs(Token);
715 assert(Regs.size() == 1 &&
716 "Expected a single register for convergence tokens.");
722 auto &
Offsets = *VMap.getOffsets(Token);
730 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
734 int getOrCreateFrameIndex(
const AllocaInst &AI);
739 Align getMemOpAlign(
const Instruction &
I);
744 MachineBasicBlock &getMBB(
const BasicBlock &BB);
750 void addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred);
756 SmallVector<MachineBasicBlock *, 1> getMachinePredBBs(CFGEdge Edge) {
757 auto RemappedEdge = MachinePreds.
find(Edge);
758 if (RemappedEdge != MachinePreds.
end())
759 return RemappedEdge->second;
760 return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*Edge.first));
765 BranchProbability getEdgeProbability(
const MachineBasicBlock *Src,
766 const MachineBasicBlock *Dst)
const;
768 void addSuccessorWithProb(
769 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.