llvm.org GIT mirror llvm / 7d4a3d4
Re-commit: [globalisel] Tablegen-erate current Register Bank Information Summary: Adds a RegisterBank tablegen class that can be used to declare the register banks and an associated tablegen pass to generate the necessary code. Changes since last commit: The new tablegen pass is now correctly guarded by LLVM_BUILD_GLOBAL_ISEL and this should fix the buildbots however it may not be the whole fix. The previous buildbot failures suggest there may be a memory bug lurking that I'm unable to reproduce (including when using asan) or spot in the source. If they re-occur on this commit then I'll need assistance from the bot owners to track it down. Reviewers: t.p.northover, ab, rovka, qcolombet Reviewed By: qcolombet Subscribers: aditya_nandakumar, rengolin, kristof.beyls, vkalintiris, mgorny, dberris, llvm-commits, rovka Differential Revision: https://reviews.llvm.org/D27338 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292367 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Sanders 2 years ago
16 changed file(s) with 449 addition(s) and 205 deletion(s). Raw diff Collapse all Expand all
4141
4242 public:
4343 RegisterBank(unsigned ID, const char *Name, unsigned Size,
44 const uint32_t *ContainedRegClasses);
44 const uint32_t *ContainedRegClasses, unsigned NumRegClasses);
4545
4646 /// Get the identifier of this register bank.
4747 unsigned getID() const { return ID; }
0 //===- RegisterBank.td - Register bank definitions ---------*- tablegen -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //
10 //===----------------------------------------------------------------------===//
11
12 class RegisterBank classes> {
13 string Name = name;
14 list RegisterClasses = classes;
15 }
13431343 //===----------------------------------------------------------------------===//
13441344 // Pull in the common support for Global ISel generation.
13451345 //
1346 include "llvm/Target/GlobalISel/RegisterBank.td"
13461347 include "llvm/Target/TargetGlobalISel.td"
1818
1919 const unsigned RegisterBank::InvalidID = UINT_MAX;
2020
21 RegisterBank::RegisterBank(unsigned ID, const char *Name, unsigned Size,
22 const uint32_t *CoveredClasses)
21 RegisterBank::RegisterBank(
22 unsigned ID, const char *Name, unsigned Size,
23 const uint32_t *CoveredClasses, unsigned NumRegClasses)
2324 : ID(ID), Name(Name), Size(Size) {
24 ContainedRegClasses.resize(200);
25 ContainedRegClasses.resize(NumRegClasses);
2526 ContainedRegClasses.setBitsInMask(CoveredClasses);
2627 }
2728
126126 //===----------------------------------------------------------------------===//
127127
128128 include "AArch64RegisterInfo.td"
129 include "AArch64RegisterBanks.td"
129130 include "AArch64CallingConvention.td"
130131
131132 //===----------------------------------------------------------------------===//
1515 #endif
1616
1717 namespace llvm {
18 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 };
142
143 RegisterBank GPRRegBank(AArch64::GPRRegBankID, "GPR", 64, GPRCoverageData);
144 RegisterBank FPRRegBank(AArch64::FPRRegBankID, "FPR", 512, FPRCoverageData);
145 RegisterBank CCRRegBank(AArch64::CCRRegBankID, "CCR", 32, CCRCoverageData);
146 } // end namespace AArch64
147
148 RegisterBank *AArch64GenRegisterBankInfo::RegBanks[] = {
149 &AArch64::GPRRegBank, &AArch64::FPRRegBank, &AArch64::CCRRegBank};
150
15118 RegisterBankInfo::PartialMapping AArch64GenRegisterBankInfo::PartMappings[]{
15219 /* StartIdx, Length, RegBank */
153 // 0: GPR 32-bit value.
20 // 0: FPR 32-bit value.
21 {0, 32, AArch64::FPRRegBank},
22 // 1: FPR 64-bit value.
23 {0, 64, AArch64::FPRRegBank},
24 // 2: FPR 128-bit value.
25 {0, 128, AArch64::FPRRegBank},
26 // 3: FPR 256-bit value.
27 {0, 256, AArch64::FPRRegBank},
28 // 4: FPR 512-bit value.
29 {0, 512, AArch64::FPRRegBank},
30 // 5: GPR 32-bit value.
15431 {0, 32, AArch64::GPRRegBank},
155 // 1: GPR 64-bit value.
32 // 6: GPR 64-bit value.
15633 {0, 64, AArch64::GPRRegBank},
157 // 2: FPR 32-bit value.
158 {0, 32, AArch64::FPRRegBank},
159 // 3: FPR 64-bit value.
160 {0, 64, AArch64::FPRRegBank},
161 // 4: FPR 128-bit value.
162 {0, 128, AArch64::FPRRegBank},
163 // 5: FPR 256-bit value.
164 {0, 256, AArch64::FPRRegBank},
165 // 6: FPR 512-bit value.
166 {0, 512, AArch64::FPRRegBank}};
34 };
16735
16836 // ValueMappings.
16937 RegisterBankInfo::ValueMapping AArch64GenRegisterBankInfo::ValMappings[]{
17038 /* BreakDown, NumBreakDowns */
17139 // 3-operands instructions (all binary operations should end up with one of
17240 // those mapping).
173 // 0: GPR 32-bit value. <-- This must match First3OpsIdx.
174 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
175 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
176 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
177 // 3: GPR 64-bit value.
178 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
179 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
180 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
181 // 6: FPR 32-bit value.
182 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
183 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
184 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
185 // 9: FPR 64-bit value.
186 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
187 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
188 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
189 // 12: FPR 128-bit value.
41 // 0: FPR 32-bit value. <-- This must match First3OpsIdx.
42 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
43 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
44 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
45 // 3: FPR 64-bit value.
46 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
47 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
48 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
49 // 6: FPR 128-bit value.
19050 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1},
19151 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1},
19252 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1},
193 // 15: FPR 256-bit value.
53 // 9: FPR 256-bit value.
19454 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1},
19555 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1},
19656 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1},
197 // 18: FPR 512-bit value. <-- This must match Last3OpsIdx.
57 // 12: FPR 512-bit value.
19858 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1},
19959 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1},
20060 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1},
61 // 15: GPR 32-bit value.
62 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
63 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
64 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
65 // 18: GPR 64-bit value. <-- This must match Last3OpsIdx.
66 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
67 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
68 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
20169 // Cross register bank copies.
202 // 21: GPR 32-bit value to FPR 32-bit value. <-- This must match
70 // 21: FPR 32-bit value to GPR 32-bit value. <-- This must match
20371 // FirstCrossRegCpyIdx.
204 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
205 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
206 // 23: GPR 64-bit value to FPR 64-bit value.
207 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
208 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
209 // 25: FPR 32-bit value to GPR 32-bit value.
210 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
211 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
212 // 27: FPR 64-bit value to GPR 64-bit value. <-- This must match
72 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
73 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
74 // 23: FPR 64-bit value to GPR 64-bit value.
75 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
76 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
77 // 25: FPR 128-bit value to GPR 128-bit value (invalid)
78 {nullptr, 1},
79 {nullptr, 1},
80 // 27: FPR 256-bit value to GPR 256-bit value (invalid)
81 {nullptr, 1},
82 {nullptr, 1},
83 // 29: FPR 512-bit value to GPR 512-bit value (invalid)
84 {nullptr, 1},
85 {nullptr, 1},
86 // 31: GPR 32-bit value to FPR 32-bit value.
87 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
88 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
89 // 33: GPR 64-bit value to FPR 64-bit value. <-- This must match
21390 // LastCrossRegCpyIdx.
214 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
215 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1}
91 {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
92 {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
21693 };
21794
21895 bool AArch64GenRegisterBankInfo::checkPartialMap(unsigned Idx,
300177
301178 AArch64GenRegisterBankInfo::PartialMappingIdx
302179 AArch64GenRegisterBankInfo::BankIDToCopyMapIdx[]{
180 PMI_None, // CCR
181 PMI_FirstFPR, // FPR
303182 PMI_FirstGPR, // GPR
304 PMI_FirstFPR, // FPR
305 PMI_None, // CCR
306183 };
307184
308185 const RegisterBankInfo::ValueMapping *
2020 #include "llvm/Target/TargetRegisterInfo.h"
2121 #include "llvm/Target/TargetSubtargetInfo.h"
2222
23 #define GET_TARGET_REGBANK_IMPL
24 #include "AArch64GenRegisterBank.inc"
25
2326 // This file will be TableGen'ed at some point.
2427 #include "AArch64GenRegisterBankInfo.def"
2528
2831 #ifndef LLVM_BUILD_GLOBAL_ISEL
2932 #error "You shouldn't build this"
3033 #endif
31
32 AArch64GenRegisterBankInfo::AArch64GenRegisterBankInfo()
33 : RegisterBankInfo(RegBanks, AArch64::NumRegisterBanks) {}
3434
3535 AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
3636 : AArch64GenRegisterBankInfo() {
1515
1616 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
1717
18 #define GET_REGBANK_DECLARATIONS
19 #include "AArch64GenRegisterBank.inc"
20
1821 namespace llvm {
1922
2023 class TargetRegisterInfo;
2124
22 namespace AArch64 {
23 enum {
24 GPRRegBankID = 0, /// General Purpose Registers: W, X.
25 FPRRegBankID = 1, /// Floating Point/Vector Registers: B, H, S, D, Q.
26 CCRRegBankID = 2, /// Conditional register: NZCV.
27 NumRegisterBanks
28 };
29 } // End AArch64 namespace.
30
3125 class AArch64GenRegisterBankInfo : public RegisterBankInfo {
32 private:
33 static RegisterBank *RegBanks[];
34
3526 protected:
36 AArch64GenRegisterBankInfo();
3727
3828 enum PartialMappingIdx {
3929 PMI_None = -1,
40 PMI_GPR32 = 1,
41 PMI_GPR64,
42 PMI_FPR32,
30 PMI_FPR32 = 1,
4331 PMI_FPR64,
4432 PMI_FPR128,
4533 PMI_FPR256,
4634 PMI_FPR512,
35 PMI_GPR32,
36 PMI_GPR64,
4737 PMI_FirstGPR = PMI_GPR32,
4838 PMI_LastGPR = PMI_GPR64,
4939 PMI_FirstFPR = PMI_FPR32,
5040 PMI_LastFPR = PMI_FPR512,
51 PMI_Min = PMI_FirstGPR,
41 PMI_Min = PMI_FirstFPR,
5242 };
5343
5444 static RegisterBankInfo::PartialMapping PartMappings[];
6050 Last3OpsIdx = 18,
6151 DistanceBetweenRegBanks = 3,
6252 FirstCrossRegCpyIdx = 21,
63 LastCrossRegCpyIdx = 27,
53 LastCrossRegCpyIdx = 33,
6454 DistanceBetweenCrossRegCpy = 2
6555 };
6656
8979 /// register bank with a size of \p Size.
9080 static const RegisterBankInfo::ValueMapping *
9181 getCopyMapping(unsigned DstBankID, unsigned SrcBankID, unsigned Size);
82
83 #define GET_TARGET_REGBANK_CLASS
84 #include "AArch64GenRegisterBank.inc"
9285 };
9386
9487 /// This class provides the information for the target register banks.
0 //=- AArch64RegisterBank.td - Describe the AArch64 Banks -----*- tablegen -*-=//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //
10 //===----------------------------------------------------------------------===//
11
12 /// General Purpose Registers: W, X.
13 def GPRRegBank : RegisterBank<"GPR", [GPR64all]>;
14
15 /// Floating Point/Vector Registers: B, H, S, D, Q.
16 def FPRRegBank : RegisterBank<"FPR", [QQQQ]>;
17
18 /// Conditional register: NZCV.
19 def CCRRegBank : RegisterBank<"CCR", [CCR]>;
1313 tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler)
1414 tablegen(LLVM AArch64GenSystemOperands.inc -gen-searchable-tables)
1515 if(LLVM_BUILD_GLOBAL_ISEL)
16 tablegen(LLVM AArch64GenRegisterBank.inc -gen-register-bank)
1617 tablegen(LLVM AArch64GenGlobalISel.inc -gen-global-isel)
1718 endif()
1819
5454 0,
5555 };
5656
57 RegisterBank GPRRegBank(ARM::GPRRegBankID, "GPRB", 32, ARM::GPRCoverageData);
57 // FIXME: The 200 will be replaced by the number of register classes when this is
58 // tablegenerated.
59 RegisterBank GPRRegBank(ARM::GPRRegBankID, "GPRB", 32, ARM::GPRCoverageData, 200);
5860 RegisterBank *RegBanks[] = {&GPRRegBank};
5961
6062 RegisterBankInfo::PartialMapping GPRPartialMapping{0, 32, GPRRegBank};
0 //===- RegisterBank.td - Register bank definitions ---------*- tablegen -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //
10 //===----------------------------------------------------------------------===//
11
12 class RegisterBank classes> {
13 string Name = name;
14 list RegisterClasses = classes;
15 }
2626 IntrinsicEmitter.cpp
2727 OptParserEmitter.cpp
2828 PseudoLoweringEmitter.cpp
29 RegisterBankEmitter.cpp
2930 RegisterInfoEmitter.cpp
3031 SearchableTableEmitter.cpp
3132 SubtargetEmitter.cpp
0 //===- RegisterBankEmitter.cpp - Generate a Register Bank Desc. -*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This tablegen backend is responsible for emitting a description of a target
10 // register bank for a code generator.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/ADT/BitVector.h"
15 #include "llvm/Support/Debug.h"
16 #include "llvm/TableGen/Error.h"
17 #include "llvm/TableGen/Record.h"
18 #include "llvm/TableGen/TableGenBackend.h"
19
20 #include "CodeGenRegisters.h"
21
22 #define DEBUG_TYPE "register-bank-emitter"
23
24 using namespace llvm;
25
26 namespace {
27 class RegisterBank {
28
29 /// A vector of register classes that are included in the register bank.
30 typedef std::vector RegisterClassesTy;
31
32 private:
33 const Record &TheDef;
34
35 /// The register classes that are covered by the register bank.
36 RegisterClassesTy RCs;
37
38 /// The register class with the largest register size.
39 const CodeGenRegisterClass *RCWithLargestRegsSize;
40
41 public:
42 RegisterBank(const Record &TheDef)
43 : TheDef(TheDef), RCs(), RCWithLargestRegsSize(nullptr) {}
44
45 /// Get the human-readable name for the bank.
46 std::string getName() const { return TheDef.getValueAsString("Name"); }
47 /// Get the name of the enumerator in the ID enumeration.
48 std::string getEnumeratorName() const { return (TheDef.getName() + "ID").str(); }
49
50 /// Get the name of the array holding the register class coverage data;
51 std::string getCoverageArrayName() const {
52 return (TheDef.getName() + "CoverageData").str();
53 }
54
55 /// Get the name of the global instance variable.
56 StringRef getInstanceVarName() const { return TheDef.getName(); }
57
58 const Record &getDef() const { return TheDef; }
59
60 /// Get the register classes listed in the RegisterBank.RegisterClasses field.
61 std::vector
62 getExplictlySpecifiedRegisterClasses(
63 CodeGenRegBank &RegisterClassHierarchy) const {
64 std::vector RCs;
65 for (const auto &RCDef : getDef().getValueAsListOfDefs("RegisterClasses"))
66 RCs.push_back(RegisterClassHierarchy.getRegClass(RCDef));
67 return RCs;
68 }
69
70 /// Add a register class to the bank without duplicates.
71 void addRegisterClass(const CodeGenRegisterClass *RC) {
72 if (std::find_if(RCs.begin(), RCs.end(),
73 [&RC](const CodeGenRegisterClass *X) {
74 return X == RC;
75 }) != RCs.end())
76 return;
77
78 // FIXME? We really want the register size rather than the spill size
79 // since the spill size may be bigger on some targets with
80 // limited load/store instructions. However, we don't store the
81 // register size anywhere (we could sum the sizes of the subregisters
82 // but there may be additional bits too) and we can't derive it from
83 // the VT's reliably due to Untyped.
84 if (RCWithLargestRegsSize == nullptr)
85 RCWithLargestRegsSize = RC;
86 else if (RCWithLargestRegsSize->SpillSize < RC->SpillSize)
87 RCWithLargestRegsSize = RC;
88 assert(RCWithLargestRegsSize && "RC was nullptr?");
89
90 RCs.emplace_back(RC);
91 }
92
93 const CodeGenRegisterClass *getRCWithLargestRegsSize() const {
94 return RCWithLargestRegsSize;
95 }
96
97 iterator_range
98 register_classes() const {
99 return llvm::make_range(RCs.begin(), RCs.end());
100 }
101 };
102
103 class RegisterBankEmitter {
104 private:
105 RecordKeeper &Records;
106 CodeGenRegBank RegisterClassHierarchy;
107
108 void emitHeader(raw_ostream &OS, const StringRef TargetName,
109 const std::vector &Banks);
110 void emitBaseClassDefinition(raw_ostream &OS, const StringRef TargetName,
111 const std::vector &Banks);
112 void emitBaseClassImplementation(raw_ostream &OS, const StringRef TargetName,
113 std::vector &Banks);
114
115 public:
116 RegisterBankEmitter(RecordKeeper &R)
117 : Records(R), RegisterClassHierarchy(Records) {}
118
119 void run(raw_ostream &OS);
120 };
121
122 } // end anonymous namespace
123
124 /// Emit code to declare the ID enumeration and external global instance
125 /// variables.
126 void RegisterBankEmitter::emitHeader(raw_ostream &OS,
127 const StringRef TargetName,
128 const std::vector &Banks) {
129 // RegisterBankInfo.h
130 OS << "namespace llvm {\n"
131 << "namespace " << TargetName << " {\n"
132 << "enum {\n";
133 for (const auto &Bank : Banks)
134 OS << " " << Bank.getEnumeratorName() << ",\n";
135 OS << " NumRegisterBanks,\n"
136 << "};\n"
137 << "} // end namespace " << TargetName << "\n"
138 << "} // end namespace llvm\n";
139 }
140
141 /// Emit declarations of the GenRegisterBankInfo class.
142 void RegisterBankEmitter::emitBaseClassDefinition(
143 raw_ostream &OS, const StringRef TargetName,
144 const std::vector &Banks) {
145 OS << "private:\n"
146 << " static RegisterBank *RegBanks[];\n\n"
147 << "protected:\n"
148 << " " << TargetName << "GenRegisterBankInfo();\n"
149 << "\n";
150 }
151
152 /// Visit each register class belonging to the given register bank.
153 ///
154 /// A class belongs to the bank iff any of these apply:
155 /// * It is explicitly specified
156 /// * It is a subclass of a class that is a member.
157 /// * It is a class containing subregisters of the registers of a class that
158 /// is a member. This is known as a subreg-class.
159 ///
160 /// This function must be called for each explicitly specified register class.
161 ///
162 /// \param RC The register class to search.
163 /// \param Kind A debug string containing the path the visitor took to reach RC.
164 /// \param VisitFn The action to take for each class visited. It may be called
165 /// multiple times for a given class if there are multiple paths
166 /// to the class.
167 static void visitRegisterBankClasses(
168 CodeGenRegBank &RegisterClassHierarchy, const CodeGenRegisterClass *RC,
169 const Twine Kind,
170 std::function VisitFn) {
171 // Visit each explicitly named class.
172 VisitFn(RC, Kind.str());
173
174 for (const auto &PossibleSubclass : RegisterClassHierarchy.getRegClasses()) {
175 Twine TmpKind = Kind + " (" + PossibleSubclass.getName() + ")";
176
177 // Visit each subclass of an explicitly named class.
178 if (RC != &PossibleSubclass && RC->hasSubClass(&PossibleSubclass))
179 visitRegisterBankClasses(RegisterClassHierarchy, &PossibleSubclass,
180 TmpKind + " " + RC->getName() + " subclass",
181 VisitFn);
182
183 // Visit each class that contains only subregisters of RC with a common
184 // subregister-index.
185 //
186 // More precisely, PossibleSubclass is a subreg-class iff Reg:SubIdx is in
187 // PossibleSubclass for all registers Reg from RC using any
188 // subregister-index SubReg
189 for (const auto &SubIdx : RegisterClassHierarchy.getSubRegIndices()) {
190 BitVector BV(RegisterClassHierarchy.getRegClasses().size());
191 PossibleSubclass.getSuperRegClasses(&SubIdx, BV);
192 if (BV.test(RC->EnumValue)) {
193 Twine TmpKind2 = TmpKind + " " + RC->getName() +
194 " class-with-subregs: " + RC->getName();
195 VisitFn(&PossibleSubclass, TmpKind2.str());
196 }
197 }
198 }
199 }
200
201 void RegisterBankEmitter::emitBaseClassImplementation(
202 raw_ostream &OS, StringRef TargetName,
203 std::vector &Banks) {
204
205 OS << "namespace llvm {\n"
206 << "namespace " << TargetName << " {\n";
207 for (const auto &Bank : Banks) {
208 std::vector> RCsGroupedByWord(
209 (RegisterClassHierarchy.getRegClasses().size() + 31) / 32);
210
211 for (const auto &RC : Bank.register_classes())
212 RCsGroupedByWord[RC->EnumValue / 32].push_back(RC);
213
214 OS << "const uint32_t " << Bank.getCoverageArrayName() << "[] = {\n";
215 unsigned LowestIdxInWord = 0;
216 for (const auto &RCs : RCsGroupedByWord) {
217 OS << " // " << LowestIdxInWord << "-" << (LowestIdxInWord + 31) << "\n";
218 for (const auto &RC : RCs) {
219 Twine QualifiedRegClassID =
220 TargetName + "::" + RC->getName() + "RegClassID";
221 OS << " (1u << (" << QualifiedRegClassID << " - "
222 << LowestIdxInWord << ")) |\n";
223 }
224 OS << " 0,\n";
225 LowestIdxInWord += 32;
226 }
227 OS << "};\n";
228 }
229 OS << "\n";
230
231 for (const auto &Bank : Banks) {
232 Twine QualifiedBankID = TargetName + "::" + Bank.getEnumeratorName();
233 unsigned Size = Bank.getRCWithLargestRegsSize()->SpillSize;
234 OS << "RegisterBank " << Bank.getInstanceVarName() << "(/* ID */ "
235 << QualifiedBankID << ", /* Name */ \"" << Bank.getName()
236 << "\", /* Size */ " << Size << ", "
237 << "/* CoveredRegClasses */ " << Bank.getCoverageArrayName()
238 << ", /* NumRegClasses */ "
239 << RegisterClassHierarchy.getRegClasses().size() << ");\n";
240 }
241 OS << "} // end namespace " << TargetName << "\n"
242 << "\n";
243
244 OS << "RegisterBank *" << TargetName
245 << "GenRegisterBankInfo::RegBanks[] = {\n";
246 for (const auto &Bank : Banks)
247 OS << " &" << TargetName << "::" << Bank.getInstanceVarName() << ",\n";
248 OS << "};\n\n";
249
250 OS << TargetName << "GenRegisterBankInfo::" << TargetName
251 << "GenRegisterBankInfo()\n"
252 << " : RegisterBankInfo(RegBanks, " << TargetName
253 << "::NumRegisterBanks) {\n"
254 << " // Assert that RegBank indices match their ID's\n"
255 << " unsigned Index = 0;\n"
256 << "#ifndef NDEBUG\n"
257 << " for (const auto &RB : RegBanks)\n"
258 << " assert(Index++ == RB->getID() && \"Index != ID\");\n"
259 << "#endif // NDEBUG\n"
260 << "}\n"
261 << "} // end namespace llvm\n";
262 }
263
264 void RegisterBankEmitter::run(raw_ostream &OS) {
265 std::vector Targets = Records.getAllDerivedDefinitions("Target");
266 if (Targets.size() != 1)
267 PrintFatalError("ERROR: Too many or too few subclasses of Target defined!");
268 StringRef TargetName = Targets[0]->getName();
269
270 std::vector Banks;
271 for (const auto &V : Records.getAllDerivedDefinitions("RegisterBank")) {
272 RegisterBank Bank(*V);
273
274 for (const CodeGenRegisterClass *RC :
275 Bank.getExplictlySpecifiedRegisterClasses(RegisterClassHierarchy)) {
276 visitRegisterBankClasses(
277 RegisterClassHierarchy, RC, "explicit",
278 [&Bank](const CodeGenRegisterClass *RC, StringRef Kind) {
279 DEBUG(dbgs() << "Added " << RC->getName() << "(" << Kind << ")\n");
280 Bank.addRegisterClass(RC);
281 });
282 }
283
284 Banks.push_back(Bank);
285 }
286
287 emitSourceFileHeader("Register Bank Source Fragments", OS);
288 OS << "#ifdef GET_REGBANK_DECLARATIONS\n"
289 << "#undef GET_REGBANK_DECLARATIONS\n";
290 emitHeader(OS, TargetName, Banks);
291 OS << "#endif // GET_REGBANK_DECLARATIONS\n\n"
292 << "#ifdef GET_TARGET_REGBANK_CLASS\n"
293 << "#undef GET_TARGET_REGBANK_CLASS\n";
294 emitBaseClassDefinition(OS, TargetName, Banks);
295 OS << "#endif // GET_TARGET_REGBANK_CLASS\n\n"
296 << "#ifdef GET_TARGET_REGBANK_IMPL\n"
297 << "#undef GET_TARGET_REGBANK_IMPL\n";
298 emitBaseClassImplementation(OS, TargetName, Banks);
299 OS << "#endif // GET_TARGET_REGBANK_IMPL\n";
300 }
301
302 namespace llvm {
303
304 void EmitRegisterBank(RecordKeeper &RK, raw_ostream &OS) {
305 RegisterBankEmitter(RK).run(OS);
306 }
307
308 } // end namespace llvm
4545 GenAttributes,
4646 GenSearchableTables,
4747 GenGlobalISel,
48 GenRegisterBank,
4849 };
4950
5051 namespace {
9394 clEnumValN(GenSearchableTables, "gen-searchable-tables",
9495 "Generate generic binary-searchable table"),
9596 clEnumValN(GenGlobalISel, "gen-global-isel",
96 "Generate GlobalISel selector")));
97 "Generate GlobalISel selector"),
98 clEnumValN(GenRegisterBank, "gen-register-bank",
99 "Generate registers bank descriptions")));
97100
98101 cl::opt
99102 Class("class", cl::desc("Print Enum list for this class"),
181184 break;
182185 case GenGlobalISel:
183186 EmitGlobalISel(Records, OS);
187 case GenRegisterBank:
188 EmitRegisterBank(Records, OS);
184189 break;
185190 }
186191
8080 void EmitAttributes(RecordKeeper &RK, raw_ostream &OS);
8181 void EmitSearchableTables(RecordKeeper &RK, raw_ostream &OS);
8282 void EmitGlobalISel(RecordKeeper &RK, raw_ostream &OS);
83 void EmitRegisterBank(RecordKeeper &RK, raw_ostream &OS);
8384
8485 } // End llvm namespace
8586