18#ifndef LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H
19#define LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H
42class ConstrainedFPIntrinsic;
45class MachineBasicBlock;
48class MachineRegisterInfo;
49class OptimizationRemarkEmitter;
51class TargetLibraryInfo;
52class TargetPassConfig;
73 class ValueToVRegInfo {
75 ValueToVRegInfo() =
default;
80 using const_vreg_iterator =
82 using const_offset_iterator =
85 inline const_vreg_iterator vregs_end()
const {
return ValToVRegs.end(); }
87 VRegListT *getVRegs(
const Value &V) {
88 auto It = ValToVRegs.find(&V);
89 if (It != ValToVRegs.end())
92 return insertVRegs(V);
95 OffsetListT *getOffsets(
const Value &V) {
96 auto It = TypeToOffsets.find(V.getType());
97 if (It != TypeToOffsets.end())
100 return insertOffsets(V);
103 const_vreg_iterator findVRegs(
const Value &V)
const {
104 return ValToVRegs.find(&V);
107 bool contains(
const Value &V)
const {
return ValToVRegs.contains(&V); }
111 TypeToOffsets.clear();
112 VRegAlloc.DestroyAll();
113 OffsetAlloc.DestroyAll();
117 VRegListT *insertVRegs(
const Value &V) {
118 assert(!ValToVRegs.contains(&V) &&
"Value already exists");
122 auto *VRegList =
new (VRegAlloc.Allocate()) VRegListT();
123 ValToVRegs[&V] = VRegList;
127 OffsetListT *insertOffsets(
const Value &V) {
128 assert(!TypeToOffsets.contains(V.getType()) &&
"Type already exists");
130 auto *OffsetList =
new (OffsetAlloc.Allocate()) OffsetListT();
131 TypeToOffsets[V.getType()] = OffsetList;
145 ValueToVRegInfo VMap;
157 using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>;
206 bool translateCopy(
const User &U,
const Value &V,
225 bool translateOverflowIntrinsic(
const CallInst &CI,
unsigned Op,
227 bool translateFixedPointIntrinsic(
unsigned Op,
const CallInst &CI,
264 bool findUnwindDestinations(
277 bool translateCast(
unsigned Opcode,
const User &U,
288 return translateCompare(U, MIRBuilder);
292 bool translateFCmp(
const User &U, MachineIRBuilder &MIRBuilder) {
293 return translateCompare(U, MIRBuilder);
298 void finishPendingPhis();
302 bool translateUnaryOp(
unsigned Opcode,
const User &U,
303 MachineIRBuilder &MIRBuilder);
307 bool translateBinaryOp(
unsigned Opcode,
const User &U,
308 MachineIRBuilder &MIRBuilder);
313 bool shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases);
317 void emitBranchForMergedCondition(
const Value *
Cond, MachineBasicBlock *
TBB,
318 MachineBasicBlock *FBB,
319 MachineBasicBlock *CurBB,
320 MachineBasicBlock *SwitchBB,
321 BranchProbability TProb,
322 BranchProbability FProb,
bool InvertCond);
325 void findMergedConditions(
const Value *
Cond, MachineBasicBlock *
TBB,
326 MachineBasicBlock *FBB, MachineBasicBlock *CurBB,
327 MachineBasicBlock *SwitchBB,
329 BranchProbability FProb,
bool InvertCond);
333 bool translateBr(
const User &U, MachineIRBuilder &MIRBuilder);
336 bool emitJumpTableHeader(SwitchCG::JumpTable &JT,
337 SwitchCG::JumpTableHeader &JTH,
338 MachineBasicBlock *HeaderBB);
339 void emitJumpTable(SwitchCG::JumpTable &JT, MachineBasicBlock *
MBB);
341 void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB,
342 MachineIRBuilder &MIB);
346 void emitBitTestHeader(SwitchCG::BitTestBlock &BTB,
347 MachineBasicBlock *SwitchMBB);
349 void emitBitTestCase(SwitchCG::BitTestBlock &BB, MachineBasicBlock *NextMBB,
350 BranchProbability BranchProbToNext, Register
Reg,
351 SwitchCG::BitTestCase &
B, MachineBasicBlock *SwitchBB);
353 bool lowerJumpTableWorkItem(
354 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
355 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
358 MachineBasicBlock *Fallthrough,
bool FallthroughUnreachable);
361 MachineBasicBlock *Fallthrough,
362 bool FallthroughUnreachable,
363 BranchProbability UnhandledProbs,
364 MachineBasicBlock *CurMBB,
365 MachineIRBuilder &MIB,
366 MachineBasicBlock *SwitchMBB);
368 bool lowerBitTestWorkItem(
369 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
370 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
372 BranchProbability DefaultProb, BranchProbability UnhandledProbs,
374 bool FallthroughUnreachable);
376 bool lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W, Value *
Cond,
377 MachineBasicBlock *SwitchMBB,
378 MachineBasicBlock *DefaultMBB,
379 MachineIRBuilder &MIB);
381 bool translateSwitch(
const User &U, MachineIRBuilder &MIRBuilder);
384 bool translateIndirectBr(
const User &U, MachineIRBuilder &MIRBuilder);
386 bool translateExtractValue(
const User &U, MachineIRBuilder &MIRBuilder);
388 bool translateInsertValue(
const User &U, MachineIRBuilder &MIRBuilder);
390 bool translateSelect(
const User &U, MachineIRBuilder &MIRBuilder);
392 bool translateGetElementPtr(
const User &U, MachineIRBuilder &MIRBuilder);
394 bool translateAlloca(
const User &U, MachineIRBuilder &MIRBuilder);
400 bool translateRet(
const User &U, MachineIRBuilder &MIRBuilder);
402 bool translateFNeg(
const User &U, MachineIRBuilder &MIRBuilder);
404 bool translateAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
405 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
407 bool translateSub(
const User &U, MachineIRBuilder &MIRBuilder) {
408 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
410 bool translateAnd(
const User &U, MachineIRBuilder &MIRBuilder) {
411 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
413 bool translateMul(
const User &U, MachineIRBuilder &MIRBuilder) {
414 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
416 bool translateOr(
const User &U, MachineIRBuilder &MIRBuilder) {
417 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
419 bool translateXor(
const User &U, MachineIRBuilder &MIRBuilder) {
420 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
423 bool translateUDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
424 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
426 bool translateSDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
427 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
429 bool translateURem(
const User &U, MachineIRBuilder &MIRBuilder) {
430 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
432 bool translateSRem(
const User &U, MachineIRBuilder &MIRBuilder) {
433 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
435 bool translateIntToPtr(
const User &U, MachineIRBuilder &MIRBuilder) {
436 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
438 bool translatePtrToInt(
const User &U, MachineIRBuilder &MIRBuilder) {
439 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
441 bool translateTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
442 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
444 bool translateFPTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
445 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
447 bool translateFPExt(
const User &U, MachineIRBuilder &MIRBuilder) {
448 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
450 bool translateFPToUI(
const User &U, MachineIRBuilder &MIRBuilder) {
451 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
453 bool translateFPToSI(
const User &U, MachineIRBuilder &MIRBuilder) {
454 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
456 bool translateUIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
457 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
459 bool translateSIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
460 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
462 bool translateUnreachable(
const User &U, MachineIRBuilder &MIRBuilder);
464 bool translateSExt(
const User &U, MachineIRBuilder &MIRBuilder) {
465 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
468 bool translateZExt(
const User &U, MachineIRBuilder &MIRBuilder) {
469 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
472 bool translateShl(
const User &U, MachineIRBuilder &MIRBuilder) {
473 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
475 bool translateLShr(
const User &U, MachineIRBuilder &MIRBuilder) {
476 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
478 bool translateAShr(
const User &U, MachineIRBuilder &MIRBuilder) {
479 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
482 bool translateFAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
483 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
485 bool translateFSub(
const User &U, MachineIRBuilder &MIRBuilder) {
486 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
488 bool translateFMul(
const User &U, MachineIRBuilder &MIRBuilder) {
489 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
491 bool translateFDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
492 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
494 bool translateFRem(
const User &U, MachineIRBuilder &MIRBuilder) {
495 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
498 bool translateVAArg(
const User &U, MachineIRBuilder &MIRBuilder);
500 bool translateInsertElement(
const User &U, MachineIRBuilder &MIRBuilder);
502 bool translateExtractElement(
const User &U, MachineIRBuilder &MIRBuilder);
504 bool translateShuffleVector(
const User &U, MachineIRBuilder &MIRBuilder);
506 bool translateAtomicCmpXchg(
const User &U, MachineIRBuilder &MIRBuilder);
507 bool translateAtomicRMW(
const User &U, MachineIRBuilder &MIRBuilder);
508 bool translateFence(
const User &U, MachineIRBuilder &MIRBuilder);
509 bool translateFreeze(
const User &U, MachineIRBuilder &MIRBuilder);
513 bool translateResume(
const User &U, MachineIRBuilder &MIRBuilder) {
516 bool translateCleanupRet(
const User &U, MachineIRBuilder &MIRBuilder) {
519 bool translateCatchRet(
const User &U, MachineIRBuilder &MIRBuilder) {
522 bool translateCatchSwitch(
const User &U, MachineIRBuilder &MIRBuilder) {
525 bool translateAddrSpaceCast(
const User &U, MachineIRBuilder &MIRBuilder) {
526 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
528 bool translateCleanupPad(
const User &U, MachineIRBuilder &MIRBuilder) {
531 bool translateCatchPad(
const User &U, MachineIRBuilder &MIRBuilder) {
534 bool translateUserOp1(
const User &U, MachineIRBuilder &MIRBuilder) {
537 bool translateUserOp2(
const User &U, MachineIRBuilder &MIRBuilder) {
548 std::unique_ptr<MachineIRBuilder> CurBuilder;
553 std::unique_ptr<MachineIRBuilder> EntryBuilder;
559 MachineRegisterInfo *MRI =
nullptr;
561 const DataLayout *DL;
564 const TargetPassConfig *TPC;
569 std::unique_ptr<OptimizationRemarkEmitter> ORE;
573 const TargetLibraryInfo *LibInfo;
578 bool EnableOpts =
false;
582 bool HasTailCall =
false;
584 StackProtectorDescriptor SPDescriptor;
587 class GISelSwitchLowering :
public SwitchCG::SwitchLowering {
589 GISelSwitchLowering(IRTranslator *irt, FunctionLoweringInfo &funcinfo)
591 assert(irt &&
"irt is null!");
594 void addSuccessorWithProb(
595 MachineBasicBlock *Src, MachineBasicBlock *Dst,
597 IRT->addSuccessorWithProb(Src, Dst, Prob);
600 virtual ~GISelSwitchLowering() =
default;
606 std::unique_ptr<GISelSwitchLowering> SL;
612 void finalizeFunction();
617 bool finalizeBasicBlock(
const BasicBlock &BB, MachineBasicBlock &
MBB);
627 bool emitSPDescriptorParent(StackProtectorDescriptor &SPD,
628 MachineBasicBlock *ParentBB);
640 bool emitSPDescriptorFailure(StackProtectorDescriptor &SPD,
641 MachineBasicBlock *FailureBB);
647 ArrayRef<Register> getOrCreateVRegs(
const Value &Val);
649 Register getOrCreateVReg(
const Value &Val) {
650 auto Regs = getOrCreateVRegs(Val);
653 assert(Regs.size() == 1 &&
654 "attempt to get single VReg for aggregate or void");
660 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
664 int getOrCreateFrameIndex(
const AllocaInst &AI);
669 Align getMemOpAlign(
const Instruction &
I);
674 MachineBasicBlock &getMBB(
const BasicBlock &BB);
680 void addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred);
686 SmallVector<MachineBasicBlock *, 1> getMachinePredBBs(CFGEdge Edge) {
687 auto RemappedEdge = MachinePreds.
find(Edge);
688 if (RemappedEdge != MachinePreds.
end())
689 return RemappedEdge->second;
690 return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*Edge.first));
695 BranchProbability getEdgeProbability(
const MachineBasicBlock *Src,
696 const MachineBasicBlock *Dst)
const;
698 void addSuccessorWithProb(
699 MachineBasicBlock *Src, MachineBasicBlock *Dst,
return AArch64::GPR64RegClass contains(Reg)
This file defines the BumpPtrAllocator interface.
SmallVector< MachineOperand, 4 > Cond
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseMap class.
This file declares the MachineIRBuilder class.
typename CallsiteContextGraph< DerivedCCG, FuncTy, CallTy >::FuncInfo FuncInfo
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
Represent the analysis usage information of a pass.
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.
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...
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...
IRTranslator(CodeGenOpt::Level OptLevel=CodeGenOpt::None)
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.
Level
Code generation optimization level.
@ BasicBlock
Various leaf nodes.
CaseClusterVector::iterator CaseClusterIt
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.