llvm.org GIT mirror llvm / 6e712a2
[globalisel] Initialize RegisterBanks with static data. Summary: Refactor the RegisterBank initialization to use static data. This requires GlobalISel implementations to rewrite calls to createRegisterBank() and addRegBankCoverage() into a call to setRegBankData(). Out of tree targets can use diff 4 of D27807 (https://reviews.llvm.org/D27807?id=84117) to have addRegBankCoverage() dump the register classes and other data that needs to be provided to setRegBankData(). This is the method that was used to generate the static data in this patch. Tablegen-eration of this static data will follow after some refactoring. Reviewers: t.p.northover, ab, rovka, qcolombet Subscribers: aditya_nandakumar, kristof.beyls, vkalintiris, llvm-commits, dberris Differential Revision: https://reviews.llvm.org/D27807 Differential Revision: https://reviews.llvm.org/D27808 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@291768 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Sanders 3 years ago
6 changed file(s) with 164 addition(s) and 142 deletion(s). Raw diff Collapse all Expand all
383383
384384 /// Create a RegisterBankInfo that can accomodate up to \p NumRegBanks
385385 /// RegisterBank instances.
386 ///
387 /// \note For the verify method to succeed all the \p NumRegBanks
388 /// must be initialized by createRegisterBank and updated with
389 /// addRegBankCoverage RegisterBank.
390386 RegisterBankInfo(RegisterBank **RegBanks, unsigned NumRegBanks);
391387
392388 /// This constructor is meaningless.
399395 llvm_unreachable("This constructor should not be executed");
400396 }
401397
402 /// Create a new register bank with the given parameter and add it
403 /// to RegBanks.
404 /// \pre \p ID must not already be used.
405 /// \pre \p ID < NumRegBanks.
406 void createRegisterBank(unsigned ID, const char *Name);
407
408 /// Add \p RCId to the set of register class that the register bank,
409 /// identified \p ID, covers.
410 /// This method transitively adds all the sub classes and the subreg-classes
411 /// of \p RCId to the set of covered register classes.
412 /// It also adjusts the size of the register bank to reflect the maximal
413 /// size of a value that can be hold into that register bank.
414 ///
415 /// \note This method does *not* add the super classes of \p RCId.
416 /// The rationale is if \p ID covers the registers of \p RCId, that
417 /// does not necessarily mean that \p ID covers the set of registers
418 /// of RCId's superclasses.
419 /// This method does *not* add the superreg classes as well for consistents.
420 /// The expected use is to add the coverage top-down with respect to the
421 /// register hierarchy.
422 ///
423 /// \todo TableGen should just generate the BitSet vector for us.
424 void addRegBankCoverage(unsigned ID, unsigned RCId,
425 const TargetRegisterInfo &TRI);
398 void setRegBankData(unsigned ID, const char *Name, unsigned Size,
399 const uint32_t *CoveredClasses);
426400
427401 /// Get the register bank identified by \p ID.
428402 RegisterBank &getRegBank(unsigned ID) {
2222
2323 bool RegisterBank::verify(const TargetRegisterInfo &TRI) const {
2424 assert(isValid() && "Invalid register bank");
25 assert(ContainedRegClasses.size() == TRI.getNumRegClasses() &&
26 "TRI does not match the initialization process?");
2725 for (unsigned RCId = 0, End = TRI.getNumRegClasses(); RCId != End; ++RCId) {
2826 const TargetRegisterClass &RC = *TRI.getRegClass(RCId);
2927
8080 return true;
8181 }
8282
83 void RegisterBankInfo::createRegisterBank(unsigned ID, const char *Name) {
84 DEBUG(dbgs() << "Create register bank: " << ID << " with name \"" << Name
85 << "\"\n");
86 RegisterBank &RegBank = getRegBank(ID);
87 assert(RegBank.getID() == RegisterBank::InvalidID &&
88 "A register bank should be created only once");
89 RegBank.ID = ID;
90 RegBank.Name = Name;
91 }
92
93 void RegisterBankInfo::addRegBankCoverage(unsigned ID, unsigned RCId,
94 const TargetRegisterInfo &TRI) {
83 void RegisterBankInfo::setRegBankData(unsigned ID, const char *Name,
84 unsigned Size,
85 const uint32_t *CoveredClasses) {
9586 RegisterBank &RB = getRegBank(ID);
96 unsigned NbOfRegClasses = TRI.getNumRegClasses();
97
98 DEBUG(dbgs() << "Add coverage for: " << RB << '\n');
99
100 // Check if RB is underconstruction.
101 if (!RB.isValid())
102 RB.ContainedRegClasses.resize(NbOfRegClasses);
103 else if (RB.covers(*TRI.getRegClass(RCId)))
104 // If RB already covers this register class, there is nothing
105 // to do.
106 return;
107
108 BitVector &Covered = RB.ContainedRegClasses;
109 SmallVector WorkList;
110
111 WorkList.push_back(RCId);
112 Covered.set(RCId);
113
114 unsigned &MaxSize = RB.Size;
115 do {
116 unsigned RCId = WorkList.pop_back_val();
117
118 const TargetRegisterClass &CurRC = *TRI.getRegClass(RCId);
119
120 DEBUG(dbgs() << "Examine: " << TRI.getRegClassName(&CurRC)
121 << "(Size*8: " << (CurRC.getSize() * 8) << ")\n");
122
123 // Remember the biggest size in bits.
124 MaxSize = std::max(MaxSize, CurRC.getSize() * 8);
125
126 // Walk through all sub register classes and push them into the worklist.
127 bool First = true;
128 for (BitMaskClassIterator It(CurRC.getSubClassMask(), TRI); It.isValid();
129 ++It) {
130 unsigned SubRCId = It.getID();
131 if (!Covered.test(SubRCId)) {
132 if (First)
133 DEBUG(dbgs() << " Enqueue sub-class: ");
134 DEBUG(dbgs() << TRI.getRegClassName(TRI.getRegClass(SubRCId)) << ", ");
135 WorkList.push_back(SubRCId);
136 // Remember that we saw the sub class.
137 Covered.set(SubRCId);
138 First = false;
139 }
140 }
141 if (!First)
142 DEBUG(dbgs() << '\n');
143
144 // Push also all the register classes that can be accessed via a
145 // subreg index, i.e., its subreg-class (which is different than
146 // its subclass).
147 //
148 // Note: It would probably be faster to go the other way around
149 // and have this method add only super classes, since this
150 // information is available in a more efficient way. However, it
151 // feels less natural for the client of this APIs plus we will
152 // TableGen the whole bitset at some point, so compile time for
153 // the initialization is not very important.
154 First = true;
155 for (unsigned SubRCId = 0; SubRCId < NbOfRegClasses; ++SubRCId) {
156 if (Covered.test(SubRCId))
157 continue;
158 bool Pushed = false;
159 const TargetRegisterClass *SubRC = TRI.getRegClass(SubRCId);
160 for (SuperRegClassIterator SuperRCIt(SubRC, &TRI); SuperRCIt.isValid();
161 ++SuperRCIt) {
162 if (Pushed)
163 break;
164 for (BitMaskClassIterator It(SuperRCIt.getMask(), TRI); It.isValid();
165 ++It) {
166 unsigned SuperRCId = It.getID();
167 if (SuperRCId == RCId) {
168 if (First)
169 DEBUG(dbgs() << " Enqueue subreg-class: ");
170 DEBUG(dbgs() << TRI.getRegClassName(SubRC) << ", ");
171 WorkList.push_back(SubRCId);
172 // Remember that we saw the sub class.
173 Covered.set(SubRCId);
174 Pushed = true;
175 First = false;
176 break;
177 }
178 }
179 }
180 }
181 if (!First)
182 DEBUG(dbgs() << '\n');
183 } while (!WorkList.empty());
87 RB.ID = ID;
88 RB.Name = Name;
89 RB.Size = Size;
90 RB.ContainedRegClasses.resize(200);
91 RB.ContainedRegClasses.setBitsInMask(CoveredClasses);
18492 }
18593
18694 const RegisterBank *
1616
1717 namespace llvm {
1818 namespace AArch64 {
19
20 const uint32_t GPRCoverageData[] = {
21 // Classes 0-31
22 (1u << AArch64::GPR32allRegClassID) | (1u << AArch64::GPR32RegClassID) |
23 (1u << AArch64::GPR32spRegClassID) |
24 (1u << AArch64::GPR32commonRegClassID) |
25 (1u << AArch64::GPR32sponlyRegClassID) |
26 (1u << AArch64::GPR64allRegClassID) | (1u << AArch64::GPR64RegClassID) |
27 (1u << AArch64::GPR64spRegClassID) |
28 (1u << AArch64::GPR64commonRegClassID) |
29 (1u << AArch64::tcGPR64RegClassID) |
30 (1u << AArch64::GPR64sponlyRegClassID),
31 // Classes 32-63
32 0,
33 // FIXME: The entries below this point can be safely removed once this is
34 // tablegenerated. It's only needed because of the hardcoded register class
35 // limit.
36 // Classes 64-96
37 0,
38 // Classes 97-128
39 0,
40 // Classes 129-160
41 0,
42 // Classes 161-192
43 0,
44 // Classes 193-224
45 0,
46 };
47
48 const uint32_t FPRCoverageData[] = {
49 // Classes 0-31
50 (1u << AArch64::FPR8RegClassID) | (1u << AArch64::FPR16RegClassID) |
51 (1u << AArch64::FPR32RegClassID) | (1u << AArch64::FPR64RegClassID) |
52 (1u << AArch64::DDRegClassID) | (1u << AArch64::FPR128RegClassID) |
53 (1u << AArch64::FPR128_loRegClassID) | (1u << AArch64::DDDRegClassID) |
54 (1u << AArch64::DDDDRegClassID),
55 // Classes 32-63
56 (1u << (AArch64::QQRegClassID - 32)) |
57 (1u << (AArch64::QQ_with_qsub0_in_FPR128_loRegClassID - 32)) |
58 (1u << (AArch64::QQ_with_qsub1_in_FPR128_loRegClassID - 32)) |
59 (1u
60 << (AArch64::
61 QQQ_with_qsub1_in_FPR128_lo_and_QQQ_with_qsub2_in_FPR128_loRegClassID -
62 32)) |
63 (1u
64 << (AArch64::
65 QQQ_with_qsub0_in_FPR128_lo_and_QQQ_with_qsub2_in_FPR128_loRegClassID -
66 32)) |
67 (1u << (AArch64::QQQQRegClassID - 32)) |
68 (1u << (AArch64::QQQQ_with_qsub0_in_FPR128_loRegClassID - 32)) |
69 (1u << (AArch64::QQQQ_with_qsub1_in_FPR128_loRegClassID - 32)) |
70 (1u << (AArch64::QQQQ_with_qsub2_in_FPR128_loRegClassID - 32)) |
71 (1u << (AArch64::QQQQ_with_qsub3_in_FPR128_loRegClassID - 32)) |
72 (1u
73 << (AArch64::
74 QQQQ_with_qsub0_in_FPR128_lo_and_QQQQ_with_qsub1_in_FPR128_loRegClassID -
75 32)) |
76 (1u
77 << (AArch64::
78 QQQQ_with_qsub1_in_FPR128_lo_and_QQQQ_with_qsub2_in_FPR128_loRegClassID -
79 32)) |
80 (1u
81 << (AArch64::
82 QQQQ_with_qsub2_in_FPR128_lo_and_QQQQ_with_qsub3_in_FPR128_loRegClassID -
83 32)) |
84 (1u
85 << (AArch64::
86 QQQQ_with_qsub0_in_FPR128_lo_and_QQQQ_with_qsub2_in_FPR128_loRegClassID -
87 32)) |
88 (1u
89 << (AArch64::
90 QQQQ_with_qsub1_in_FPR128_lo_and_QQQQ_with_qsub3_in_FPR128_loRegClassID -
91 32)) |
92 (1u
93 << (AArch64::
94 QQQQ_with_qsub0_in_FPR128_lo_and_QQQQ_with_qsub3_in_FPR128_loRegClassID -
95 32)) |
96 (1u
97 << (AArch64::
98 QQ_with_qsub0_in_FPR128_lo_and_QQ_with_qsub1_in_FPR128_loRegClassID -
99 32)) |
100 (1u << (AArch64::QQQRegClassID - 32)) |
101 (1u << (AArch64::QQQ_with_qsub0_in_FPR128_loRegClassID - 32)) |
102 (1u << (AArch64::QQQ_with_qsub1_in_FPR128_loRegClassID - 32)) |
103 (1u << (AArch64::QQQ_with_qsub2_in_FPR128_loRegClassID - 32)) |
104 (1u
105 << (AArch64::
106 QQQ_with_qsub0_in_FPR128_lo_and_QQQ_with_qsub1_in_FPR128_loRegClassID -
107 32)),
108 // FIXME: The entries below this point can be safely removed once this
109 // is tablegenerated. It's only needed because of the hardcoded register
110 // class limit.
111 // Classes 64-96
112 0,
113 // Classes 97-128
114 0,
115 // Classes 129-160
116 0,
117 // Classes 161-192
118 0,
119 // Classes 193-224
120 0,
121 };
122
123 const uint32_t CCRCoverageData[] = {
124 // Classes 0-31
125 1u << AArch64::CCRRegClassID,
126 // Classes 32-63
127 0,
128 // FIXME: The entries below this point can be safely removed once this
129 // is tablegenerated. It's only needed because of the hardcoded register
130 // class limit.
131 // Classes 64-96
132 0,
133 // Classes 97-128
134 0,
135 // Classes 129-160
136 0,
137 // Classes 161-192
138 0,
139 // Classes 193-224
140 0,
141 };
19142
20143 RegisterBank GPRRegBank;
21144 RegisterBank FPRRegBank;
4040 if (AlreadyInit)
4141 return;
4242 AlreadyInit = true;
43 // Initialize the GPR bank.
44 createRegisterBank(AArch64::GPRRegBankID, "GPR");
4543 // The GPR register bank is fully defined by all the registers in
4644 // GR64all + its subclasses.
47 addRegBankCoverage(AArch64::GPRRegBankID, AArch64::GPR64allRegClassID, TRI);
45 setRegBankData(AArch64::GPRRegBankID, "GPR", 64, AArch64::GPRCoverageData);
4846 const RegisterBank &RBGPR = getRegBank(AArch64::GPRRegBankID);
4947 (void)RBGPR;
5048 assert(&AArch64::GPRRegBank == &RBGPR &&
5351 "Subclass not added?");
5452 assert(RBGPR.getSize() == 64 && "GPRs should hold up to 64-bit");
5553
56 // Initialize the FPR bank.
57 createRegisterBank(AArch64::FPRRegBankID, "FPR");
5854 // The FPR register bank is fully defined by all the registers in
5955 // GR64all + its subclasses.
60 addRegBankCoverage(AArch64::FPRRegBankID, AArch64::QQQQRegClassID, TRI);
56 setRegBankData(AArch64::FPRRegBankID, "FPR", 512, AArch64::FPRCoverageData);
57
6158 const RegisterBank &RBFPR = getRegBank(AArch64::FPRRegBankID);
6259 (void)RBFPR;
6360 assert(&AArch64::FPRRegBank == &RBFPR &&
7067 "FPRs should hold up to 512-bit via QQQQ sequence");
7168
7269 // Initialize the CCR bank.
73 createRegisterBank(AArch64::CCRRegBankID, "CCR");
74 addRegBankCoverage(AArch64::CCRRegBankID, AArch64::CCRRegClassID, TRI);
70 setRegBankData(AArch64::CCRRegBankID, "CCR", 32, AArch64::CCRCoverageData);
7571 const RegisterBank &RBCCR = getRegBank(AArch64::CCRRegBankID);
7672 (void)RBCCR;
7773 assert(&AArch64::CCRRegBank == &RBCCR &&
2828 // into an ARMGenRegisterBankInfo.def (similar to AArch64).
2929 namespace llvm {
3030 namespace ARM {
31 const uint32_t GPRCoverageData[] = {
32 // Classes 0-31
33 (1u << ARM::GPRRegClassID) | (1u << ARM::GPRwithAPSRRegClassID) |
34 (1u << ARM::GPRnopcRegClassID) | (1u << ARM::rGPRRegClassID) |
35 (1u << ARM::hGPRRegClassID) | (1u << ARM::tGPRRegClassID) |
36 (1u << ARM::GPRnopc_and_hGPRRegClassID) |
37 (1u << ARM::hGPR_and_rGPRRegClassID) | (1u << ARM::tcGPRRegClassID) |
38 (1u << ARM::tGPR_and_tcGPRRegClassID) | (1u << ARM::GPRspRegClassID) |
39 (1u << ARM::hGPR_and_tcGPRRegClassID),
40 // Classes 32-63
41 0,
42 // Classes 64-96
43 0,
44 // FIXME: Some of the entries below this point can be safely removed once
45 // this is tablegenerated. It's only needed because of the hardcoded
46 // register class limit.
47 // Classes 97-128
48 0,
49 // Classes 129-160
50 0,
51 // Classes 161-192
52 0,
53 // Classes 193-224
54 0,
55 };
56
3157 RegisterBank GPRRegBank;
3258 RegisterBank *RegBanks[] = {&GPRRegBank};
3359
5177 AlreadyInit = true;
5278
5379 // Initialize the GPR bank.
54 createRegisterBank(ARM::GPRRegBankID, "GPRB");
55
56 addRegBankCoverage(ARM::GPRRegBankID, ARM::GPRRegClassID, TRI);
57 addRegBankCoverage(ARM::GPRRegBankID, ARM::GPRwithAPSRRegClassID, TRI);
80 setRegBankData(ARM::GPRRegBankID, "GPRB", 32, ARM::GPRCoverageData);
5881 const RegisterBank &RBGPR = getRegBank(ARM::GPRRegBankID);
5982 (void)RBGPR;
6083 assert(&ARM::GPRRegBank == &RBGPR && "The order in RegBanks is messed up");