LLVM: include/llvm/CodeGen/GlobalISel/IRTranslator.h Source File (original) (raw)
67public:
69
70private:
71
73
74
75 class ValueToVRegInfo {
76 public:
77 ValueToVRegInfo() = default;
78
81
82 using const_vreg_iterator =
84 using const_offset_iterator =
86
87 inline const_vreg_iterator vregs_end() const { return ValToVRegs.end(); }
88
89 VRegListT *getVRegs(const Value &V) {
90 auto It = ValToVRegs.find(&V);
91 if (It != ValToVRegs.end())
92 return It->second;
93
94 return insertVRegs(V);
95 }
96
97 OffsetListT *getOffsets(const Value &V) {
98 auto It = TypeToOffsets.find(V.getType());
99 if (It != TypeToOffsets.end())
100 return It->second;
101
102 return insertOffsets(V);
103 }
104
105 const_vreg_iterator findVRegs(const Value &V) const {
106 return ValToVRegs.find(&V);
107 }
108
109 bool contains(const Value &V) const { return ValToVRegs.contains(&V); }
110
111 void reset() {
112 ValToVRegs.clear();
113 TypeToOffsets.clear();
114 VRegAlloc.DestroyAll();
115 OffsetAlloc.DestroyAll();
116 }
117
118 private:
119 VRegListT *insertVRegs(const Value &V) {
120 assert(!ValToVRegs.contains(&V) && "Value already exists");
121
122
123
124 auto *VRegList = new (VRegAlloc.Allocate()) VRegListT();
125 ValToVRegs[&V] = VRegList;
126 return VRegList;
127 }
128
129 OffsetListT *insertOffsets(const Value &V) {
130 assert(!TypeToOffsets.contains(V.getType()) && "Type already exists");
131
132 auto *OffsetList = new (OffsetAlloc.Allocate()) OffsetListT();
133 TypeToOffsets[V.getType()] = OffsetList;
134 return OffsetList;
135 }
138
139
140
143 };
144
145
146
147 ValueToVRegInfo VMap;
148
149
150
151
152
153
154 using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>;
156
157
158
160 PendingPHIs;
161
162
163
165
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
194
195
196
197
198
199
201
202
203
204 void translateDbgInfo(const Instruction &Inst,
206
207
208
209
210 void translateDbgValueRecord(Value *V, bool HasArgList,
214
215
216
217
218 void translateDbgDeclareRecord(Value *Address, bool HasArgList,
222
223
224 bool translateCopy(const User &U, const Value &V,
226
227
228
230
231
233
234
236
237
239 unsigned Opcode);
240
241
243 unsigned Opcode);
244
245
246
247
248 bool translateVectorInterleave2Intrinsic(const CallInst &CI,
250 bool translateVectorDeinterleave2Intrinsic(const CallInst &CI,
252
254
255 bool translateOverflowIntrinsic(const CallInst &CI, unsigned Op,
257 bool translateFixedPointIntrinsic(unsigned Op, const CallInst &CI,
259
260
261
262
263
265
266
267
270
273
276
277
278
279 std::optional getArgPhysReg(Argument &Arg);
280
281
282
283
284
285 bool translateIfEntryValueArgument(bool isDeclare, Value *Arg,
290
292
293
295
296
297
299
300 bool translateIntrinsic(
303
304
305
306
307
308
309
310
311
314 SmallVectorImpl<std::pair<MachineBasicBlock *, BranchProbability>>
315 &UnwindDests);
316
318
320 bool translateCallBrIntrinsic(const CallBrInst &I,
322
324
325
326
327 bool translateCast(unsigned Opcode, const User &U,
329
330
332
333
335
336
338 return translateCompare(U, MIRBuilder);
339 }
340
341
342 bool translateFCmp(const User &U, MachineIRBuilder &MIRBuilder) {
343 return translateCompare(U, MIRBuilder);
344 }
345
346
347
348 void finishPendingPhis();
349
350
351
352 bool translateUnaryOp(unsigned Opcode, const User &U,
353 MachineIRBuilder &MIRBuilder);
354
355
356
357 bool translateBinaryOp(unsigned Opcode, const User &U,
358 MachineIRBuilder &MIRBuilder);
359
360
361
362
363 bool shouldEmitAsBranches(const std::vectorSwitchCG::CaseBlock &Cases);
364
365
366
367 void emitBranchForMergedCondition(const Value *Cond, MachineBasicBlock *TBB,
368 MachineBasicBlock *FBB,
369 MachineBasicBlock *CurBB,
370 MachineBasicBlock *SwitchBB,
371 BranchProbability TProb,
372 BranchProbability FProb, bool InvertCond);
373
374
375 void findMergedConditions(const Value *Cond, MachineBasicBlock *TBB,
376 MachineBasicBlock *FBB, MachineBasicBlock *CurBB,
377 MachineBasicBlock *SwitchBB,
379 BranchProbability FProb, bool InvertCond);
380
381
382
383 bool translateBr(const User &U, MachineIRBuilder &MIRBuilder);
384
385
386 bool emitJumpTableHeader(SwitchCG::JumpTable &JT,
387 SwitchCG::JumpTableHeader &JTH,
388 MachineBasicBlock *HeaderBB);
389 void emitJumpTable(SwitchCG::JumpTable &JT, MachineBasicBlock *MBB);
390
391 void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB,
392 MachineIRBuilder &MIB);
393
394
395
396 void emitBitTestHeader(SwitchCG::BitTestBlock &BTB,
397 MachineBasicBlock *SwitchMBB);
398
399 void emitBitTestCase(SwitchCG::BitTestBlock &BB, MachineBasicBlock *NextMBB,
400 BranchProbability BranchProbToNext, Register Reg,
401 SwitchCG::BitTestCase &B, MachineBasicBlock *SwitchBB);
402
404 const SwitchCG::SwitchWorkListItem &W, Value *Cond,
405 MachineBasicBlock *SwitchMBB, MachineIRBuilder &MIB);
406
407 bool lowerJumpTableWorkItem(
408 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
409 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
412 MachineBasicBlock *Fallthrough, bool FallthroughUnreachable);
413
415 MachineBasicBlock *Fallthrough,
416 bool FallthroughUnreachable,
417 BranchProbability UnhandledProbs,
418 MachineBasicBlock *CurMBB,
419 MachineIRBuilder &MIB,
420 MachineBasicBlock *SwitchMBB);
421
422 bool lowerBitTestWorkItem(
423 SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
424 MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
426 BranchProbability DefaultProb, BranchProbability UnhandledProbs,
428 bool FallthroughUnreachable);
429
430 bool lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W, Value *Cond,
431 MachineBasicBlock *SwitchMBB,
432 MachineBasicBlock *DefaultMBB,
433 MachineIRBuilder &MIB);
434
435 bool translateSwitch(const User &U, MachineIRBuilder &MIRBuilder);
436
437
438 bool translateIndirectBr(const User &U, MachineIRBuilder &MIRBuilder);
439
440 bool translateExtractValue(const User &U, MachineIRBuilder &MIRBuilder);
441
442 bool translateInsertValue(const User &U, MachineIRBuilder &MIRBuilder);
443
444 bool translateSelect(const User &U, MachineIRBuilder &MIRBuilder);
445
446 bool translateGetElementPtr(const User &U, MachineIRBuilder &MIRBuilder);
447
448 bool translateAlloca(const User &U, MachineIRBuilder &MIRBuilder);
449
450
451
452
453
454 bool translateRet(const User &U, MachineIRBuilder &MIRBuilder);
455
456 bool translateFNeg(const User &U, MachineIRBuilder &MIRBuilder);
457
458 bool translateAdd(const User &U, MachineIRBuilder &MIRBuilder) {
459 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
460 }
461 bool translateSub(const User &U, MachineIRBuilder &MIRBuilder) {
462 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
463 }
464 bool translateAnd(const User &U, MachineIRBuilder &MIRBuilder) {
465 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
466 }
467 bool translateMul(const User &U, MachineIRBuilder &MIRBuilder) {
468 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
469 }
470 bool translateOr(const User &U, MachineIRBuilder &MIRBuilder) {
471 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
472 }
473 bool translateXor(const User &U, MachineIRBuilder &MIRBuilder) {
474 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
475 }
476
477 bool translateUDiv(const User &U, MachineIRBuilder &MIRBuilder) {
478 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
479 }
480 bool translateSDiv(const User &U, MachineIRBuilder &MIRBuilder) {
481 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
482 }
483 bool translateURem(const User &U, MachineIRBuilder &MIRBuilder) {
484 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
485 }
486 bool translateSRem(const User &U, MachineIRBuilder &MIRBuilder) {
487 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
488 }
489 bool translateIntToPtr(const User &U, MachineIRBuilder &MIRBuilder) {
490 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
491 }
492 bool translatePtrToInt(const User &U, MachineIRBuilder &MIRBuilder) {
493 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
494 }
495 bool translatePtrToAddr(const User &U, MachineIRBuilder &MIRBuilder) {
496
497 return translatePtrToInt(U, MIRBuilder);
498 }
499 bool translateTrunc(const User &U, MachineIRBuilder &MIRBuilder) {
500 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
501 }
502 bool translateFPTrunc(const User &U, MachineIRBuilder &MIRBuilder) {
503 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
504 }
505 bool translateFPExt(const User &U, MachineIRBuilder &MIRBuilder) {
506 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
507 }
508 bool translateFPToUI(const User &U, MachineIRBuilder &MIRBuilder) {
509 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
510 }
511 bool translateFPToSI(const User &U, MachineIRBuilder &MIRBuilder) {
512 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
513 }
514 bool translateUIToFP(const User &U, MachineIRBuilder &MIRBuilder) {
515 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
516 }
517 bool translateSIToFP(const User &U, MachineIRBuilder &MIRBuilder) {
518 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
519 }
520 bool translateUnreachable(const User &U, MachineIRBuilder &MIRBuilder);
521
522 bool translateSExt(const User &U, MachineIRBuilder &MIRBuilder) {
523 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
524 }
525
526 bool translateZExt(const User &U, MachineIRBuilder &MIRBuilder) {
527 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
528 }
529
530 bool translateShl(const User &U, MachineIRBuilder &MIRBuilder) {
531 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
532 }
533 bool translateLShr(const User &U, MachineIRBuilder &MIRBuilder) {
534 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
535 }
536 bool translateAShr(const User &U, MachineIRBuilder &MIRBuilder) {
537 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
538 }
539
540 bool translateFAdd(const User &U, MachineIRBuilder &MIRBuilder) {
541 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
542 }
543 bool translateFSub(const User &U, MachineIRBuilder &MIRBuilder) {
544 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
545 }
546 bool translateFMul(const User &U, MachineIRBuilder &MIRBuilder) {
547 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
548 }
549 bool translateFDiv(const User &U, MachineIRBuilder &MIRBuilder) {
550 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
551 }
552 bool translateFRem(const User &U, MachineIRBuilder &MIRBuilder) {
553 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
554 }
555
556 bool translateVAArg(const User &U, MachineIRBuilder &MIRBuilder);
557
558 bool translateInsertElement(const User &U, MachineIRBuilder &MIRBuilder);
559 bool translateInsertVector(const User &U, MachineIRBuilder &MIRBuilder);
560
561 bool translateExtractElement(const User &U, MachineIRBuilder &MIRBuilder);
562 bool translateExtractVector(const User &U, MachineIRBuilder &MIRBuilder);
563
564 bool translateShuffleVector(const User &U, MachineIRBuilder &MIRBuilder);
565
566 bool translateAtomicCmpXchg(const User &U, MachineIRBuilder &MIRBuilder);
567 bool translateAtomicRMW(const User &U, MachineIRBuilder &MIRBuilder);
568 bool translateFence(const User &U, MachineIRBuilder &MIRBuilder);
569 bool translateFreeze(const User &U, MachineIRBuilder &MIRBuilder);
570
571
572
573 bool translateResume(const User &U, MachineIRBuilder &MIRBuilder) {
574 return false;
575 }
576 bool translateCleanupRet(const User &U, MachineIRBuilder &MIRBuilder) {
577 return false;
578 }
579 bool translateCatchRet(const User &U, MachineIRBuilder &MIRBuilder) {
580 return false;
581 }
582 bool translateCatchSwitch(const User &U, MachineIRBuilder &MIRBuilder) {
583 return false;
584 }
585 bool translateAddrSpaceCast(const User &U, MachineIRBuilder &MIRBuilder) {
586 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
587 }
588 bool translateCleanupPad(const User &U, MachineIRBuilder &MIRBuilder) {
589 return false;
590 }
591 bool translateCatchPad(const User &U, MachineIRBuilder &MIRBuilder) {
592 return false;
593 }
594 bool translateUserOp1(const User &U, MachineIRBuilder &MIRBuilder) {
595 return false;
596 }
597 bool translateUserOp2(const User &U, MachineIRBuilder &MIRBuilder) {
598 return false;
599 }
600
601 bool translateConvergenceControlIntrinsic(const CallInst &CI,
603 MachineIRBuilder &MIRBuilder);
604
605
606
607
608
609
610
611
612 std::unique_ptr CurBuilder;
613
614
615
616
617 std::unique_ptr EntryBuilder;
618
619
620 MachineFunction *MF = nullptr;
621
622
623 MachineRegisterInfo *MRI = nullptr;
624
625 const DataLayout *DL = nullptr;
626
627
628 const TargetPassConfig *TPC = nullptr;
629
631
632
633 std::unique_ptr ORE;
634
635 AAResults *AA = nullptr;
636 AssumptionCache *AC = nullptr;
637 const TargetLibraryInfo *LibInfo = nullptr;
638 const TargetLowering *TLI = nullptr;
639 FunctionLoweringInfo FuncInfo;
640
641
642
643 bool EnableOpts = false;
644
645
646
647 bool HasTailCall = false;
648
649 StackProtectorDescriptor SPDescriptor;
650
651
652 class GISelSwitchLowering : public SwitchCG::SwitchLowering {
653 public:
654 GISelSwitchLowering(IRTranslator *irt, FunctionLoweringInfo &funcinfo)
656 assert(irt && "irt is null!");
657 }
658
659 void addSuccessorWithProb(
660 MachineBasicBlock *Src, MachineBasicBlock *Dst,
662 IRT->addSuccessorWithProb(Src, Dst, Prob);
663 }
664
665 ~GISelSwitchLowering() override = default;
666
667 private:
669 };
670
671 std::unique_ptr SL;
672
673
674
675
676
677 void finalizeFunction();
678
679
680
681
682 bool finalizeBasicBlock(const BasicBlock &BB, MachineBasicBlock &MBB);
683
684
685
686
687
688
689
690
691
692 bool emitSPDescriptorParent(StackProtectorDescriptor &SPD,
693 MachineBasicBlock *ParentBB);
694
695
696
697
698
699
700
701
702
703
704
705 bool emitSPDescriptorFailure(StackProtectorDescriptor &SPD,
706 MachineBasicBlock *FailureBB);
707
708
709
710
711
713
715 auto Regs = getOrCreateVRegs(Val);
716 if (Regs.empty())
717 return 0;
718 assert(Regs.size() == 1 &&
719 "attempt to get single VReg for aggregate or void");
720 return Regs[0];
721 }
722
723 Register getOrCreateConvergenceTokenVReg(const Value &Token) {
724 assert(Token.getType()->isTokenTy());
725 auto &Regs = *VMap.getVRegs(Token);
726 if (!Regs.empty()) {
727 assert(Regs.size() == 1 &&
728 "Expected a single register for convergence tokens.");
729 return Regs[0];
730 }
731
732 auto Reg = MRI->createGenericVirtualRegister(LLT::token());
733 Regs.push_back(Reg);
734 auto &Offsets = *VMap.getOffsets(Token);
737 return Reg;
738 }
739
740
741
742 ValueToVRegInfo::VRegListT &allocateVRegs(const Value &Val);
743
744
745
746 int getOrCreateFrameIndex(const AllocaInst &AI);
747
748
749
750
751 Align getMemOpAlign(const Instruction &I);
752
753
754
755
756 MachineBasicBlock &getMBB(const BasicBlock &BB);
757
758
759
760
761
762 void addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred);
763
764
765
766
767
769 auto RemappedEdge = MachinePreds.find(Edge);
770 if (RemappedEdge != MachinePreds.end())
771 return RemappedEdge->second;
772 return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*Edge.first));
773 }
774
775
776
777 BranchProbability getEdgeProbability(const MachineBasicBlock *Src,
778 const MachineBasicBlock *Dst) const;
779
780 void addSuccessorWithProb(
781 MachineBasicBlock *Src, MachineBasicBlock *Dst,
783
784public:
786
788
790
791
792
793
794
795
796
797
798
799
800
801
802
804};