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 *>;
208 bool translateCopy(
const User &U,
const Value &V,
227 bool translateOverflowIntrinsic(
const CallInst &CI,
unsigned Op,
229 bool translateFixedPointIntrinsic(
unsigned Op,
const CallInst &CI,
251 std::optional<MCRegister> getArgPhysReg(
Argument &Arg);
255 bool translateIfEntryValueArgument(
const DbgDeclareInst &DebugInst);
260 bool translateIfEntryValueArgument(
const DbgValueInst &DebugInst,
280 bool findUnwindDestinations(
293 bool translateCast(
unsigned Opcode,
const User &U,
304 return translateCompare(U, MIRBuilder);
308 bool translateFCmp(
const User &U, MachineIRBuilder &MIRBuilder) {
309 return translateCompare(U, MIRBuilder);
314 void finishPendingPhis();
318 bool translateUnaryOp(
unsigned Opcode,
const User &U,
319 MachineIRBuilder &MIRBuilder);
323 bool translateBinaryOp(
unsigned Opcode,
const User &U,
324 MachineIRBuilder &MIRBuilder);
329 bool shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases);
333 void emitBranchForMergedCondition(
const Value *
Cond, MachineBasicBlock *
TBB,
334 MachineBasicBlock *FBB,
335 MachineBasicBlock *CurBB,
336 MachineBasicBlock *SwitchBB,
337 BranchProbability TProb,
338 BranchProbability FProb,
bool InvertCond);
341 void findMergedConditions(
const Value *
Cond, MachineBasicBlock *
TBB,
342 MachineBasicBlock *FBB, MachineBasicBlock *CurBB,
343 MachineBasicBlock *SwitchBB,
345 BranchProbability FProb,
bool InvertCond);
349 bool translateBr(
const User &U, MachineIRBuilder &MIRBuilder);
352 bool emitJumpTableHeader(SwitchCG::JumpTable &JT,
353 SwitchCG::JumpTableHeader &JTH,
354 MachineBasicBlock *HeaderBB);
355 void emitJumpTable(SwitchCG::JumpTable &JT, MachineBasicBlock *
MBB);
357 void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB,
358 MachineIRBuilder &MIB);
362 void emitBitTestHeader(SwitchCG::BitTestBlock &BTB,
363 MachineBasicBlock *SwitchMBB);
365 void emitBitTestCase(SwitchCG::BitTestBlock &BB, MachineBasicBlock *NextMBB,
366 BranchProbability BranchProbToNext, Register
Reg,
367 SwitchCG::BitTestCase &
B, MachineBasicBlock *SwitchBB);
369 bool lowerJumpTableWorkItem(
370 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
371 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
374 MachineBasicBlock *Fallthrough,
bool FallthroughUnreachable);
377 MachineBasicBlock *Fallthrough,
378 bool FallthroughUnreachable,
379 BranchProbability UnhandledProbs,
380 MachineBasicBlock *CurMBB,
381 MachineIRBuilder &MIB,
382 MachineBasicBlock *SwitchMBB);
384 bool lowerBitTestWorkItem(
385 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
386 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
388 BranchProbability DefaultProb, BranchProbability UnhandledProbs,
390 bool FallthroughUnreachable);
392 bool lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W, Value *
Cond,
393 MachineBasicBlock *SwitchMBB,
394 MachineBasicBlock *DefaultMBB,
395 MachineIRBuilder &MIB);
397 bool translateSwitch(
const User &U, MachineIRBuilder &MIRBuilder);
400 bool translateIndirectBr(
const User &U, MachineIRBuilder &MIRBuilder);
402 bool translateExtractValue(
const User &U, MachineIRBuilder &MIRBuilder);
404 bool translateInsertValue(
const User &U, MachineIRBuilder &MIRBuilder);
406 bool translateSelect(
const User &U, MachineIRBuilder &MIRBuilder);
408 bool translateGetElementPtr(
const User &U, MachineIRBuilder &MIRBuilder);
410 bool translateAlloca(
const User &U, MachineIRBuilder &MIRBuilder);
416 bool translateRet(
const User &U, MachineIRBuilder &MIRBuilder);
418 bool translateFNeg(
const User &U, MachineIRBuilder &MIRBuilder);
420 bool translateAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
421 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
423 bool translateSub(
const User &U, MachineIRBuilder &MIRBuilder) {
424 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
426 bool translateAnd(
const User &U, MachineIRBuilder &MIRBuilder) {
427 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
429 bool translateMul(
const User &U, MachineIRBuilder &MIRBuilder) {
430 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
432 bool translateOr(
const User &U, MachineIRBuilder &MIRBuilder) {
433 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
435 bool translateXor(
const User &U, MachineIRBuilder &MIRBuilder) {
436 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
439 bool translateUDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
440 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
442 bool translateSDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
443 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
445 bool translateURem(
const User &U, MachineIRBuilder &MIRBuilder) {
446 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
448 bool translateSRem(
const User &U, MachineIRBuilder &MIRBuilder) {
449 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
451 bool translateIntToPtr(
const User &U, MachineIRBuilder &MIRBuilder) {
452 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
454 bool translatePtrToInt(
const User &U, MachineIRBuilder &MIRBuilder) {
455 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
457 bool translateTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
458 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
460 bool translateFPTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
461 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
463 bool translateFPExt(
const User &U, MachineIRBuilder &MIRBuilder) {
464 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
466 bool translateFPToUI(
const User &U, MachineIRBuilder &MIRBuilder) {
467 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
469 bool translateFPToSI(
const User &U, MachineIRBuilder &MIRBuilder) {
470 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
472 bool translateUIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
473 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
475 bool translateSIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
476 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
478 bool translateUnreachable(
const User &U, MachineIRBuilder &MIRBuilder);
480 bool translateSExt(
const User &U, MachineIRBuilder &MIRBuilder) {
481 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
484 bool translateZExt(
const User &U, MachineIRBuilder &MIRBuilder) {
485 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
488 bool translateShl(
const User &U, MachineIRBuilder &MIRBuilder) {
489 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
491 bool translateLShr(
const User &U, MachineIRBuilder &MIRBuilder) {
492 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
494 bool translateAShr(
const User &U, MachineIRBuilder &MIRBuilder) {
495 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
498 bool translateFAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
499 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
501 bool translateFSub(
const User &U, MachineIRBuilder &MIRBuilder) {
502 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
504 bool translateFMul(
const User &U, MachineIRBuilder &MIRBuilder) {
505 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
507 bool translateFDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
508 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
510 bool translateFRem(
const User &U, MachineIRBuilder &MIRBuilder) {
511 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
514 bool translateVAArg(
const User &U, MachineIRBuilder &MIRBuilder);
516 bool translateInsertElement(
const User &U, MachineIRBuilder &MIRBuilder);
518 bool translateExtractElement(
const User &U, MachineIRBuilder &MIRBuilder);
520 bool translateShuffleVector(
const User &U, MachineIRBuilder &MIRBuilder);
522 bool translateAtomicCmpXchg(
const User &U, MachineIRBuilder &MIRBuilder);
523 bool translateAtomicRMW(
const User &U, MachineIRBuilder &MIRBuilder);
524 bool translateFence(
const User &U, MachineIRBuilder &MIRBuilder);
525 bool translateFreeze(
const User &U, MachineIRBuilder &MIRBuilder);
529 bool translateResume(
const User &U, MachineIRBuilder &MIRBuilder) {
532 bool translateCleanupRet(
const User &U, MachineIRBuilder &MIRBuilder) {
535 bool translateCatchRet(
const User &U, MachineIRBuilder &MIRBuilder) {
538 bool translateCatchSwitch(
const User &U, MachineIRBuilder &MIRBuilder) {
541 bool translateAddrSpaceCast(
const User &U, MachineIRBuilder &MIRBuilder) {
542 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
544 bool translateCleanupPad(
const User &U, MachineIRBuilder &MIRBuilder) {
547 bool translateCatchPad(
const User &U, MachineIRBuilder &MIRBuilder) {
550 bool translateUserOp1(
const User &U, MachineIRBuilder &MIRBuilder) {
553 bool translateUserOp2(
const User &U, MachineIRBuilder &MIRBuilder) {
564 std::unique_ptr<MachineIRBuilder> CurBuilder;
569 std::unique_ptr<MachineIRBuilder> EntryBuilder;
572 MachineFunction *MF =
nullptr;
575 MachineRegisterInfo *MRI =
nullptr;
577 const DataLayout *DL =
nullptr;
580 const TargetPassConfig *TPC =
nullptr;
585 std::unique_ptr<OptimizationRemarkEmitter> ORE;
587 AAResults *AA =
nullptr;
588 AssumptionCache *AC =
nullptr;
589 const TargetLibraryInfo *LibInfo =
nullptr;
590 FunctionLoweringInfo FuncInfo;
594 bool EnableOpts =
false;
598 bool HasTailCall =
false;
600 StackProtectorDescriptor SPDescriptor;
603 class GISelSwitchLowering :
public SwitchCG::SwitchLowering {
605 GISelSwitchLowering(IRTranslator *irt, FunctionLoweringInfo &funcinfo)
607 assert(irt &&
"irt is null!");
610 void addSuccessorWithProb(
611 MachineBasicBlock *Src, MachineBasicBlock *Dst,
613 IRT->addSuccessorWithProb(Src, Dst, Prob);
616 virtual ~GISelSwitchLowering() =
default;
622 std::unique_ptr<GISelSwitchLowering> SL;
628 void finalizeFunction();
633 bool finalizeBasicBlock(
const BasicBlock &BB, MachineBasicBlock &
MBB);
643 bool emitSPDescriptorParent(StackProtectorDescriptor &SPD,
644 MachineBasicBlock *ParentBB);
656 bool emitSPDescriptorFailure(StackProtectorDescriptor &SPD,
657 MachineBasicBlock *FailureBB);
663 ArrayRef<Register> getOrCreateVRegs(
const Value &Val);
665 Register getOrCreateVReg(
const Value &Val) {
666 auto Regs = getOrCreateVRegs(Val);
669 assert(Regs.size() == 1 &&
670 "attempt to get single VReg for aggregate or void");
676 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
680 int getOrCreateFrameIndex(
const AllocaInst &AI);
685 Align getMemOpAlign(
const Instruction &
I);
690 MachineBasicBlock &getMBB(
const BasicBlock &BB);
696 void addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred);
702 SmallVector<MachineBasicBlock *, 1> getMachinePredBBs(CFGEdge Edge) {
703 auto RemappedEdge = MachinePreds.
find(Edge);
704 if (RemappedEdge != MachinePreds.
end())
705 return RemappedEdge->second;
706 return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*Edge.first));
711 BranchProbability getEdgeProbability(
const MachineBasicBlock *Src,
712 const MachineBasicBlock *Dst)
const;
714 void addSuccessorWithProb(
715 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.
static constexpr uint32_t Opcode
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.
This represents the llvm.dbg.declare instruction.
This represents the llvm.dbg.value instruction.
iterator find(const_arg_type_t< KeyT > Val)
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.
CaseClusterVector::iterator CaseClusterIt
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.
CodeGenOptLevel
Code generation optimization level.