@@ -58,12 +58,13 @@ template <class D> struct BPOrderer {
5858 // program startup.
5959 // * compressionSortStartupFunctions: if profilePath is specified, allocate
6060 // extra utility vertices to prioritize nearby function similarity.
61- auto computeOrder (llvm::StringRef profilePath, bool forFunctionCompression,
62- bool forDataCompression,
63- bool compressionSortStartupFunctions, bool verbose,
64- llvm::ArrayRef<Section *> sections,
65- const DenseMap<CachedHashStringRef, std::set<unsigned >>
66- &rootSymbolToSectionIdxs)
61+ auto
62+ computeOrder (llvm::StringRef profilePath,
63+ llvm::ArrayRef<llvm::GlobPattern> compressionSortSectionGlobs,
64+ bool compressionSortStartupFunctions, bool verbose,
65+ llvm::ArrayRef<Section *> sections,
66+ const DenseMap<CachedHashStringRef, std::set<unsigned >>
67+ &rootSymbolToSectionIdxs)
6768 -> llvm::DenseMap<const Section *, int >;
6869
6970 std::optional<StringRef> static getResolvedLinkageName (StringRef name) {
@@ -150,7 +151,7 @@ static SmallVector<std::pair<unsigned, UtilityNodes>> getUnsForCompression(
150151
151152template <class D >
152153auto BPOrderer<D>::computeOrder(
153- StringRef profilePath, bool forFunctionCompression, bool forDataCompression ,
154+ StringRef profilePath, ArrayRef<GlobPattern> compressionSortSectionGlobs ,
154155 bool compressionSortStartupFunctions, bool verbose,
155156 ArrayRef<Section *> sections,
156157 const DenseMap<CachedHashStringRef, std::set<unsigned >>
@@ -221,19 +222,20 @@ auto BPOrderer<D>::computeOrder(
221222 }
222223 }
223224
224- SmallVector< unsigned > sectionIdxsForFunctionCompression,
225- sectionIdxsForDataCompression ;
225+ // Using map<> to guarantee that iteration order is deterministic
226+ std::map<std::string, SmallVector< unsigned >> sectionNameToIdxsForCompression ;
226227 for (unsigned sectionIdx = 0 ; sectionIdx < sections.size (); sectionIdx++) {
227228 if (startupSectionIdxUNs.count (sectionIdx))
228229 continue ;
229230 const auto *isec = sections[sectionIdx];
230- if (D::isCodeSection (*isec)) {
231- if (forFunctionCompression)
232- sectionIdxsForFunctionCompression.push_back (sectionIdx);
233- } else {
234- if (forDataCompression)
235- sectionIdxsForDataCompression.push_back (sectionIdx);
236- }
231+ std::string sectionName = D::getSectionName (*isec);
232+ bool isMatch =
233+ llvm::any_of (compressionSortSectionGlobs, [&](const GlobPattern &glob) {
234+ return glob.match (sectionName);
235+ });
236+ if (!isMatch)
237+ continue ;
238+ sectionNameToIdxsForCompression[sectionName].push_back (sectionIdx);
237239 }
238240
239241 if (compressionSortStartupFunctions) {
@@ -252,51 +254,43 @@ auto BPOrderer<D>::computeOrder(
252254 }
253255 }
254256
255- // Map a section index (order directly) to a list of duplicate section indices
256- // (not ordered directly).
257+ // Map a section index (ordered directly) to a list of duplicate section
258+ // indices (not ordered directly).
257259 DenseMap<unsigned , SmallVector<unsigned , 0 >> duplicateSectionIdxs;
258- auto unsForFunctionCompression = getUnsForCompression<D>(
259- sections, sectionToIdx, sectionIdxsForFunctionCompression,
260- &duplicateSectionIdxs, maxUN);
261- auto unsForDataCompression = getUnsForCompression<D>(
262- sections, sectionToIdx, sectionIdxsForDataCompression,
263- &duplicateSectionIdxs, maxUN);
264-
265- std::vector<BPFunctionNode> nodesForStartup, nodesForFunctionCompression,
266- nodesForDataCompression;
260+ SmallVector<std::vector<BPFunctionNode>> nodesForCompression;
261+ for (auto &[name, idxs] : sectionNameToIdxsForCompression) {
262+ auto &nodes = nodesForCompression.emplace_back ();
263+ auto uns = getUnsForCompression<D>(sections, sectionToIdx, idxs,
264+ &duplicateSectionIdxs, maxUN);
265+ for (auto &[sectionIdx, uns] : uns)
266+ nodes.emplace_back (sectionIdx, uns);
267+ // Sort compression nodes by their Id (which is the section index) because
268+ // the input linker order tends to be not bad.
269+ llvm::sort (nodes, [](auto &L, auto &R) { return L.Id < R.Id ; });
270+ }
271+
272+ std::vector<BPFunctionNode> nodesForStartup;
267273 for (auto &[sectionIdx, uns] : startupSectionIdxUNs)
268274 nodesForStartup.emplace_back (sectionIdx, uns);
269- for (auto &[sectionIdx, uns] : unsForFunctionCompression)
270- nodesForFunctionCompression.emplace_back (sectionIdx, uns);
271- for (auto &[sectionIdx, uns] : unsForDataCompression)
272- nodesForDataCompression.emplace_back (sectionIdx, uns);
273275
274276 // Use the first timestamp to define the initial order for startup nodes.
275277 llvm::sort (nodesForStartup, [§ionIdxToTimestamp](auto &L, auto &R) {
276278 return std::make_pair (sectionIdxToTimestamp[L.Id ], L.Id ) <
277279 std::make_pair (sectionIdxToTimestamp[R.Id ], R.Id );
278280 });
279- // Sort compression nodes by their Id (which is the section index) because the
280- // input linker order tends to be not bad.
281- llvm::sort (nodesForFunctionCompression,
282- [](auto &L, auto &R) { return L.Id < R.Id ; });
283- llvm::sort (nodesForDataCompression,
284- [](auto &L, auto &R) { return L.Id < R.Id ; });
285281
286282 {
287283 TimeTraceScope timeScope (" Balanced Partitioning" );
288284 BalancedPartitioningConfig config;
289285 BalancedPartitioning bp (config);
290286 bp.run (nodesForStartup);
291- bp. run (nodesForFunctionCompression);
292- bp.run (nodesForDataCompression );
287+ for ( auto &nodes : nodesForCompression)
288+ bp.run (nodes );
293289 }
294290
295291 unsigned numStartupSections = 0 , startupSize = 0 ;
296- unsigned numCodeCompressionSections = 0 , codeCompressionSize = 0 ;
297- unsigned numDuplicateCodeSections = 0 , duplicateCodeSize = 0 ;
298- unsigned numDataCompressionSections = 0 , dataCompressionSize = 0 ;
299- unsigned numDuplicateDataSections = 0 , duplicateDataSize = 0 ;
292+ unsigned numCompressionSections = 0 , compressionSize = 0 ;
293+ unsigned numDuplicateCompressionSections = 0 , duplicateCompressionSize = 0 ;
300294 SetVector<const Section *> orderedSections;
301295 // Order startup functions,
302296 for (auto &node : nodesForStartup) {
@@ -306,63 +300,49 @@ auto BPOrderer<D>::computeOrder(
306300 ++numStartupSections;
307301 }
308302 }
309- // then functions for compression,
310- for (auto &node : nodesForFunctionCompression) {
311- const auto *isec = sections[node.Id ];
312- if (orderedSections.insert (isec)) {
313- codeCompressionSize += D::getSize (*isec);
314- ++numCodeCompressionSections;
315- }
316- auto It = duplicateSectionIdxs.find (node.Id );
317- if (It == duplicateSectionIdxs.end ())
318- continue ;
319- for (auto dupSecIdx : It->getSecond ()) {
320- const auto *dupIsec = sections[dupSecIdx];
321- if (orderedSections.insert (dupIsec)) {
322- duplicateCodeSize += D::getSize (*dupIsec);
323- ++numDuplicateCodeSections;
303+ // then sections for compression.
304+ for (const auto &nodes : nodesForCompression) {
305+ for (auto &node : nodes) {
306+ const auto *isec = sections[node.Id ];
307+ if (orderedSections.insert (isec)) {
308+ compressionSize += D::getSize (*isec);
309+ ++numCompressionSections;
324310 }
325- }
326- }
327- // then data for compression.
328- for (auto &node : nodesForDataCompression) {
329- const auto *isec = sections[node.Id ];
330- if (orderedSections.insert (isec)) {
331- dataCompressionSize += D::getSize (*isec);
332- ++numDataCompressionSections;
333- }
334- auto It = duplicateSectionIdxs.find (node.Id );
335- if (It == duplicateSectionIdxs.end ())
336- continue ;
337- for (auto dupSecIdx : It->getSecond ()) {
338- const auto *dupIsec = sections[dupSecIdx];
339- if (orderedSections.insert (dupIsec)) {
340- duplicateDataSize += D::getSize (*dupIsec);
341- ++numDuplicateDataSections;
311+ auto It = duplicateSectionIdxs.find (node.Id );
312+ if (It == duplicateSectionIdxs.end ())
313+ continue ;
314+ for (auto dupSecIdx : It->getSecond ()) {
315+ const auto *dupIsec = sections[dupSecIdx];
316+ if (orderedSections.insert (dupIsec)) {
317+ duplicateCompressionSize += D::getSize (*dupIsec);
318+ ++numDuplicateCompressionSections;
319+ }
342320 }
343321 }
344322 }
345323
346324 if (verbose) {
347- unsigned numTotalOrderedSections =
348- numStartupSections + numCodeCompressionSections +
349- numDuplicateCodeSections + numDataCompressionSections +
350- numDuplicateDataSections;
351- unsigned totalOrderedSize = startupSize + codeCompressionSize +
352- duplicateCodeSize + dataCompressionSize +
353- duplicateDataSize;
325+ unsigned numTotalOrderedSections = numStartupSections +
326+ numCompressionSections +
327+ numDuplicateCompressionSections;
328+ unsigned totalOrderedSize =
329+ startupSize + compressionSize + duplicateCompressionSize;
330+ SmallVector<StringRef> sectionNames;
331+ for (auto &[name, idxs] : sectionNameToIdxsForCompression)
332+ sectionNames.push_back (name);
333+ llvm::sort (sectionNames);
354334 dbgs () << " Ordered " << numTotalOrderedSections << " sections ("
355335 << totalOrderedSize << " bytes) using balanced partitioning:\n " ;
356336 dbgs () << " Functions for startup: " << numStartupSections << " ("
357337 << startupSize << " bytes)\n " ;
358- dbgs () << " Functions for compression: " << numCodeCompressionSections
359- << " ( " << codeCompressionSize << " bytes)\n " ;
360- dbgs () << " Duplicate functions: " << numDuplicateCodeSections << " ( "
361- << duplicateCodeSize << " bytes) \n " ;
362- dbgs () << " Data for compression: " << numDataCompressionSections << " ( "
363- << dataCompressionSize << " bytes) \n " ;
364- dbgs () << " Duplicate data: " << numDuplicateDataSections << " ("
365- << duplicateDataSize << " bytes)\n " ;
338+ dbgs () << " Sections for compression: " << numCompressionSections << " ( "
339+ << compressionSize << " bytes)\n " ;
340+ for (StringRef name : sectionNames)
341+ dbgs () << name << " " ;
342+ dbgs () << " \n " ;
343+ dbgs () << " Duplicate compression sections: "
344+ << numDuplicateCompressionSections << " ("
345+ << duplicateCompressionSize << " bytes)\n " ;
366346
367347 if (!profilePath.empty ()) {
368348 // Evaluate this function order for startup
0 commit comments