@@ -46,12 +46,13 @@ class StaticDataSplitter : public MachineFunctionPass {
4646 const MachineBlockFrequencyInfo *MBFI = nullptr ;
4747 const ProfileSummaryInfo *PSI = nullptr ;
4848
49- // Returns true iff any jump table is hot-cold categorized.
50- bool splitJumpTables (MachineFunction &MF);
49+ // Update LLVM statistics for a machine function without profiles.
50+ void updateStatsWithoutProfiles (const MachineFunction &MF);
51+ // Update LLVM statistics for a machine function with profiles.
52+ void updateStatsWithProfiles (const MachineFunction &MF);
5153
52- // Same as above but works on functions with profile information.
53- bool splitJumpTablesWithProfiles (const MachineFunction &MF,
54- MachineJumpTableInfo &MJTI);
54+ // Use profiles to partition static data.
55+ bool partitionStaticDataWithProfiles (MachineFunction &MF);
5556
5657public:
5758 static char ID;
@@ -77,13 +78,25 @@ bool StaticDataSplitter::runOnMachineFunction(MachineFunction &MF) {
7778 MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI ();
7879 PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI ();
7980
80- return splitJumpTables (MF);
81+ const bool ProfileAvailable = PSI && PSI->hasProfileSummary () && MBFI &&
82+ MF.getFunction ().hasProfileData ();
83+
84+ if (!ProfileAvailable) {
85+ updateStatsWithoutProfiles (MF);
86+ return false ;
87+ }
88+
89+ bool Changed = partitionStaticDataWithProfiles (MF);
90+
91+ updateStatsWithProfiles (MF);
92+ return Changed;
8193}
8294
83- bool StaticDataSplitter::splitJumpTablesWithProfiles (
84- const MachineFunction &MF, MachineJumpTableInfo &MJTI) {
95+ bool StaticDataSplitter::partitionStaticDataWithProfiles (MachineFunction &MF) {
8596 int NumChangedJumpTables = 0 ;
8697
98+ MachineJumpTableInfo *MJTI = MF.getJumpTableInfo ();
99+
87100 // Jump table could be used by either terminating instructions or
88101 // non-terminating ones, so we walk all instructions and use
89102 // `MachineOperand::isJTI()` to identify jump table operands.
@@ -92,63 +105,55 @@ bool StaticDataSplitter::splitJumpTablesWithProfiles(
92105 for (const auto &MBB : MF) {
93106 for (const MachineInstr &I : MBB) {
94107 for (const MachineOperand &Op : I.operands ()) {
95- if (!Op.isJTI ())
96- continue ;
97- const int JTI = Op.getIndex ();
98- // This is not a source block of jump table.
99- if (JTI == -1 )
100- continue ;
101-
102- auto Hotness = MachineFunctionDataHotness::Hot;
103-
104- // Hotness is based on source basic block hotness.
105- // TODO: PSI APIs are about instruction hotness. Introduce API for data
106- // access hotness.
107- if (PSI->isColdBlock (&MBB, MBFI))
108- Hotness = MachineFunctionDataHotness::Cold;
109-
110- if (MJTI.updateJumpTableEntryHotness (JTI, Hotness))
111- ++NumChangedJumpTables;
108+ if (Op.isJTI ()) {
109+ assert (MJTI != nullptr && " Jump table info is not available." );
110+ const int JTI = Op.getIndex ();
111+ // This is not a source block of jump table.
112+ if (JTI == -1 )
113+ continue ;
114+
115+ auto Hotness = MachineFunctionDataHotness::Hot;
116+
117+ // Hotness is based on source basic block hotness.
118+ // TODO: PSI APIs are about instruction hotness. Introduce API for
119+ // data access hotness.
120+ if (PSI->isColdBlock (&MBB, MBFI))
121+ Hotness = MachineFunctionDataHotness::Cold;
122+
123+ if (MJTI->updateJumpTableEntryHotness (JTI, Hotness))
124+ ++NumChangedJumpTables;
125+ }
112126 }
113127 }
114128 }
115129 return NumChangedJumpTables > 0 ;
116130}
117131
118- bool StaticDataSplitter::splitJumpTables (MachineFunction &MF) {
119- MachineJumpTableInfo *MJTI = MF.getJumpTableInfo ();
120- if (!MJTI || MJTI->getJumpTables ().empty ())
121- return false ;
132+ void StaticDataSplitter::updateStatsWithProfiles (const MachineFunction &MF) {
133+ if (!AreStatisticsEnabled ())
134+ return ;
122135
123- const bool ProfileAvailable = PSI && PSI->hasProfileSummary () && MBFI &&
124- MF.getFunction ().hasProfileData ();
125- auto statOnExit = llvm::make_scope_exit ([&] {
126- if (!AreStatisticsEnabled ())
127- return ;
128-
129- if (!ProfileAvailable) {
130- NumUnknownJumpTables += MJTI->getJumpTables ().size ();
131- return ;
132- }
133-
134- for (size_t JTI = 0 ; JTI < MJTI->getJumpTables ().size (); JTI++) {
135- auto Hotness = MJTI->getJumpTables ()[JTI].Hotness ;
136- if (Hotness == MachineFunctionDataHotness::Hot) {
136+ if (const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo ()) {
137+ for (const auto &JumpTable : MJTI->getJumpTables ()) {
138+ if (JumpTable.Hotness == MachineFunctionDataHotness::Hot) {
137139 ++NumHotJumpTables;
138140 } else {
139- assert (Hotness == MachineFunctionDataHotness::Cold &&
141+ assert (JumpTable. Hotness == MachineFunctionDataHotness::Cold &&
140142 " A jump table is either hot or cold when profile information is "
141143 " available." );
142144 ++NumColdJumpTables;
143145 }
144146 }
145- });
147+ }
148+ }
146149
147- // Place jump tables according to block hotness if function has profile data.
148- if (ProfileAvailable )
149- return splitJumpTablesWithProfiles (MF, *MJTI) ;
150+ void StaticDataSplitter::updateStatsWithoutProfiles ( const MachineFunction &MF) {
151+ if (! AreStatisticsEnabled () )
152+ return ;
150153
151- return true ;
154+ if (const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo ()) {
155+ NumUnknownJumpTables += MJTI->getJumpTables ().size ();
156+ }
152157}
153158
154159char StaticDataSplitter::ID = 0 ;
0 commit comments