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);
108 return ValToVRegs.find(&V) != ValToVRegs.end();
113 TypeToOffsets.clear();
114 VRegAlloc.DestroyAll();
115 OffsetAlloc.DestroyAll();
119 VRegListT *insertVRegs(
const Value &V) {
120 assert(ValToVRegs.find(&V) == ValToVRegs.end() &&
"Value already exists");
124 auto *VRegList =
new (VRegAlloc.Allocate()) VRegListT();
125 ValToVRegs[&V] = VRegList;
129 OffsetListT *insertOffsets(
const Value &V) {
130 assert(TypeToOffsets.find(V.
getType()) == TypeToOffsets.end() &&
131 "Type already exists");
133 auto *OffsetList =
new (OffsetAlloc.Allocate()) OffsetListT();
134 TypeToOffsets[V.
getType()] = OffsetList;
148 ValueToVRegInfo VMap;
160 using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>;
209 bool translateCopy(
const User &U,
const Value &V,
228 bool translateOverflowIntrinsic(
const CallInst &CI,
unsigned Op,
230 bool translateFixedPointIntrinsic(
unsigned Op,
const CallInst &CI,
267 bool findUnwindDestinations(
280 bool translateCast(
unsigned Opcode,
const User &U,
291 return translateCompare(U, MIRBuilder);
295 bool translateFCmp(
const User &U, MachineIRBuilder &MIRBuilder) {
296 return translateCompare(U, MIRBuilder);
301 void finishPendingPhis();
305 bool translateUnaryOp(
unsigned Opcode,
const User &U,
306 MachineIRBuilder &MIRBuilder);
310 bool translateBinaryOp(
unsigned Opcode,
const User &U,
311 MachineIRBuilder &MIRBuilder);
316 bool shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases);
320 void emitBranchForMergedCondition(
const Value *
Cond, MachineBasicBlock *
TBB,
321 MachineBasicBlock *FBB,
322 MachineBasicBlock *CurBB,
323 MachineBasicBlock *SwitchBB,
324 BranchProbability TProb,
325 BranchProbability FProb,
bool InvertCond);
328 void findMergedConditions(
const Value *
Cond, MachineBasicBlock *
TBB,
329 MachineBasicBlock *FBB, MachineBasicBlock *CurBB,
330 MachineBasicBlock *SwitchBB,
332 BranchProbability FProb,
bool InvertCond);
336 bool translateBr(
const User &U, MachineIRBuilder &MIRBuilder);
339 bool emitJumpTableHeader(SwitchCG::JumpTable &JT,
340 SwitchCG::JumpTableHeader &JTH,
341 MachineBasicBlock *HeaderBB);
342 void emitJumpTable(SwitchCG::JumpTable &JT, MachineBasicBlock *
MBB);
344 void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB,
345 MachineIRBuilder &MIB);
349 void emitBitTestHeader(SwitchCG::BitTestBlock &BTB,
350 MachineBasicBlock *SwitchMBB);
352 void emitBitTestCase(SwitchCG::BitTestBlock &BB, MachineBasicBlock *NextMBB,
353 BranchProbability BranchProbToNext, Register
Reg,
354 SwitchCG::BitTestCase &
B, MachineBasicBlock *SwitchBB);
356 bool lowerJumpTableWorkItem(
357 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
358 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
361 MachineBasicBlock *Fallthrough,
bool FallthroughUnreachable);
364 MachineBasicBlock *Fallthrough,
365 bool FallthroughUnreachable,
366 BranchProbability UnhandledProbs,
367 MachineBasicBlock *CurMBB,
368 MachineIRBuilder &MIB,
369 MachineBasicBlock *SwitchMBB);
371 bool lowerBitTestWorkItem(
372 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
373 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
375 BranchProbability DefaultProb, BranchProbability UnhandledProbs,
377 bool FallthroughUnreachable);
379 bool lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W, Value *
Cond,
380 MachineBasicBlock *SwitchMBB,
381 MachineBasicBlock *DefaultMBB,
382 MachineIRBuilder &MIB);
384 bool translateSwitch(
const User &U, MachineIRBuilder &MIRBuilder);
387 bool translateIndirectBr(
const User &U, MachineIRBuilder &MIRBuilder);
389 bool translateExtractValue(
const User &U, MachineIRBuilder &MIRBuilder);
391 bool translateInsertValue(
const User &U, MachineIRBuilder &MIRBuilder);
393 bool translateSelect(
const User &U, MachineIRBuilder &MIRBuilder);
395 bool translateGetElementPtr(
const User &U, MachineIRBuilder &MIRBuilder);
397 bool translateAlloca(
const User &U, MachineIRBuilder &MIRBuilder);
403 bool translateRet(
const User &U, MachineIRBuilder &MIRBuilder);
405 bool translateFNeg(
const User &U, MachineIRBuilder &MIRBuilder);
407 bool translateAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
408 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
410 bool translateSub(
const User &U, MachineIRBuilder &MIRBuilder) {
411 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
413 bool translateAnd(
const User &U, MachineIRBuilder &MIRBuilder) {
414 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
416 bool translateMul(
const User &U, MachineIRBuilder &MIRBuilder) {
417 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
419 bool translateOr(
const User &U, MachineIRBuilder &MIRBuilder) {
420 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
422 bool translateXor(
const User &U, MachineIRBuilder &MIRBuilder) {
423 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
426 bool translateUDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
427 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
429 bool translateSDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
430 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
432 bool translateURem(
const User &U, MachineIRBuilder &MIRBuilder) {
433 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
435 bool translateSRem(
const User &U, MachineIRBuilder &MIRBuilder) {
436 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
438 bool translateIntToPtr(
const User &U, MachineIRBuilder &MIRBuilder) {
439 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
441 bool translatePtrToInt(
const User &U, MachineIRBuilder &MIRBuilder) {
442 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
444 bool translateTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
445 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
447 bool translateFPTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
448 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
450 bool translateFPExt(
const User &U, MachineIRBuilder &MIRBuilder) {
451 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
453 bool translateFPToUI(
const User &U, MachineIRBuilder &MIRBuilder) {
454 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
456 bool translateFPToSI(
const User &U, MachineIRBuilder &MIRBuilder) {
457 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
459 bool translateUIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
460 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
462 bool translateSIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
463 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
465 bool translateUnreachable(
const User &U, MachineIRBuilder &MIRBuilder);
467 bool translateSExt(
const User &U, MachineIRBuilder &MIRBuilder) {
468 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
471 bool translateZExt(
const User &U, MachineIRBuilder &MIRBuilder) {
472 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
475 bool translateShl(
const User &U, MachineIRBuilder &MIRBuilder) {
476 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
478 bool translateLShr(
const User &U, MachineIRBuilder &MIRBuilder) {
479 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
481 bool translateAShr(
const User &U, MachineIRBuilder &MIRBuilder) {
482 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
485 bool translateFAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
486 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
488 bool translateFSub(
const User &U, MachineIRBuilder &MIRBuilder) {
489 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
491 bool translateFMul(
const User &U, MachineIRBuilder &MIRBuilder) {
492 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
494 bool translateFDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
495 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
497 bool translateFRem(
const User &U, MachineIRBuilder &MIRBuilder) {
498 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
501 bool translateVAArg(
const User &U, MachineIRBuilder &MIRBuilder);
503 bool translateInsertElement(
const User &U, MachineIRBuilder &MIRBuilder);
505 bool translateExtractElement(
const User &U, MachineIRBuilder &MIRBuilder);
507 bool translateShuffleVector(
const User &U, MachineIRBuilder &MIRBuilder);
509 bool translateAtomicCmpXchg(
const User &U, MachineIRBuilder &MIRBuilder);
510 bool translateAtomicRMW(
const User &U, MachineIRBuilder &MIRBuilder);
511 bool translateFence(
const User &U, MachineIRBuilder &MIRBuilder);
512 bool translateFreeze(
const User &U, MachineIRBuilder &MIRBuilder);
516 bool translateResume(
const User &U, MachineIRBuilder &MIRBuilder) {
519 bool translateCleanupRet(
const User &U, MachineIRBuilder &MIRBuilder) {
522 bool translateCatchRet(
const User &U, MachineIRBuilder &MIRBuilder) {
525 bool translateCatchSwitch(
const User &U, MachineIRBuilder &MIRBuilder) {
528 bool translateAddrSpaceCast(
const User &U, MachineIRBuilder &MIRBuilder) {
529 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
531 bool translateCleanupPad(
const User &U, MachineIRBuilder &MIRBuilder) {
534 bool translateCatchPad(
const User &U, MachineIRBuilder &MIRBuilder) {
537 bool translateUserOp1(
const User &U, MachineIRBuilder &MIRBuilder) {
540 bool translateUserOp2(
const User &U, MachineIRBuilder &MIRBuilder) {
551 std::unique_ptr<MachineIRBuilder> CurBuilder;
556 std::unique_ptr<MachineIRBuilder> EntryBuilder;
562 MachineRegisterInfo *MRI =
nullptr;
564 const DataLayout *DL;
567 const TargetPassConfig *TPC;
572 std::unique_ptr<OptimizationRemarkEmitter> ORE;
576 const TargetLibraryInfo *LibInfo;
577 FunctionLoweringInfo FuncInfo;
581 bool EnableOpts =
false;
585 bool HasTailCall =
false;
587 StackProtectorDescriptor SPDescriptor;
590 class GISelSwitchLowering :
public SwitchCG::SwitchLowering {
592 GISelSwitchLowering(IRTranslator *irt, FunctionLoweringInfo &funcinfo)
594 assert(irt &&
"irt is null!");
597 void addSuccessorWithProb(
598 MachineBasicBlock *Src, MachineBasicBlock *Dst,
600 IRT->addSuccessorWithProb(Src, Dst, Prob);
603 virtual ~GISelSwitchLowering() =
default;
609 std::unique_ptr<GISelSwitchLowering> SL;
615 void finalizeFunction();
620 bool finalizeBasicBlock(
const BasicBlock &BB, MachineBasicBlock &
MBB);
630 bool emitSPDescriptorParent(StackProtectorDescriptor &SPD,
631 MachineBasicBlock *ParentBB);
643 bool emitSPDescriptorFailure(StackProtectorDescriptor &SPD,
644 MachineBasicBlock *FailureBB);
650 ArrayRef<Register> getOrCreateVRegs(
const Value &Val);
652 Register getOrCreateVReg(
const Value &Val) {
653 auto Regs = getOrCreateVRegs(Val);
656 assert(Regs.size() == 1 &&
657 "attempt to get single VReg for aggregate or void");
663 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
667 int getOrCreateFrameIndex(
const AllocaInst &AI);
672 Align getMemOpAlign(
const Instruction &
I);
677 MachineBasicBlock &getMBB(
const BasicBlock &BB);
683 void addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred);
689 SmallVector<MachineBasicBlock *, 1> getMachinePredBBs(CFGEdge Edge) {
690 auto RemappedEdge = MachinePreds.
find(Edge);
691 if (RemappedEdge != MachinePreds.
end())
692 return RemappedEdge->second;
693 return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*Edge.first));
698 BranchProbability getEdgeProbability(
const MachineBasicBlock *Src,
699 const MachineBasicBlock *Dst)
const;
701 void addSuccessorWithProb(
702 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.
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.
Type * getType() const
All values are typed, get the type of this value.
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.