@@ -41,25 +41,17 @@ STATISTIC(NumUnknownJumpTables,
4141 " Number of jump tables with unknown hotness. Option "
4242 " -static-data-default-hotness specifies the hotness." );
4343
44- static cl::opt<MachineFunctionDataHotness> StaticDataDefaultHotness (
45- " static-data-default-hotness" , cl::Hidden,
46- cl::desc (" This option specifies the hotness of static data when profile "
47- " information is unavailable" ),
48- cl::init(MachineFunctionDataHotness::Hot),
49- cl::values(clEnumValN(MachineFunctionDataHotness::Hot, " hot" , " Hot" ),
50- clEnumValN(MachineFunctionDataHotness::Cold, " cold" , " Cold" )));
51-
5244class StaticDataSplitter : public MachineFunctionPass {
5345 const MachineBranchProbabilityInfo *MBPI = nullptr ;
5446 const MachineBlockFrequencyInfo *MBFI = nullptr ;
5547 const ProfileSummaryInfo *PSI = nullptr ;
5648
57- // Returns true iff any jump table is hot-cold categorized.
58- bool splitJumpTables (MachineFunction &MF);
49+ void updateStats (bool ProfileAvailable, const MachineJumpTableInfo *MJTI);
50+ void updateJumpTableStats (bool ProfileAvailable,
51+ const MachineJumpTableInfo &MJTI);
5952
60- // Same as above but works on functions with profile information.
61- bool splitJumpTablesWithProfiles (const MachineFunction &MF,
62- MachineJumpTableInfo &MJTI);
53+ // Use profiles to partition static data.
54+ bool partitionStaticDataWithProfiles (MachineFunction &MF);
6355
6456public:
6557 static char ID;
@@ -85,13 +77,22 @@ bool StaticDataSplitter::runOnMachineFunction(MachineFunction &MF) {
8577 MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI ();
8678 PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI ();
8779
88- return splitJumpTables (MF);
80+ const bool ProfileAvailable = PSI && PSI->hasProfileSummary () && MBFI &&
81+ MF.getFunction ().hasProfileData ();
82+ bool Changed = false ;
83+
84+ if (ProfileAvailable)
85+ Changed |= partitionStaticDataWithProfiles (MF);
86+
87+ updateStats (ProfileAvailable, MF.getJumpTableInfo ());
88+ return Changed;
8989}
9090
91- bool StaticDataSplitter::splitJumpTablesWithProfiles (
92- const MachineFunction &MF, MachineJumpTableInfo &MJTI) {
91+ bool StaticDataSplitter::partitionStaticDataWithProfiles (MachineFunction &MF) {
9392 int NumChangedJumpTables = 0 ;
9493
94+ MachineJumpTableInfo *MJTI = MF.getJumpTableInfo ();
95+
9596 // Jump table could be used by either terminating instructions or
9697 // non-terminating ones, so we walk all instructions and use
9798 // `MachineOperand::isJTI()` to identify jump table operands.
@@ -100,70 +101,58 @@ bool StaticDataSplitter::splitJumpTablesWithProfiles(
100101 for (const auto &MBB : MF) {
101102 for (const MachineInstr &I : MBB) {
102103 for (const MachineOperand &Op : I.operands ()) {
103- if (!Op.isJTI ())
104- continue ;
105- const int JTI = Op.getIndex ();
106- // This is not a source block of jump table.
107- if (JTI == -1 )
108- continue ;
109-
110- auto Hotness = MachineFunctionDataHotness::Hot;
111-
112- // Hotness is based on source basic block hotness.
113- // TODO: PSI APIs are about instruction hotness. Introduce API for data
114- // access hotness.
115- if (PSI->isColdBlock (&MBB, MBFI))
116- Hotness = MachineFunctionDataHotness::Cold;
117-
118- if (MJTI.updateJumpTableEntryHotness (JTI, Hotness))
119- ++NumChangedJumpTables;
104+ if (Op.isJTI ()) {
105+ assert (MJTI != nullptr && " Jump table info is not available." );
106+ const int JTI = Op.getIndex ();
107+ // This is not a source block of jump table.
108+ if (JTI == -1 )
109+ continue ;
110+
111+ auto Hotness = MachineFunctionDataHotness::Hot;
112+
113+ // Hotness is based on source basic block hotness.
114+ // TODO: PSI APIs are about instruction hotness. Introduce API for
115+ // data access hotness.
116+ if (PSI->isColdBlock (&MBB, MBFI))
117+ Hotness = MachineFunctionDataHotness::Cold;
118+
119+ if (MJTI->updateJumpTableEntryHotness (JTI, Hotness))
120+ ++NumChangedJumpTables;
121+ }
120122 }
121123 }
122124 }
123125 return NumChangedJumpTables > 0 ;
124126}
125127
126- bool StaticDataSplitter::splitJumpTables (MachineFunction &MF) {
127- MachineJumpTableInfo *MJTI = MF.getJumpTableInfo ();
128- if (!MJTI || MJTI->getJumpTables ().empty ())
129- return false ;
128+ void StaticDataSplitter::updateJumpTableStats (
129+ bool ProfileAvailable, const MachineJumpTableInfo &MJTI) {
130130
131- const bool ProfileAvailable = PSI && PSI->hasProfileSummary () && MBFI &&
132- MF.getFunction ().hasProfileData ();
133- auto statOnExit = llvm::make_scope_exit ([&] {
134- if (!AreStatisticsEnabled ())
135- return ;
136-
137- if (!ProfileAvailable) {
138- NumUnknownJumpTables += MJTI->getJumpTables ().size ();
139- return ;
140- }
131+ if (!ProfileAvailable) {
132+ NumUnknownJumpTables += MJTI.getJumpTables ().size ();
133+ return ;
134+ }
141135
142- for (size_t JTI = 0 ; JTI < MJTI->getJumpTables ().size (); JTI++) {
143- auto Hotness = MJTI->getJumpTables ()[JTI].Hotness ;
144- if (Hotness == MachineFunctionDataHotness::Hot) {
145- ++NumHotJumpTables;
146- } else {
147- assert (Hotness == MachineFunctionDataHotness::Cold &&
148- " A jump table is either hot or cold when profile information is "
149- " available." );
150- ++NumColdJumpTables;
151- }
136+ for (size_t JTI = 0 ; JTI < MJTI.getJumpTables ().size (); JTI++) {
137+ auto Hotness = MJTI.getJumpTables ()[JTI].Hotness ;
138+ if (Hotness == MachineFunctionDataHotness::Hot) {
139+ ++NumHotJumpTables;
140+ } else {
141+ assert (Hotness == MachineFunctionDataHotness::Cold &&
142+ " A jump table is either hot or cold when profile information is "
143+ " available." );
144+ ++NumColdJumpTables;
152145 }
153- });
154-
155- // Place jump tables according to block hotness if function has profile data.
156- if (ProfileAvailable)
157- return splitJumpTablesWithProfiles (MF, *MJTI);
146+ }
147+ }
158148
159- // If function profile is unavailable (e.g., module not instrumented, or new
160- // code paths lacking samples), -static-data-default-hotness specifies the
161- // hotness.
162- for (size_t JTI = 0 ; JTI < MJTI->getJumpTables ().size (); JTI++)
163- MF.getJumpTableInfo ()->updateJumpTableEntryHotness (
164- JTI, StaticDataDefaultHotness);
149+ void StaticDataSplitter::updateStats (bool ProfileAvailable,
150+ const MachineJumpTableInfo *MJTI) {
151+ if (!AreStatisticsEnabled ())
152+ return ;
165153
166- return true ;
154+ if (MJTI)
155+ updateJumpTableStats (ProfileAvailable, *MJTI);
167156}
168157
169158char StaticDataSplitter::ID = 0 ;
0 commit comments