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;
159 using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>;
215 void translateDbgValueRecord(
Value *V,
bool HasArgList,
223 void translateDbgDeclareRecord(
Value *
Address,
bool HasArgList,
229 bool translateCopy(
const User &U,
const Value &V,
253 bool translateVectorInterleave2Intrinsic(
const CallInst &CI,
255 bool translateVectorDeinterleave2Intrinsic(
const CallInst &CI,
260 bool translateOverflowIntrinsic(
const CallInst &CI,
unsigned Op,
262 bool translateFixedPointIntrinsic(
unsigned Op,
const CallInst &CI,
284 std::optional<MCRegister> getArgPhysReg(
Argument &Arg);
290 bool translateIfEntryValueArgument(
bool isDeclare,
Value *Arg,
313 bool findUnwindDestinations(
326 bool translateCast(
unsigned Opcode,
const User &U,
337 return translateCompare(U, MIRBuilder);
341 bool translateFCmp(
const User &U, MachineIRBuilder &MIRBuilder) {
342 return translateCompare(U, MIRBuilder);
347 void finishPendingPhis();
351 bool translateUnaryOp(
unsigned Opcode,
const User &U,
352 MachineIRBuilder &MIRBuilder);
356 bool translateBinaryOp(
unsigned Opcode,
const User &U,
357 MachineIRBuilder &MIRBuilder);
362 bool shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases);
366 void emitBranchForMergedCondition(
const Value *
Cond, MachineBasicBlock *
TBB,
367 MachineBasicBlock *FBB,
368 MachineBasicBlock *CurBB,
369 MachineBasicBlock *SwitchBB,
370 BranchProbability TProb,
371 BranchProbability FProb,
bool InvertCond);
374 void findMergedConditions(
const Value *
Cond, MachineBasicBlock *
TBB,
375 MachineBasicBlock *FBB, MachineBasicBlock *CurBB,
376 MachineBasicBlock *SwitchBB,
378 BranchProbability FProb,
bool InvertCond);
382 bool translateBr(
const User &U, MachineIRBuilder &MIRBuilder);
385 bool emitJumpTableHeader(SwitchCG::JumpTable &JT,
386 SwitchCG::JumpTableHeader &JTH,
387 MachineBasicBlock *HeaderBB);
388 void emitJumpTable(SwitchCG::JumpTable &JT, MachineBasicBlock *
MBB);
390 void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB,
391 MachineIRBuilder &MIB);
395 void emitBitTestHeader(SwitchCG::BitTestBlock &BTB,
396 MachineBasicBlock *SwitchMBB);
398 void emitBitTestCase(SwitchCG::BitTestBlock &BB, MachineBasicBlock *NextMBB,
399 BranchProbability BranchProbToNext, Register
Reg,
400 SwitchCG::BitTestCase &
B, MachineBasicBlock *SwitchBB);
403 const SwitchCG::SwitchWorkListItem &W, Value *
Cond,
404 MachineBasicBlock *SwitchMBB, MachineIRBuilder &MIB);
406 bool lowerJumpTableWorkItem(
407 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
408 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
411 MachineBasicBlock *Fallthrough,
bool FallthroughUnreachable);
414 MachineBasicBlock *Fallthrough,
415 bool FallthroughUnreachable,
416 BranchProbability UnhandledProbs,
417 MachineBasicBlock *CurMBB,
418 MachineIRBuilder &MIB,
419 MachineBasicBlock *SwitchMBB);
421 bool lowerBitTestWorkItem(
422 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
423 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
425 BranchProbability DefaultProb, BranchProbability UnhandledProbs,
427 bool FallthroughUnreachable);
429 bool lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W, Value *
Cond,
430 MachineBasicBlock *SwitchMBB,
431 MachineBasicBlock *DefaultMBB,
432 MachineIRBuilder &MIB);
434 bool translateSwitch(
const User &U, MachineIRBuilder &MIRBuilder);
437 bool translateIndirectBr(
const User &U, MachineIRBuilder &MIRBuilder);
439 bool translateExtractValue(
const User &U, MachineIRBuilder &MIRBuilder);
441 bool translateInsertValue(
const User &U, MachineIRBuilder &MIRBuilder);
443 bool translateSelect(
const User &U, MachineIRBuilder &MIRBuilder);
445 bool translateGetElementPtr(
const User &U, MachineIRBuilder &MIRBuilder);
447 bool translateAlloca(
const User &U, MachineIRBuilder &MIRBuilder);
453 bool translateRet(
const User &U, MachineIRBuilder &MIRBuilder);
455 bool translateFNeg(
const User &U, MachineIRBuilder &MIRBuilder);
457 bool translateAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
458 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
460 bool translateSub(
const User &U, MachineIRBuilder &MIRBuilder) {
461 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
463 bool translateAnd(
const User &U, MachineIRBuilder &MIRBuilder) {
464 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
466 bool translateMul(
const User &U, MachineIRBuilder &MIRBuilder) {
467 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
469 bool translateOr(
const User &U, MachineIRBuilder &MIRBuilder) {
470 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
472 bool translateXor(
const User &U, MachineIRBuilder &MIRBuilder) {
473 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
476 bool translateUDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
477 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
479 bool translateSDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
480 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
482 bool translateURem(
const User &U, MachineIRBuilder &MIRBuilder) {
483 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
485 bool translateSRem(
const User &U, MachineIRBuilder &MIRBuilder) {
486 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
488 bool translateIntToPtr(
const User &U, MachineIRBuilder &MIRBuilder) {
489 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
491 bool translatePtrToInt(
const User &U, MachineIRBuilder &MIRBuilder) {
492 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
494 bool translateTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
495 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
497 bool translateFPTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
498 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
500 bool translateFPExt(
const User &U, MachineIRBuilder &MIRBuilder) {
501 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
503 bool translateFPToUI(
const User &U, MachineIRBuilder &MIRBuilder) {
504 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
506 bool translateFPToSI(
const User &U, MachineIRBuilder &MIRBuilder) {
507 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
509 bool translateUIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
510 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
512 bool translateSIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
513 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
515 bool translateUnreachable(
const User &U, MachineIRBuilder &MIRBuilder);
517 bool translateSExt(
const User &U, MachineIRBuilder &MIRBuilder) {
518 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
521 bool translateZExt(
const User &U, MachineIRBuilder &MIRBuilder) {
522 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
525 bool translateShl(
const User &U, MachineIRBuilder &MIRBuilder) {
526 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
528 bool translateLShr(
const User &U, MachineIRBuilder &MIRBuilder) {
529 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
531 bool translateAShr(
const User &U, MachineIRBuilder &MIRBuilder) {
532 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
535 bool translateFAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
536 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
538 bool translateFSub(
const User &U, MachineIRBuilder &MIRBuilder) {
539 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
541 bool translateFMul(
const User &U, MachineIRBuilder &MIRBuilder) {
542 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
544 bool translateFDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
545 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
547 bool translateFRem(
const User &U, MachineIRBuilder &MIRBuilder) {
548 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
551 bool translateVAArg(
const User &U, MachineIRBuilder &MIRBuilder);
553 bool translateInsertElement(
const User &U, MachineIRBuilder &MIRBuilder);
555 bool translateExtractElement(
const User &U, MachineIRBuilder &MIRBuilder);
557 bool translateShuffleVector(
const User &U, MachineIRBuilder &MIRBuilder);
559 bool translateAtomicCmpXchg(
const User &U, MachineIRBuilder &MIRBuilder);
560 bool translateAtomicRMW(
const User &U, MachineIRBuilder &MIRBuilder);
561 bool translateFence(
const User &U, MachineIRBuilder &MIRBuilder);
562 bool translateFreeze(
const User &U, MachineIRBuilder &MIRBuilder);
566 bool translateResume(
const User &U, MachineIRBuilder &MIRBuilder) {
569 bool translateCleanupRet(
const User &U, MachineIRBuilder &MIRBuilder) {
572 bool translateCatchRet(
const User &U, MachineIRBuilder &MIRBuilder) {
575 bool translateCatchSwitch(
const User &U, MachineIRBuilder &MIRBuilder) {
578 bool translateAddrSpaceCast(
const User &U, MachineIRBuilder &MIRBuilder) {
579 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
581 bool translateCleanupPad(
const User &U, MachineIRBuilder &MIRBuilder) {
584 bool translateCatchPad(
const User &U, MachineIRBuilder &MIRBuilder) {
587 bool translateUserOp1(
const User &U, MachineIRBuilder &MIRBuilder) {
590 bool translateUserOp2(
const User &U, MachineIRBuilder &MIRBuilder) {
594 bool translateConvergenceControlIntrinsic(
const CallInst &CI,
596 MachineIRBuilder &MIRBuilder);
605 std::unique_ptr<MachineIRBuilder> CurBuilder;
610 std::unique_ptr<MachineIRBuilder> EntryBuilder;
613 MachineFunction *MF =
nullptr;
616 MachineRegisterInfo *MRI =
nullptr;
618 const DataLayout *DL =
nullptr;
621 const TargetPassConfig *TPC =
nullptr;
626 std::unique_ptr<OptimizationRemarkEmitter> ORE;
628 AAResults *AA =
nullptr;
629 AssumptionCache *AC =
nullptr;
630 const TargetLibraryInfo *LibInfo =
nullptr;
631 const TargetLowering *TLI =
nullptr;
632 FunctionLoweringInfo FuncInfo;
636 bool EnableOpts =
false;
640 bool HasTailCall =
false;
642 StackProtectorDescriptor SPDescriptor;
645 class GISelSwitchLowering :
public SwitchCG::SwitchLowering {
647 GISelSwitchLowering(IRTranslator *irt, FunctionLoweringInfo &funcinfo)
649 assert(irt &&
"irt is null!");
652 void addSuccessorWithProb(
653 MachineBasicBlock *Src, MachineBasicBlock *Dst,
655 IRT->addSuccessorWithProb(Src, Dst, Prob);
658 virtual ~GISelSwitchLowering() =
default;
664 std::unique_ptr<GISelSwitchLowering> SL;
670 void finalizeFunction();
675 bool finalizeBasicBlock(
const BasicBlock &BB, MachineBasicBlock &
MBB);
685 bool emitSPDescriptorParent(StackProtectorDescriptor &SPD,
686 MachineBasicBlock *ParentBB);
698 bool emitSPDescriptorFailure(StackProtectorDescriptor &SPD,
699 MachineBasicBlock *FailureBB);
705 ArrayRef<Register> getOrCreateVRegs(
const Value &Val);
707 Register getOrCreateVReg(
const Value &Val) {
708 auto Regs = getOrCreateVRegs(Val);
711 assert(Regs.size() == 1 &&
712 "attempt to get single VReg for aggregate or void");
716 Register getOrCreateConvergenceTokenVReg(
const Value &Token) {
717 assert(Token.getType()->isTokenTy());
718 auto &Regs = *VMap.getVRegs(Token);
720 assert(Regs.size() == 1 &&
721 "Expected a single register for convergence tokens.");
727 auto &
Offsets = *VMap.getOffsets(Token);
735 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
739 int getOrCreateFrameIndex(
const AllocaInst &AI);
744 Align getMemOpAlign(
const Instruction &
I);
749 MachineBasicBlock &getMBB(
const BasicBlock &BB);
755 void addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred);
761 SmallVector<MachineBasicBlock *, 1> getMachinePredBBs(CFGEdge Edge) {
762 auto RemappedEdge = MachinePreds.
find(Edge);
763 if (RemappedEdge != MachinePreds.
end())
764 return RemappedEdge->second;
765 return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*Edge.first));
770 BranchProbability getEdgeProbability(
const MachineBasicBlock *Src,
771 const MachineBasicBlock *Dst)
const;
773 void addSuccessorWithProb(
774 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.