1010// for the following types of static data:
1111// - Jump tables
1212// - Module-internal global variables
13- // - Constant pools (TODO)
13+ // - Constant pools
1414//
1515// For the original RFC of this pass please see
1616// https://discourse.llvm.org/t/rfc-profile-guided-static-data-partitioning/83744
@@ -60,8 +60,8 @@ class StaticDataSplitter : public MachineFunctionPass {
6060
6161 // Returns the constant if the operand refers to a global variable or constant
6262 // 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 );
6565
6666 // Use profiles to partition static data.
6767 bool partitionStaticDataWithProfiles (MachineFunction &MF);
@@ -89,8 +89,11 @@ class StaticDataSplitter : public MachineFunctionPass {
8989 AU.addRequired <MachineBlockFrequencyInfoWrapperPass>();
9090 AU.addRequired <ProfileSummaryInfoWrapperPass>();
9191 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 ();
9497 }
9598
9699 bool runOnMachineFunction (MachineFunction &MF) override ;
@@ -119,40 +122,63 @@ bool StaticDataSplitter::runOnMachineFunction(MachineFunction &MF) {
119122 return Changed;
120123}
121124
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 ())
125130 return nullptr ;
126131
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 ())
133152 return nullptr ;
134- return GV;
153+
154+ return CPE.Val .ConstVal ;
135155}
136156
137157bool 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 ;
139167
140- const TargetMachine &TM = MF.getTarget ();
141168 MachineJumpTableInfo *MJTI = MF.getJumpTableInfo ();
142169
143170 // Jump table could be used by either terminating instructions or
144171 // non-terminating ones, so we walk all instructions and use
145172 // `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.
148175 for (const auto &MBB : MF) {
176+ std::optional<uint64_t > Count = MBFI->getBlockProfileCount (&MBB);
149177 for (const MachineInstr &I : MBB) {
150178 for (const MachineOperand &Op : I.operands ()) {
151- if (!Op.isJTI () && !Op.isGlobal ())
179+ if (!Op.isJTI () && !Op.isGlobal () && !Op. isCPI () )
152180 continue ;
153181
154- std::optional<uint64_t > Count = MBFI->getBlockProfileCount (&MBB);
155-
156182 if (Op.isJTI ()) {
157183 assert (MJTI != nullptr && " Jump table info is not available." );
158184 const int JTI = Op.getIndex ();
@@ -168,15 +194,16 @@ bool StaticDataSplitter::partitionStaticDataWithProfiles(MachineFunction &MF) {
168194 if (Count && PSI->isColdCount (*Count))
169195 Hotness = MachineFunctionDataHotness::Cold;
170196
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 () )) {
174200 SDPI->addConstantProfileCount (C, Count);
201+ Changed = true ;
175202 }
176203 }
177204 }
178205 }
179- return NumChangedJumpTables > 0 ;
206+ return Changed ;
180207}
181208
182209const GlobalVariable *
@@ -218,7 +245,8 @@ void StaticDataSplitter::annotateStaticDataWithoutProfiles(
218245 for (const auto &MBB : MF)
219246 for (const MachineInstr &I : MBB)
220247 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 ()))
222250 SDPI->addConstantProfileCount (C, std::nullopt );
223251}
224252
0 commit comments