18 #ifndef LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H
19 #define LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H
41 class ConstrainedFPIntrinsic;
44 class MachineBasicBlock;
45 class MachineFunction;
47 class MachineRegisterInfo;
48 class OptimizationRemarkEmitter;
50 class TargetPassConfig;
71 class ValueToVRegInfo {
73 ValueToVRegInfo() =
default;
78 using const_vreg_iterator =
80 using const_offset_iterator =
83 inline const_vreg_iterator vregs_end()
const {
return ValToVRegs.end(); }
85 VRegListT *getVRegs(
const Value &V) {
86 auto It = ValToVRegs.find(&V);
87 if (It != ValToVRegs.end())
90 return insertVRegs(V);
93 OffsetListT *getOffsets(
const Value &V) {
94 auto It = TypeToOffsets.find(V.
getType());
95 if (It != TypeToOffsets.end())
98 return insertOffsets(V);
101 const_vreg_iterator findVRegs(
const Value &V)
const {
102 return ValToVRegs.find(&V);
106 return ValToVRegs.find(&V) != ValToVRegs.end();
111 TypeToOffsets.clear();
112 VRegAlloc.DestroyAll();
113 OffsetAlloc.DestroyAll();
117 VRegListT *insertVRegs(
const Value &V) {
118 assert(ValToVRegs.find(&V) == ValToVRegs.end() &&
"Value already exists");
122 auto *VRegList =
new (VRegAlloc.Allocate()) VRegListT();
123 ValToVRegs[&V] = VRegList;
127 OffsetListT *insertOffsets(
const Value &V) {
128 assert(TypeToOffsets.find(V.
getType()) == TypeToOffsets.end() &&
129 "Type already exists");
131 auto *OffsetList =
new (OffsetAlloc.Allocate()) OffsetListT();
132 TypeToOffsets[V.
getType()] = OffsetList;
146 ValueToVRegInfo VMap;
158 using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>;
207 bool translateCopy(
const User &U,
const Value &V,
226 bool translateOverflowIntrinsic(
const CallInst &CI,
unsigned Op,
228 bool translateFixedPointIntrinsic(
unsigned Op,
const CallInst &CI,
265 bool findUnwindDestinations(
278 bool translateCast(
unsigned Opcode,
const User &U,
289 return translateCompare(U, MIRBuilder);
293 bool translateFCmp(
const User &U, MachineIRBuilder &MIRBuilder) {
294 return translateCompare(U, MIRBuilder);
299 void finishPendingPhis();
303 bool translateUnaryOp(
unsigned Opcode,
const User &U,
304 MachineIRBuilder &MIRBuilder);
308 bool translateBinaryOp(
unsigned Opcode,
const User &U,
309 MachineIRBuilder &MIRBuilder);
314 bool shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases);
318 void emitBranchForMergedCondition(
const Value *
Cond, MachineBasicBlock *TBB,
319 MachineBasicBlock *FBB,
320 MachineBasicBlock *CurBB,
321 MachineBasicBlock *SwitchBB,
322 BranchProbability TProb,
323 BranchProbability FProb,
bool InvertCond);
326 void findMergedConditions(
const Value *
Cond, MachineBasicBlock *TBB,
327 MachineBasicBlock *FBB, MachineBasicBlock *CurBB,
328 MachineBasicBlock *SwitchBB,
330 BranchProbability FProb,
bool InvertCond);
334 bool translateBr(
const User &U, MachineIRBuilder &MIRBuilder);
338 SwitchCG::JumpTableHeader &JTH,
339 MachineBasicBlock *HeaderBB);
342 void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB,
343 MachineIRBuilder &MIB);
347 void emitBitTestHeader(SwitchCG::BitTestBlock &BTB,
348 MachineBasicBlock *SwitchMBB);
350 void emitBitTestCase(SwitchCG::BitTestBlock &
BB, MachineBasicBlock *NextMBB,
351 BranchProbability BranchProbToNext, Register
Reg,
352 SwitchCG::BitTestCase &
B, MachineBasicBlock *SwitchBB);
354 bool lowerJumpTableWorkItem(
355 SwitchCG::SwitchWorkListItem
W, MachineBasicBlock *SwitchMBB,
356 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
359 MachineBasicBlock *Fallthrough,
bool FallthroughUnreachable);
362 MachineBasicBlock *Fallthrough,
363 bool FallthroughUnreachable,
364 BranchProbability UnhandledProbs,
365 MachineBasicBlock *CurMBB,
366 MachineIRBuilder &MIB,
367 MachineBasicBlock *SwitchMBB);
369 bool lowerBitTestWorkItem(
370 SwitchCG::SwitchWorkListItem
W, MachineBasicBlock *SwitchMBB,
371 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
373 BranchProbability DefaultProb, BranchProbability UnhandledProbs,
375 bool FallthroughUnreachable);
377 bool lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem
W,
Value *
Cond,
378 MachineBasicBlock *SwitchMBB,
379 MachineBasicBlock *DefaultMBB,
380 MachineIRBuilder &MIB);
382 bool translateSwitch(
const User &U, MachineIRBuilder &MIRBuilder);
385 bool translateIndirectBr(
const User &U, MachineIRBuilder &MIRBuilder);
387 bool translateExtractValue(
const User &U, MachineIRBuilder &MIRBuilder);
389 bool translateInsertValue(
const User &U, MachineIRBuilder &MIRBuilder);
391 bool translateSelect(
const User &U, MachineIRBuilder &MIRBuilder);
393 bool translateGetElementPtr(
const User &U, MachineIRBuilder &MIRBuilder);
395 bool translateAlloca(
const User &U, MachineIRBuilder &MIRBuilder);
401 bool translateRet(
const User &U, MachineIRBuilder &MIRBuilder);
403 bool translateFNeg(
const User &U, MachineIRBuilder &MIRBuilder);
405 bool translateAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
406 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
408 bool translateSub(
const User &U, MachineIRBuilder &MIRBuilder) {
409 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
411 bool translateAnd(
const User &U, MachineIRBuilder &MIRBuilder) {
412 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
414 bool translateMul(
const User &U, MachineIRBuilder &MIRBuilder) {
415 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
417 bool translateOr(
const User &U, MachineIRBuilder &MIRBuilder) {
418 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
420 bool translateXor(
const User &U, MachineIRBuilder &MIRBuilder) {
421 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
424 bool translateUDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
425 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
427 bool translateSDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
428 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
430 bool translateURem(
const User &U, MachineIRBuilder &MIRBuilder) {
431 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
433 bool translateSRem(
const User &U, MachineIRBuilder &MIRBuilder) {
434 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
436 bool translateIntToPtr(
const User &U, MachineIRBuilder &MIRBuilder) {
437 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
439 bool translatePtrToInt(
const User &U, MachineIRBuilder &MIRBuilder) {
440 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
442 bool translateTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
443 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
445 bool translateFPTrunc(
const User &U, MachineIRBuilder &MIRBuilder) {
446 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
448 bool translateFPExt(
const User &U, MachineIRBuilder &MIRBuilder) {
449 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
451 bool translateFPToUI(
const User &U, MachineIRBuilder &MIRBuilder) {
452 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
454 bool translateFPToSI(
const User &U, MachineIRBuilder &MIRBuilder) {
455 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
457 bool translateUIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
458 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
460 bool translateSIToFP(
const User &U, MachineIRBuilder &MIRBuilder) {
461 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
463 bool translateUnreachable(
const User &U, MachineIRBuilder &MIRBuilder);
465 bool translateSExt(
const User &U, MachineIRBuilder &MIRBuilder) {
466 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
469 bool translateZExt(
const User &U, MachineIRBuilder &MIRBuilder) {
470 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
473 bool translateShl(
const User &U, MachineIRBuilder &MIRBuilder) {
474 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
476 bool translateLShr(
const User &U, MachineIRBuilder &MIRBuilder) {
477 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
479 bool translateAShr(
const User &U, MachineIRBuilder &MIRBuilder) {
480 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
483 bool translateFAdd(
const User &U, MachineIRBuilder &MIRBuilder) {
484 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
486 bool translateFSub(
const User &U, MachineIRBuilder &MIRBuilder) {
487 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
489 bool translateFMul(
const User &U, MachineIRBuilder &MIRBuilder) {
490 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
492 bool translateFDiv(
const User &U, MachineIRBuilder &MIRBuilder) {
493 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
495 bool translateFRem(
const User &U, MachineIRBuilder &MIRBuilder) {
496 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
499 bool translateVAArg(
const User &U, MachineIRBuilder &MIRBuilder);
501 bool translateInsertElement(
const User &U, MachineIRBuilder &MIRBuilder);
503 bool translateExtractElement(
const User &U, MachineIRBuilder &MIRBuilder);
505 bool translateShuffleVector(
const User &U, MachineIRBuilder &MIRBuilder);
507 bool translateAtomicCmpXchg(
const User &U, MachineIRBuilder &MIRBuilder);
508 bool translateAtomicRMW(
const User &U, MachineIRBuilder &MIRBuilder);
509 bool translateFence(
const User &U, MachineIRBuilder &MIRBuilder);
510 bool translateFreeze(
const User &U, MachineIRBuilder &MIRBuilder);
514 bool translateResume(
const User &U, MachineIRBuilder &MIRBuilder) {
517 bool translateCleanupRet(
const User &U, MachineIRBuilder &MIRBuilder) {
520 bool translateCatchRet(
const User &U, MachineIRBuilder &MIRBuilder) {
523 bool translateCatchSwitch(
const User &U, MachineIRBuilder &MIRBuilder) {
526 bool translateAddrSpaceCast(
const User &U, MachineIRBuilder &MIRBuilder) {
527 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
529 bool translateCleanupPad(
const User &U, MachineIRBuilder &MIRBuilder) {
532 bool translateCatchPad(
const User &U, MachineIRBuilder &MIRBuilder) {
535 bool translateUserOp1(
const User &U, MachineIRBuilder &MIRBuilder) {
538 bool translateUserOp2(
const User &U, MachineIRBuilder &MIRBuilder) {
549 std::unique_ptr<MachineIRBuilder> CurBuilder;
554 std::unique_ptr<MachineIRBuilder> EntryBuilder;
560 MachineRegisterInfo *MRI =
nullptr;
562 const DataLayout *DL;
565 const TargetPassConfig *TPC;
570 std::unique_ptr<OptimizationRemarkEmitter> ORE;
572 FunctionLoweringInfo FuncInfo;
576 bool EnableOpts =
false;
580 bool HasTailCall =
false;
582 StackProtectorDescriptor SPDescriptor;
585 class GISelSwitchLowering :
public SwitchCG::SwitchLowering {
587 GISelSwitchLowering(
IRTranslator *irt, FunctionLoweringInfo &funcinfo)
589 assert(irt &&
"irt is null!");
592 virtual void addSuccessorWithProb(
593 MachineBasicBlock *Src, MachineBasicBlock *Dst,
595 IRT->addSuccessorWithProb(Src, Dst, Prob);
598 virtual ~GISelSwitchLowering() =
default;
604 std::unique_ptr<GISelSwitchLowering> SL;
610 void finalizeFunction();
625 bool emitSPDescriptorParent(StackProtectorDescriptor &SPD,
626 MachineBasicBlock *ParentBB);
638 bool emitSPDescriptorFailure(StackProtectorDescriptor &SPD,
639 MachineBasicBlock *FailureBB);
645 ArrayRef<Register> getOrCreateVRegs(
const Value &Val);
648 auto Regs = getOrCreateVRegs(Val);
651 assert(Regs.size() == 1 &&
652 "attempt to get single VReg for aggregate or void");
658 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
662 int getOrCreateFrameIndex(
const AllocaInst &AI);
667 Align getMemOpAlign(
const Instruction &
I);
678 void addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred);
684 SmallVector<MachineBasicBlock *, 1> getMachinePredBBs(CFGEdge Edge) {
685 auto RemappedEdge = MachinePreds.
find(Edge);
686 if (RemappedEdge != MachinePreds.
end())
687 return RemappedEdge->second;
688 return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*Edge.first));
693 BranchProbability getEdgeProbability(
const MachineBasicBlock *Src,
694 const MachineBasicBlock *Dst)
const;
696 void addSuccessorWithProb(
697 MachineBasicBlock *Src, MachineBasicBlock *Dst,
724 #endif // LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H