LLVM: lib/CodeGen/GlobalISel/RegBankSelect.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
32#include "llvm/Config/llvm-config.h"
42#include
43#include
44#include
45#include
46#include
47#include
48
49#define DEBUG_TYPE "regbankselect"
50
51using namespace llvm;
52
56 "Run the Fast mode (default mapping)"),
57 clEnumValN(RegBankSelect::Mode::Greedy, "regbankselect-greedy",
58 "Use the Greedy mode (best local mapping)")));
59
61
63 "Assign register bank of generic virtual registers",
64 false, false);
69 "Assign register bank of generic virtual registers", false,
71
77 LLVM_DEBUG(dbgs() << "RegBankSelect mode overrided by command line\n");
78 }
79}
80
83 assert(RBI && "Cannot work without RegisterBankInfo");
86 TPC = &getAnalysis();
88 MBFI = &getAnalysis().getMBFI();
89 MBPI = &getAnalysis().getMBPI();
90 } else {
91 MBFI = nullptr;
92 MBPI = nullptr;
93 }
95 MORE = std::make_unique(MF, MBFI);
96}
97
100
101
104 }
108}
109
112 bool &OnlyAssign) const {
113
114 OnlyAssign = false;
115
116
118 return false;
119
122
123
124 OnlyAssign = CurRegBank == nullptr;
125 LLVM_DEBUG(dbgs() << "Does assignment already match: ";
126 if (CurRegBank) dbgs() << *CurRegBank; else dbgs() << "none";
127 dbgs() << " against ";
128 assert(DesiredRegBank && "The mapping must be valid");
129 dbgs() << *DesiredRegBank << '\n';);
130 return CurRegBank == DesiredRegBank;
131}
132
137
139 "need new vreg for each breakdown");
140
141
142 assert(!NewVRegs.empty() && "We should not have to repair");
143
146
147
149 Register Dst = *NewVRegs.begin();
150
151
152
155
157 "We are about to create several defs for Dst");
158
159
160
161
167 << " to: " << printReg(Dst) << ':'
169 } else {
170
171
173
175 if (MO.isDef()) {
176 unsigned MergeOp;
179 MergeOp = TargetOpcode::G_BUILD_VECTOR;
180 else {
185 0) &&
186 "don't understand this value breakdown");
187
188 MergeOp = TargetOpcode::G_CONCAT_VECTORS;
189 }
190 } else
191 MergeOp = TargetOpcode::G_MERGE_VALUES;
192
193 auto MergeBuilder =
196
197 for (Register SrcReg : NewVRegs)
198 MergeBuilder.addUse(SrcReg);
199
200 MI = MergeBuilder;
201 } else {
204 for (Register DefReg : NewVRegs)
205 UnMergeBuilder.addDef(DefReg);
206
208 MI = UnMergeBuilder;
209 }
210 }
211
213 report_fatal_error("need testcase to support multiple insertion points");
214
215
216
217
218 std::unique_ptr<MachineInstr *[]> NewInstrs(
220 bool IsFirst = true;
221 unsigned Idx = 0;
222 for (const std::unique_ptr &InsertPt : RepairPt) {
224 if (IsFirst)
225 CurMI = MI;
226 else
228 InsertPt->insert(*CurMI);
229 NewInstrs[Idx++] = CurMI;
230 IsFirst = false;
231 }
232
233
234 return true;
235}
236
240 assert(MO.isReg() && "We should only repair register operand");
242
243 bool IsSameNumOfValues = ValMapping.NumBreakDowns == 1;
245
246
248
249
250
251
252
253
254
255
256
257
258
261
262 if (IsSameNumOfValues) {
264
265
267 std::swap(CurRegBank, DesiredRegBank);
268
269
270
271
272
273
274
275
276
277
278
279 unsigned Cost = RBI->copyCost(*DesiredRegBank, *CurRegBank,
281
282 if (Cost != std::numeric_limits::max())
284
285 }
286 return std::numeric_limits::max();
287}
288
293 "Do not know how to map this instruction");
294
299 PossibleMappings) {
302 if (CurCost < Cost) {
303 LLVM_DEBUG(dbgs() << "New best: " << CurCost << '\n');
304 Cost = CurCost;
305 BestMapping = CurMapping;
306 RepairPts.clear();
309 }
310 }
312
313
314
315 BestMapping = *PossibleMappings.begin();
318 } else
319 assert(BestMapping && "No suitable mapping for instruction");
320 return *BestMapping;
321}
322
327 assert(RepairPt.hasSplit() && "We should not have to adjust for split");
328
329
330 assert((MI.isPHI() || MI.isTerminator()) && "Why do we split?");
331
333 "Repairing placement does not match operand");
334
335
336
337
338
339 assert((.isPHI() || !MO.isDef()) && "Need split for phi def?");
340
341
342 if (!MO.isDef()) {
343 if (MI.isTerminator()) {
344 assert(&MI != &(*MI.getParent()->getFirstTerminator()) &&
345 "Need to split for the first terminator?!");
346 } else {
347
348
349
351
353 }
354 return;
355 }
356
357
358
359
360
361
362
363
364
365
367 "This code is for the def of a terminator");
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
402 if (Reg.isPhysical()) {
403
404
405
406
407
408
409
410
411
412
413
414 assert(&MI == &(*MI.getParent()->getFirstTerminator()) &&
415 "Do not know which outgoing edges are relevant");
418 "Do not know where each terminator ends up");
419 if (Next)
420
421
422
424 "Need to split between terminators");
425
426 } else {
427
429
430
431
432
433 assert(false && "Repairing cost may not be accurate");
434 } else {
435
436
437
439 }
440 }
441}
442
447 assert((MBFI || !BestCost) && "Costs comparison require MBFI");
448
449 if (!InstrMapping.isValid())
451
452
455 bool Saturated = Cost.addLocalCost(InstrMapping.getCost());
456 assert(!Saturated && "Possible mapping saturated the cost");
458 LLVM_DEBUG(dbgs() << "With: " << InstrMapping << '\n');
459 RepairPts.clear();
460 if (BestCost && Cost > *BestCost) {
461 LLVM_DEBUG(dbgs() << "Mapping is too expensive from the start\n");
463 }
465
466
467
468
469
470 for (unsigned OpIdx = 0, EndOpIdx = InstrMapping.getNumOperands();
471 OpIdx != EndOpIdx; ++OpIdx) {
474 continue;
476 if (!Reg)
477 continue;
480 continue;
481
484 InstrMapping.getOperandMapping(OpIdx);
485
486 bool Assign;
489 continue;
490 }
491 if (Assign) {
492 LLVM_DEBUG(dbgs() << "=> is free (simple assignment).\n");
495 continue;
496 }
497
498
502
503
504
505
508
509
511 LLVM_DEBUG(dbgs() << "Mapping involves impossible repairing\n");
513 }
514
515
516
517 if (!BestCost || Saturated)
518 continue;
519
520
521
522 assert(MBFI && MBPI && "Cost computation requires MBFI and MBPI");
523
524
525
526
527
528
529
530
531
532
533
535
536
537 if (RepairCost == std::numeric_limits::max())
539
540
541 const uint64_t PercentageForBias = 5;
542 uint64_t Bias = (RepairCost * PercentageForBias + 99) / 100;
543
544
545
546
547 assert(((RepairCost < RepairCost * PercentageForBias) &&
548 (RepairCost * PercentageForBias <
549 RepairCost * PercentageForBias + 99)) &&
550 "Repairing involves more than a billion of instructions?!");
551 for (const std::unique_ptr &InsertPt : RepairPt) {
552 assert(InsertPt->canMaterialize() && "We should not have made it here");
553
554 if (!InsertPt->isSplit())
555 Saturated = Cost.addLocalCost(RepairCost);
556 else {
557 uint64_t CostForInsertPt = RepairCost;
558
559
560 assert(CostForInsertPt + Bias > CostForInsertPt &&
561 "Repairing + split bias overflows");
562 CostForInsertPt += Bias;
563 uint64_t PtCost = InsertPt->frequency(*this) * CostForInsertPt;
564
565 if ((Saturated = PtCost < CostForInsertPt))
566 Cost.saturate();
567 else
568 Saturated = Cost.addNonLocalCost(PtCost);
569 }
570
571
572
573 if (BestCost && Cost > *BestCost) {
574 LLVM_DEBUG(dbgs() << "Mapping is too expensive, stop processing\n");
576 }
577
578
579
580 if (Saturated)
581 break;
582 }
583 }
586}
587
591
593
594
596 if (!RepairPt.canMaterialize() ||
598 return false;
600 "This should not make its way in the list");
601 unsigned OpIdx = RepairPt.getOpIdx();
604 InstrMapping.getOperandMapping(OpIdx);
606
607 switch (RepairPt.getKind()) {
610 "Reassignment should only be for simple mapping");
612 break;
614
615 if (MI.isDebugInstr())
616 break;
618 if ((MO, ValMapping, RepairPt, OpdMapper.getVRegs(OpIdx)))
619 return false;
620 break;
621 default:
623 }
624 }
625
626
627 LLVM_DEBUG(dbgs() << "Actual mapping of the operands: " << OpdMapper << '\n');
629
630 return true;
631}
632
635
636 unsigned Opc = MI.getOpcode();
638 assert((Opc == TargetOpcode::G_ASSERT_ZEXT ||
639 Opc == TargetOpcode::G_ASSERT_SEXT ||
640 Opc == TargetOpcode::G_ASSERT_ALIGN) &&
641 "Unexpected hint opcode!");
642
643
646
647
648 assert(RB && "Expected source register to have a register bank?");
649 LLVM_DEBUG(dbgs() << "... Hint always uses source's register bank.\n");
651 return true;
652 }
653
654
656
661 (void)DefaultCost;
663 return false;
664 } else {
667 if (PossibleMappings.empty())
668 return false;
670 }
671
672 assert(BestMapping->verify(MI) && "Invalid instruction mapping");
673
674 LLVM_DEBUG(dbgs() << "Best Mapping: " << *BestMapping << '\n');
675
676
677
679}
680
682
683
684
687
688
692
693 while (!WorkList.empty()) {
695
696
697
699 continue;
700
701
702
703 if (MI.isInlineAsm())
704 continue;
705
706
707 if (MI.isImplicitDef())
708 continue;
709
712 "unable to map instruction", MI);
713 return false;
714 }
715 }
716 }
717
718 return true;
719}
720
722#ifndef NDEBUG
726 "instruction is not legal", *MI);
727 return false;
728 }
729 }
730#endif
731 return true;
732}
733
735
738 return false;
739
743 if (F.hasOptNone())
746
747#ifndef NDEBUG
749 return false;
750#endif
751
753
755 return false;
756}
757
758
759
760
764
765 : Kind(Kind), OpIdx(OpIdx),
766 CanMaterialize(Kind != RepairingKind::Impossible), P(P) {
768 assert(MO.isReg() && "Trying to repair a non-reg operand");
769
771 return;
772
773
775
776
777 if (.isPHI() &&
.isTerminator()) {
779
780 return;
781 }
782
783
784 if (MI.isPHI()) {
785
786
787
790 if (It != MI.getParent()->end())
792 else
794 return;
795 }
796
798
799
802 for (auto Begin = Pred.begin(); It != Begin && It->isTerminator(); --It)
803 if (It->modifiesRegister(Reg, &TRI)) {
804
805
807 return;
808 }
809
810
811
812
813
814 if (It == Pred.end())
816 else
818 } else {
819
820
821
823
825 auto REnd = MI.getParent()->rend();
826
827 for (; It != REnd && It->isTerminator(); ++It) {
829 "copy insertion in middle of terminators not handled");
830 }
831
832 if (It == REnd) {
834 return;
835 }
836
837
839 return;
840 }
841
842
844 ++It != End;)
845
847 "Do not know where to split");
848
850 for (auto &Succ : Src.successors())
852 }
853}
854
858}
859
861 bool Beginning) {
863}
864
868}
869
873 HasSplit |= Point.isSplit();
874 InsertPoints.emplace_back(&Point);
875}
876
880
881
883 "Splitting before phis requires more points");
884 assert(( || !Instr.getNextNode() || !Instr.getNextNode()->isPHI()) &&
885 "Splitting between phis does not make sense");
886}
887
888void RegBankSelect::InstrInsertPoint::materialize() {
889 if (isSplit()) {
890
891
892
893
894
895
896
897
898
899
900
901
902
904 }
905
906
907
908}
909
911
913 return Instr.isTerminator();
914
915
916 return Instr.getPrevNode() && Instr.getPrevNode()->isTerminator();
917}
918
920
921
925 return 1;
927}
928
933 return 1;
935}
936
937void RegBankSelect::EdgeInsertPoint::materialize() {
938
939
940
941
942 assert(Src.isSuccessor(DstOrSplit) && DstOrSplit->isPredecessor(&Src) &&
943 "This point has already been split");
945 assert(NewBB && "Invalid call to materialize");
946
947 DstOrSplit = NewBB;
948}
949
954 return 1;
956 if (WasMaterialized)
958
959 auto *MBPIWrapper =
962 MBPIWrapper ? &MBPIWrapper->getMBPI() : nullptr;
964 return 1;
965
967 .getFrequency();
968}
969
971
972
973
974 assert(Src.succ_size() > 1 && DstOrSplit->pred_size() > 1 &&
975 "Edge is not critical");
976 return Src.canSplitCriticalEdge(DstOrSplit);
977}
978
980 : LocalFreq(LocalFreq.getFrequency()) {}
981
983
984 if (LocalCost + Cost < LocalCost) {
985 saturate();
986 return true;
987 }
988 LocalCost += Cost;
989 return isSaturated();
990}
991
993
994 if (NonLocalCost + Cost < NonLocalCost) {
995 saturate();
996 return true;
997 }
998 NonLocalCost += Cost;
999 return isSaturated();
1000}
1001
1002bool RegBankSelect::MappingCost::isSaturated() const {
1005}
1006
1008 *this = ImpossibleCost();
1009 --LocalCost;
1010}
1011
1014}
1015
1017
1018 if (*this == Cost)
1019 return false;
1020
1021
1022 if ((*this == ImpossibleCost()) || (Cost == ImpossibleCost()))
1023 return (*this == ImpossibleCost()) < (Cost == ImpossibleCost());
1024
1025
1026 if (isSaturated() || Cost.isSaturated())
1027 return isSaturated() < Cost.isSaturated();
1028
1029
1030
1031
1032
1033
1037
1038
1039
1040 if (NonLocalCost == Cost.NonLocalCost)
1041
1042
1043 return LocalCost < Cost.LocalCost;
1044
1045
1046
1047 ThisLocalAdjust = 0;
1048 OtherLocalAdjust = 0;
1049 if (LocalCost < Cost.LocalCost)
1050 OtherLocalAdjust = Cost.LocalCost - LocalCost;
1051 else
1052 ThisLocalAdjust = LocalCost - Cost.LocalCost;
1053 } else {
1054 ThisLocalAdjust = LocalCost;
1055 OtherLocalAdjust = Cost.LocalCost;
1056 }
1057
1058
1059 uint64_t ThisNonLocalAdjust = 0;
1060 uint64_t OtherNonLocalAdjust = 0;
1061 if (NonLocalCost < Cost.NonLocalCost)
1062 OtherNonLocalAdjust = Cost.NonLocalCost - NonLocalCost;
1063 else
1064 ThisNonLocalAdjust = NonLocalCost - Cost.NonLocalCost;
1065
1066 uint64_t ThisScaledCost = ThisLocalAdjust * LocalFreq;
1067
1068 bool ThisOverflows = ThisLocalAdjust && (ThisScaledCost < ThisLocalAdjust ||
1069 ThisScaledCost < LocalFreq);
1070 uint64_t OtherScaledCost = OtherLocalAdjust * Cost.LocalFreq;
1071
1072 bool OtherOverflows =
1073 OtherLocalAdjust &&
1074 (OtherScaledCost < OtherLocalAdjust || OtherScaledCost < Cost.LocalFreq);
1075
1076 ThisOverflows |= ThisNonLocalAdjust &&
1077 ThisScaledCost + ThisNonLocalAdjust < ThisNonLocalAdjust;
1078 ThisScaledCost += ThisNonLocalAdjust;
1079 OtherOverflows |= OtherNonLocalAdjust &&
1080 OtherScaledCost + OtherNonLocalAdjust < OtherNonLocalAdjust;
1081 OtherScaledCost += OtherNonLocalAdjust;
1082
1083
1084 if (ThisOverflows && OtherOverflows)
1085 return false;
1086
1087 if (ThisOverflows || OtherOverflows)
1088 return ThisOverflows < OtherOverflows;
1089
1090 return ThisScaledCost < OtherScaledCost;
1091}
1092
1094 return LocalCost == Cost.LocalCost && NonLocalCost == Cost.NonLocalCost &&
1095 LocalFreq == Cost.LocalFreq;
1096}
1097
1098#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1101 dbgs() << '\n';
1102}
1103#endif
1104
1106 if (*this == ImpossibleCost()) {
1107 OS << "impossible";
1108 return;
1109 }
1110 if (isSaturated()) {
1111 OS << "saturated";
1112 return;
1113 }
1114 OS << LocalFreq << " * " << LocalCost << " + " << NonLocalCost;
1115}
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
#define LLVM_LIKELY(EXPR)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Interface for Targets to specify which operations they can successfully select and how the others sho...
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
static cl::opt< RegBankSelect::Mode > RegBankSelectMode(cl::desc("Mode of the RegBankSelect pass"), cl::Hidden, cl::Optional, cl::values(clEnumValN(RegBankSelect::Mode::Fast, "regbankselect-fast", "Run the Fast mode (default mapping)"), clEnumValN(RegBankSelect::Mode::Greedy, "regbankselect-greedy", "Use the Greedy mode (best local mapping)")))
This file describes the interface of the MachineFunctionPass responsible for assigning the generic vi...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
Target-Independent Code Generator Pass Configuration Options pass.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
uint64_t getFrequency() const
Returns the frequency as a fixpoint number scaled by the entry frequency.
constexpr unsigned getScalarSizeInBits() const
constexpr bool isValid() const
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isVector() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
const MachineBlockFrequencyInfo & getMBFI() const
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const
getblockFreq - Return block frequency.
BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
bool hasProperty(Property P) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineFunctionProperties & getProperties() const
Get the function properties.
MachineInstr * CloneMachineInstr(const MachineInstr *Orig)
Create a new MachineInstr which is a copy of Orig, identical in all ways except the instruction has n...
MachineFunction & getMF()
Getter for the function we currently build.
void setMBB(MachineBasicBlock &MBB)
Set the insertion point to the end of MBB.
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert = Opcode .
void setMF(MachineFunction &MF)
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
bool readsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr reads the specified register.
void insert(mop_iterator InsertBefore, ArrayRef< MachineOperand > Ops)
Inserts Ops BEFORE It. Can untie/retie tied operands.
bool isUnconditionalBranch(QueryType Type=AnyInBundle) const
Return true if this is a branch which always transfers control flow to some other block.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
void setRegBank(Register Reg, const RegisterBank &RegBank)
Set the register bank to RegBank for Reg.
Pass interface - Implemented by all 'passes'.
Insertion point on an edge.
uint64_t frequency(const Pass &P) const override
Frequency of the insertion point.
bool canMaterialize() const override
Check whether this insertion point can be materialized.
Abstract class used to represent an insertion point in a CFG.
virtual bool canMaterialize() const
Check whether this insertion point can be materialized.
virtual bool isSplit() const
Does this point involve splitting an edge or block? As soon as getPoint is called and thus,...
Insertion point before or after an instruction.
InstrInsertPoint(MachineInstr &Instr, bool Before=true)
Create an insertion point before (Before=true) or after Instr.
bool isSplit() const override
Does this point involve splitting an edge or block? As soon as getPoint is called and thus,...
uint64_t frequency(const Pass &P) const override
Frequency of the insertion point.
Insertion point at the beginning or end of a basic block.
uint64_t frequency(const Pass &P) const override
Frequency of the insertion point.
Helper class used to represent the cost for mapping an instruction.
void saturate()
Saturate the cost to the maximal representable value.
bool operator==(const MappingCost &Cost) const
Check if this is equal to Cost.
bool addLocalCost(uint64_t Cost)
Add Cost to the local cost.
void dump() const
Print this on dbgs() stream.
static MappingCost ImpossibleCost()
Return an instance of MappingCost that represents an impossible mapping.
bool addNonLocalCost(uint64_t Cost)
Add Cost to the non-local cost.
bool operator<(const MappingCost &Cost) const
Check if this is less than Cost.
void print(raw_ostream &OS) const
Print this on OS;.
Struct used to represent the placement of a repairing point for a given operand.
unsigned getNumInsertPoints() const
bool canMaterialize() const
RepairingPlacement(MachineInstr &MI, unsigned OpIdx, const TargetRegisterInfo &TRI, Pass &P, RepairingKind Kind=RepairingKind::Insert)
Create a repairing placement for the OpIdx-th operand of MI.
unsigned getOpIdx() const
RepairingKind
Define the kind of action this repairing needs.
@ Insert
Reparing code needs to happen before InsertPoints.
@ None
Nothing to repair, just drop this action.
@ Reassign
(Re)assign the register bank of the operand.
@ Impossible
Mark this repairing placement as impossible.
void switchTo(RepairingKind NewKind)
Change the type of this repairing placement to NewKind.
void addInsertPoint(MachineBasicBlock &MBB, bool Beginning)
This pass implements the reg bank selector pass used in the GlobalISel pipeline.
Mode
List of the modes supported by the RegBankSelect pass.
@ Fast
Assign the register banks as fast as possible (default).
bool checkFunctionIsLegal(MachineFunction &MF) const
Check that our input is fully legal: we require the function to have the Legalized property,...
MachineIRBuilder MIRBuilder
Helper class used for every code morphing.
MachineBlockFrequencyInfo * MBFI
Get the frequency of blocks.
Mode OptMode
Optimization mode of the pass.
const RegisterBankInfo::InstructionMapping & findBestMapping(MachineInstr &MI, RegisterBankInfo::InstructionMappings &PossibleMappings, SmallVectorImpl< RepairingPlacement > &RepairPts)
Find the best mapping for MI from PossibleMappings.
bool assignInstr(MachineInstr &MI)
Assign the register bank of each operand of MI.
bool assignRegisterBanks(MachineFunction &MF)
Walk through MF and assign a register bank to every virtual register that are still mapped to nothing...
void init(MachineFunction &MF)
Initialize the field members using MF.
void tryAvoidingSplit(RegBankSelect::RepairingPlacement &RepairPt, const MachineOperand &MO, const RegisterBankInfo::ValueMapping &ValMapping) const
When RepairPt involves splitting to repair MO for the given ValMapping, try to change the way we repa...
const TargetRegisterInfo * TRI
Information on the register classes for the current function.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
MachineBranchProbabilityInfo * MBPI
Get the frequency of the edges.
bool assignmentMatch(Register Reg, const RegisterBankInfo::ValueMapping &ValMapping, bool &OnlyAssign) const
Check if Reg is already assigned what is described by ValMapping.
uint64_t getRepairCost(const MachineOperand &MO, const RegisterBankInfo::ValueMapping &ValMapping) const
Return the cost of the instruction needed to map MO to ValMapping.
MappingCost computeMapping(MachineInstr &MI, const RegisterBankInfo::InstructionMapping &InstrMapping, SmallVectorImpl< RepairingPlacement > &RepairPts, const MappingCost *BestCost=nullptr)
Compute the cost of mapping MI with InstrMapping and compute the repairing placement for such mapping...
bool repairReg(MachineOperand &MO, const RegisterBankInfo::ValueMapping &ValMapping, RegBankSelect::RepairingPlacement &RepairPt, const iterator_range< SmallVectorImpl< Register >::const_iterator > &NewVRegs)
Insert repairing code for Reg as specified by ValMapping.
MachineRegisterInfo * MRI
MRI contains all the register class/bank information that this pass uses and updates.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetPassConfig * TPC
Current target configuration. Controls how the pass handles errors.
const RegisterBankInfo * RBI
Interface to the target lowering info related to register banks.
std::unique_ptr< MachineOptimizationRemarkEmitter > MORE
Current optimization remark emitter. Used to report failures.
bool applyMapping(MachineInstr &MI, const RegisterBankInfo::InstructionMapping &InstrMapping, SmallVectorImpl< RepairingPlacement > &RepairPts)
Apply Mapping to MI.
Helper class that represents how the value of an instruction may be mapped and what is the related co...
unsigned getNumOperands() const
Get the number of operands.
unsigned getCost() const
Get the cost.
bool verify(const MachineInstr &MI) const
Verifiy that this mapping makes sense for MI.
bool isValid() const
Check whether this object is valid.
Helper class used to get/create the virtual registers that will be used to replace the MachineOperand...
void createVRegs(unsigned OpIdx)
Create as many new virtual registers as needed for the mapping of the OpIdx-th operand.
iterator_range< SmallVectorImpl< Register >::const_iterator > getVRegs(unsigned OpIdx, bool ForDebug=false) const
Get all the virtual registers required to map the OpIdx-th operand of the instruction.
void applyMapping(MachineIRBuilder &Builder, const OperandsMapper &OpdMapper) const
Apply OpdMapper.getInstrMapping() to OpdMapper.getMI().
virtual const InstructionMapping & getInstrMapping(const MachineInstr &MI) const
Get the mapping of the different operands of MI on the register bank.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
TypeSize getSizeInBits(Register Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
InstructionMappings getInstrPossibleMappings(const MachineInstr &MI) const
Get the possible mapping for MI.
virtual unsigned copyCost(const RegisterBank &A, const RegisterBank &B, TypeSize Size) const
Get the cost of a copy from B to A, or put differently, get the cost of A = COPY B.
virtual unsigned getBreakDownCost(const ValueMapping &ValMapping, const RegisterBank *CurBank=nullptr) const
Get the cost of using ValMapping to decompose a register.
This class implements the register bank concept.
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
typename SuperClass::const_iterator const_iterator
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Target-Independent Code Generator Pass Configuration Options.
bool isGlobalISelAbortEnabled() const
Check whether or not GlobalISel should abort on error.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const RegisterBankInfo * getRegBankInfo() const
If the information for the register banks is available, return it.
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr)
bool isPreISelGenericOptimizationHint(unsigned Opcode)
cl::opt< bool > DisableGISelLegalityCheck
auto reverse(ContainerTy &&C)
void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Report an ISel error as a missed optimization remark to the LLVMContext's diagnostic stream.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Printable printRegClassOrBank(Register Reg, const MachineRegisterInfo &RegInfo, const TargetRegisterInfo *TRI)
Create Printable object to print register classes or register banks on a raw_ostream.
const MachineInstr * machineFunctionIsIllegal(const MachineFunction &MF)
Checks that MIR is fully legal, returns an illegal instruction if it's not, nullptr otherwise.
void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
bool isTargetSpecificOpcode(unsigned Opcode)
Check whether the given Opcode is a target-specific opcode.
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
const RegisterBank * RegBank
Register bank where the partial value lives.
unsigned Length
Length of this mapping in bits.
Helper struct that represents how a value is mapped through different register banks.
bool partsAllUniform() const
unsigned NumBreakDowns
Number of partial mapping to break down this value.
const PartialMapping * BreakDown
How the value is broken down between the different register banks.