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,
249 bool translateVectorInterleave2Intrinsic(
const CallInst &CI,
251 bool translateVectorDeinterleave2Intrinsic(
const CallInst &CI,
256 bool translateOverflowIntrinsic(
const CallInst &CI,
unsigned Op,
258 bool translateFixedPointIntrinsic(
unsigned Op,
const CallInst &CI,
280 std::optional<MCRegister> getArgPhysReg(
Argument &Arg);
286 bool translateIfEntryValueArgument(
bool isDeclare,
Value *Arg,
309 bool findUnwindDestinations(
322 bool translateCast(
unsigned Opcode,
const User &U,
333 return translateCompare(U, MIRBuilder);
337 bool translateFCmp(
const User &U, MachineIRBuilder &MIRBuilder) {
338 return translateCompare(U, MIRBuilder);
343 void finishPendingPhis();
347 bool translateUnaryOp(
unsigned Opcode,
const User &U,
348 MachineIRBuilder &MIRBuilder);
352 bool translateBinaryOp(
unsigned Opcode,
const User &U,
353 MachineIRBuilder &MIRBuilder);
358 bool shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases);
362 void emitBranchForMergedCondition(
const Value *
Cond, MachineBasicBlock *
TBB,
363 MachineBasicBlock *FBB,
364 MachineBasicBlock *CurBB,
365 MachineBasicBlock *SwitchBB,
366 BranchProbability TProb,
367 BranchProbability FProb,
bool InvertCond);
370 void findMergedConditions(
const Value *
Cond, MachineBasicBlock *
TBB,
371 MachineBasicBlock *FBB, MachineBasicBlock *CurBB,
372 MachineBasicBlock *SwitchBB,
374 BranchProbability FProb,
bool InvertCond);
378 bool translateBr(
const User &U, MachineIRBuilder &MIRBuilder);
381 bool emitJumpTableHeader(SwitchCG::JumpTable &JT,
382 SwitchCG::JumpTableHeader &JTH,
383 MachineBasicBlock *HeaderBB);
384 void emitJumpTable(SwitchCG::JumpTable &JT, MachineBasicBlock *
MBB);
386 void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB,
387 MachineIRBuilder &MIB);
391 void emitBitTestHeader(SwitchCG::BitTestBlock &BTB,
392 MachineBasicBlock *SwitchMBB);
394 void emitBitTestCase(SwitchCG::BitTestBlock &BB, MachineBasicBlock *NextMBB,
395 BranchProbability BranchProbToNext, Register
Reg,
396 SwitchCG::BitTestCase &
B, MachineBasicBlock *SwitchBB);
399 const SwitchCG::SwitchWorkListItem &W, Value *
Cond,
400 MachineBasicBlock *SwitchMBB, MachineIRBuilder &MIB);
402 bool lowerJumpTableWorkItem(
403 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
404 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
407 MachineBasicBlock *Fallthrough,
bool FallthroughUnreachable);
410 MachineBasicBlock *Fallthrough,
411 bool FallthroughUnreachable,
412 BranchProbability UnhandledProbs,
413 MachineBasicBlock *CurMBB,
414 MachineIRBuilder &MIB,
415 MachineBasicBlock *SwitchMBB);
417 bool lowerBitTestWorkItem(
418 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
419 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
421 BranchProbability DefaultProb, BranchProbability UnhandledProbs,
423 bool FallthroughUnreachable);
425 bool lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W, Value *
Cond,
426 MachineBasicBlock *SwitchMBB,
427 MachineBasicBlock *DefaultMBB,
428 MachineIRBuilder &MIB);
430 bool translateSwitch(
const User &U, MachineIRBuilder &MIRBuilder);
433 bool translateIndirectBr(
const User &U, MachineIRBuilder &MIRBuilder);
435 bool translateExtractValue(
const User &U, MachineIRBuilder &MIRBuilder);
437 bool translateInsertValue(
const User &U, MachineIRBuilder &MIRBuilder);
439 bool translateSelect(
const User &U, MachineIRBuilder &MIRBuilder);
441 bool translateGetElementPtr(
const User &U, MachineIRBuilder &MIRBuilder);
443 bool translateAlloca(
const User &U, MachineIRBuilder &MIRBuilder);
449 bool translateRet(
const User &U, MachineIRBuilder &MIRBuilder);
451 bool translateFNeg(
const User &U, MachineIRBuilder &MIRBuilder);
453 bool translateAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
454 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
456 bool translateSub(
const User &U, MachineIRBuilder &MIRBuilder) {
457 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
459 bool translateAnd(
const User &U, MachineIRBuilder &MIRBuilder) {
460 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
462 bool translateMul(
const User &U, MachineIRBuilder &MIRBuilder) {
463 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
465 bool translateOr(
const User &U, MachineIRBuilder &MIRBuilder) {
466 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
468 bool translateXor(
const User &U, MachineIRBuilder &MIRBuilder) {
469 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
472 bool translateUDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
473 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
475 bool translateSDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
476 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
478 bool translateURem(
const User &U, MachineIRBuilder &MIRBuilder) {
479 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
481 bool translateSRem(
const User &U, MachineIRBuilder &MIRBuilder) {
482 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
484 bool translateIntToPtr(
const User &U, MachineIRBuilder &MIRBuilder) {
485 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
487 bool translatePtrToInt(
const User &U, MachineIRBuilder &MIRBuilder) {
488 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
490 bool translateTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
491 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
493 bool translateFPTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
494 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
496 bool translateFPExt(
const User &U, MachineIRBuilder &MIRBuilder) {
497 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
499 bool translateFPToUI(
const User &U, MachineIRBuilder &MIRBuilder) {
500 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
502 bool translateFPToSI(
const User &U, MachineIRBuilder &MIRBuilder) {
503 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
505 bool translateUIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
506 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
508 bool translateSIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
509 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
511 bool translateUnreachable(
const User &U, MachineIRBuilder &MIRBuilder);
513 bool translateSExt(
const User &U, MachineIRBuilder &MIRBuilder) {
514 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
517 bool translateZExt(
const User &U, MachineIRBuilder &MIRBuilder) {
518 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
521 bool translateShl(
const User &U, MachineIRBuilder &MIRBuilder) {
522 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
524 bool translateLShr(
const User &U, MachineIRBuilder &MIRBuilder) {
525 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
527 bool translateAShr(
const User &U, MachineIRBuilder &MIRBuilder) {
528 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
531 bool translateFAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
532 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
534 bool translateFSub(
const User &U, MachineIRBuilder &MIRBuilder) {
535 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
537 bool translateFMul(
const User &U, MachineIRBuilder &MIRBuilder) {
538 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
540 bool translateFDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
541 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
543 bool translateFRem(
const User &U, MachineIRBuilder &MIRBuilder) {
544 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
547 bool translateVAArg(
const User &U, MachineIRBuilder &MIRBuilder);
549 bool translateInsertElement(
const User &U, MachineIRBuilder &MIRBuilder);
551 bool translateExtractElement(
const User &U, MachineIRBuilder &MIRBuilder);
553 bool translateShuffleVector(
const User &U, MachineIRBuilder &MIRBuilder);
555 bool translateAtomicCmpXchg(
const User &U, MachineIRBuilder &MIRBuilder);
556 bool translateAtomicRMW(
const User &U, MachineIRBuilder &MIRBuilder);
557 bool translateFence(
const User &U, MachineIRBuilder &MIRBuilder);
558 bool translateFreeze(
const User &U, MachineIRBuilder &MIRBuilder);
562 bool translateResume(
const User &U, MachineIRBuilder &MIRBuilder) {
565 bool translateCleanupRet(
const User &U, MachineIRBuilder &MIRBuilder) {
568 bool translateCatchRet(
const User &U, MachineIRBuilder &MIRBuilder) {
571 bool translateCatchSwitch(
const User &U, MachineIRBuilder &MIRBuilder) {
574 bool translateAddrSpaceCast(
const User &U, MachineIRBuilder &MIRBuilder) {
575 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
577 bool translateCleanupPad(
const User &U, MachineIRBuilder &MIRBuilder) {
580 bool translateCatchPad(
const User &U, MachineIRBuilder &MIRBuilder) {
583 bool translateUserOp1(
const User &U, MachineIRBuilder &MIRBuilder) {
586 bool translateUserOp2(
const User &U, MachineIRBuilder &MIRBuilder) {
597 std::unique_ptr<MachineIRBuilder> CurBuilder;
602 std::unique_ptr<MachineIRBuilder> EntryBuilder;
605 MachineFunction *MF =
nullptr;
608 MachineRegisterInfo *MRI =
nullptr;
610 const DataLayout *DL =
nullptr;
613 const TargetPassConfig *TPC =
nullptr;
618 std::unique_ptr<OptimizationRemarkEmitter> ORE;
620 AAResults *AA =
nullptr;
621 AssumptionCache *AC =
nullptr;
622 const TargetLibraryInfo *LibInfo =
nullptr;
623 const TargetLowering *TLI =
nullptr;
624 FunctionLoweringInfo FuncInfo;
628 bool EnableOpts =
false;
632 bool HasTailCall =
false;
634 StackProtectorDescriptor SPDescriptor;
637 class GISelSwitchLowering :
public SwitchCG::SwitchLowering {
639 GISelSwitchLowering(IRTranslator *irt, FunctionLoweringInfo &funcinfo)
641 assert(irt &&
"irt is null!");
644 void addSuccessorWithProb(
645 MachineBasicBlock *Src, MachineBasicBlock *Dst,
647 IRT->addSuccessorWithProb(Src, Dst, Prob);
650 virtual ~GISelSwitchLowering() =
default;
656 std::unique_ptr<GISelSwitchLowering> SL;
662 void finalizeFunction();
667 bool finalizeBasicBlock(
const BasicBlock &BB, MachineBasicBlock &
MBB);
677 bool emitSPDescriptorParent(StackProtectorDescriptor &SPD,
678 MachineBasicBlock *ParentBB);
690 bool emitSPDescriptorFailure(StackProtectorDescriptor &SPD,
691 MachineBasicBlock *FailureBB);
697 ArrayRef<Register> getOrCreateVRegs(
const Value &Val);
699 Register getOrCreateVReg(
const Value &Val) {
700 auto Regs = getOrCreateVRegs(Val);
703 assert(Regs.size() == 1 &&
704 "attempt to get single VReg for aggregate or void");
710 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
714 int getOrCreateFrameIndex(
const AllocaInst &AI);
719 Align getMemOpAlign(
const Instruction &
I);
724 MachineBasicBlock &getMBB(
const BasicBlock &BB);
730 void addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred);
736 SmallVector<MachineBasicBlock *, 1> getMachinePredBBs(CFGEdge Edge) {
737 auto RemappedEdge = MachinePreds.
find(Edge);
738 if (RemappedEdge != MachinePreds.
end())
739 return RemappedEdge->second;
740 return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*Edge.first));
745 BranchProbability getEdgeProbability(
const MachineBasicBlock *Src,
746 const MachineBasicBlock *Dst)
const;
748 void addSuccessorWithProb(
749 MachineBasicBlock *Src, MachineBasicBlock *Dst,
return AArch64::GPR64RegClass contains(Reg)
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...
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.