10
10
// for the following types of static data:
11
11
// - Jump tables
12
12
// - Module-internal global variables
13
- // - Constant pools (TODO)
13
+ // - Constant pools
14
14
//
15
15
// For the original RFC of this pass please see
16
16
// https://discourse.llvm.org/t/rfc-profile-guided-static-data-partitioning/83744
@@ -60,8 +60,8 @@ class StaticDataSplitter : public MachineFunctionPass {
60
60
61
61
// Returns the constant if the operand refers to a global variable or constant
62
62
// that gets lowered to static data sections. Otherwise, return nullptr.
63
- const Constant *getConstant (const MachineOperand &Op,
64
- const TargetMachine &TM );
63
+ const Constant *getConstant (const MachineOperand &Op, const TargetMachine &TM,
64
+ const MachineConstantPool *MCP );
65
65
66
66
// Use profiles to partition static data.
67
67
bool partitionStaticDataWithProfiles (MachineFunction &MF);
@@ -89,8 +89,11 @@ class StaticDataSplitter : public MachineFunctionPass {
89
89
AU.addRequired <MachineBlockFrequencyInfoWrapperPass>();
90
90
AU.addRequired <ProfileSummaryInfoWrapperPass>();
91
91
AU.addRequired <StaticDataProfileInfoWrapperPass>();
92
- // This pass does not modify the CFG.
93
- AU.setPreservesCFG ();
92
+ // This pass does not modify any required analysis results except
93
+ // StaticDataProfileInfoWrapperPass, but StaticDataProfileInfoWrapperPass
94
+ // is made an immutable pass that it won't be re-scheduled by pass manager
95
+ // anyway. So mark setPreservesAll() here for faster compile time.
96
+ AU.setPreservesAll ();
94
97
}
95
98
96
99
bool runOnMachineFunction (MachineFunction &MF) override ;
@@ -119,40 +122,63 @@ bool StaticDataSplitter::runOnMachineFunction(MachineFunction &MF) {
119
122
return Changed;
120
123
}
121
124
122
- const Constant *StaticDataSplitter::getConstant (const MachineOperand &Op,
123
- const TargetMachine &TM) {
124
- if (!Op.isGlobal ())
125
+ const Constant *
126
+ StaticDataSplitter::getConstant (const MachineOperand &Op,
127
+ const TargetMachine &TM,
128
+ const MachineConstantPool *MCP) {
129
+ if (!Op.isGlobal () && !Op.isCPI ())
125
130
return nullptr ;
126
131
127
- // Find global variables with local linkage.
128
- const GlobalVariable *GV = getLocalLinkageGlobalVariable (Op.getGlobal ());
129
- // Skip 'llvm.'-prefixed global variables conservatively because they are
130
- // often handled specially, and skip those not in static data sections.
131
- if (!GV || GV->getName ().starts_with (" llvm." ) ||
132
- !inStaticDataSection (*GV, TM))
132
+ if (Op.isGlobal ()) {
133
+ // Find global variables with local linkage.
134
+ const GlobalVariable *GV = getLocalLinkageGlobalVariable (Op.getGlobal ());
135
+ // Skip 'llvm.'-prefixed global variables conservatively because they are
136
+ // often handled specially, and skip those not in static data
137
+ // sections.
138
+ if (!GV || GV->getName ().starts_with (" llvm." ) ||
139
+ !inStaticDataSection (*GV, TM))
140
+ return nullptr ;
141
+ return GV;
142
+ }
143
+ assert (Op.isCPI () && " Op must be constant pool index in this branch" );
144
+ int CPI = Op.getIndex ();
145
+ if (CPI == -1 )
146
+ return nullptr ;
147
+
148
+ assert (MCP != nullptr && " Constant pool info is not available." );
149
+ const MachineConstantPoolEntry &CPE = MCP->getConstants ()[CPI];
150
+
151
+ if (CPE.isMachineConstantPoolEntry ())
133
152
return nullptr ;
134
- return GV;
153
+
154
+ return CPE.Val .ConstVal ;
135
155
}
136
156
137
157
bool StaticDataSplitter::partitionStaticDataWithProfiles (MachineFunction &MF) {
138
- int NumChangedJumpTables = 0 ;
158
+ // If any of the static data (jump tables, global variables, constant pools)
159
+ // are captured by the analysis, set `Changed` to true. Note this pass won't
160
+ // invalidate any analysis pass (see `getAnalysisUsage` above), so the main
161
+ // purpose of tracking and conveying the change (to pass manager) is
162
+ // informative as opposed to invalidating any analysis results. As an example
163
+ // of where this information is useful, `PMDataManager::dumpPassInfo` will
164
+ // only dump pass info if a local change happens, otherwise a pass appears as
165
+ // "skipped".
166
+ bool Changed = false ;
139
167
140
- const TargetMachine &TM = MF.getTarget ();
141
168
MachineJumpTableInfo *MJTI = MF.getJumpTableInfo ();
142
169
143
170
// Jump table could be used by either terminating instructions or
144
171
// non-terminating ones, so we walk all instructions and use
145
172
// `MachineOperand::isJTI()` to identify jump table operands.
146
- // Similarly, `MachineOperand::isCPI()` can identify constant pool usages
147
- // in the same loop.
173
+ // Similarly, `MachineOperand::isCPI()` is used to identify constant pool
174
+ // usages in the same loop.
148
175
for (const auto &MBB : MF) {
176
+ std::optional<uint64_t > Count = MBFI->getBlockProfileCount (&MBB);
149
177
for (const MachineInstr &I : MBB) {
150
178
for (const MachineOperand &Op : I.operands ()) {
151
- if (!Op.isJTI () && !Op.isGlobal ())
179
+ if (!Op.isJTI () && !Op.isGlobal () && !Op. isCPI () )
152
180
continue ;
153
181
154
- std::optional<uint64_t > Count = MBFI->getBlockProfileCount (&MBB);
155
-
156
182
if (Op.isJTI ()) {
157
183
assert (MJTI != nullptr && " Jump table info is not available." );
158
184
const int JTI = Op.getIndex ();
@@ -168,15 +194,16 @@ bool StaticDataSplitter::partitionStaticDataWithProfiles(MachineFunction &MF) {
168
194
if (Count && PSI->isColdCount (*Count))
169
195
Hotness = MachineFunctionDataHotness::Cold;
170
196
171
- if ( MJTI->updateJumpTableEntryHotness (JTI, Hotness))
172
- ++NumChangedJumpTables;
173
- } else if ( const Constant *C = getConstant (Op, TM )) {
197
+ Changed |= MJTI->updateJumpTableEntryHotness (JTI, Hotness);
198
+ } else if ( const Constant *C =
199
+ getConstant (Op, MF. getTarget (), MF. getConstantPool () )) {
174
200
SDPI->addConstantProfileCount (C, Count);
201
+ Changed = true ;
175
202
}
176
203
}
177
204
}
178
205
}
179
- return NumChangedJumpTables > 0 ;
206
+ return Changed ;
180
207
}
181
208
182
209
const GlobalVariable *
@@ -218,7 +245,8 @@ void StaticDataSplitter::annotateStaticDataWithoutProfiles(
218
245
for (const auto &MBB : MF)
219
246
for (const MachineInstr &I : MBB)
220
247
for (const MachineOperand &Op : I.operands ())
221
- if (const Constant *C = getConstant (Op, MF.getTarget ()))
248
+ if (const Constant *C =
249
+ getConstant (Op, MF.getTarget (), MF.getConstantPool ()))
222
250
SDPI->addConstantProfileCount (C, std::nullopt );
223
251
}
224
252
0 commit comments