6969// ===----------------------------------------------------------------------===//
7070
7171#include " llvm/ADT/Optional.h"
72- #include " llvm/ADT/SmallSet.h"
7372#include " llvm/ADT/SmallVector.h"
74- #include " llvm/ADT/StringMap.h"
7573#include " llvm/ADT/StringRef.h"
74+ #include " llvm/CodeGen/BasicBlockSectionsProfileReader.h"
7675#include " llvm/CodeGen/BasicBlockSectionUtils.h"
7776#include " llvm/CodeGen/MachineFunction.h"
7877#include " llvm/CodeGen/MachineFunctionPass.h"
7978#include " llvm/CodeGen/Passes.h"
8079#include " llvm/CodeGen/TargetInstrInfo.h"
8180#include " llvm/InitializePasses.h"
82- #include " llvm/Support/Error.h"
83- #include " llvm/Support/LineIterator.h"
84- #include " llvm/Support/MemoryBuffer.h"
8581#include " llvm/Target/TargetMachine.h"
8682
87- using llvm::SmallSet;
88- using llvm::SmallVector;
89- using llvm::StringMap;
90- using llvm::StringRef;
9183using namespace llvm ;
9284
9385// Placing the cold clusters in a separate section mitigates against poor
@@ -107,41 +99,11 @@ cl::opt<bool> BBSectionsDetectSourceDrift(
10799
108100namespace {
109101
110- // This struct represents the cluster information for a machine basic block.
111- struct BBClusterInfo {
112- // MachineBasicBlock ID.
113- unsigned MBBNumber;
114- // Cluster ID this basic block belongs to.
115- unsigned ClusterID;
116- // Position of basic block within the cluster.
117- unsigned PositionInCluster;
118- };
119-
120- using ProgramBBClusterInfoMapTy = StringMap<SmallVector<BBClusterInfo, 4 >>;
121-
122102class BasicBlockSections : public MachineFunctionPass {
123103public:
124104 static char ID;
125105
126- // This contains the basic-block-sections profile.
127- const MemoryBuffer *MBuf = nullptr ;
128-
129- // This encapsulates the BB cluster information for the whole program.
130- //
131- // For every function name, it contains the cluster information for (all or
132- // some of) its basic blocks. The cluster information for every basic block
133- // includes its cluster ID along with the position of the basic block in that
134- // cluster.
135- ProgramBBClusterInfoMapTy ProgramBBClusterInfo;
136-
137- // Some functions have alias names. We use this map to find the main alias
138- // name for which we have mapping in ProgramBBClusterInfo.
139- StringMap<StringRef> FuncAliasMap;
140-
141- BasicBlockSections (const MemoryBuffer *Buf)
142- : MachineFunctionPass(ID), MBuf(Buf) {
143- initializeBasicBlockSectionsPass (*PassRegistry::getPassRegistry ());
144- };
106+ BasicBlockSectionsProfileReader *BBSectionsProfileReader = nullptr ;
145107
146108 BasicBlockSections () : MachineFunctionPass(ID) {
147109 initializeBasicBlockSectionsPass (*PassRegistry::getPassRegistry ());
@@ -153,9 +115,6 @@ class BasicBlockSections : public MachineFunctionPass {
153115
154116 void getAnalysisUsage (AnalysisUsage &AU) const override ;
155117
156- // / Read profiles of basic blocks if available here.
157- bool doInitialization (Module &M) override ;
158-
159118 // / Identify basic blocks that need separate sections and prepare to emit them
160119 // / accordingly.
161120 bool runOnMachineFunction (MachineFunction &MF) override ;
@@ -205,29 +164,26 @@ static void updateBranches(
205164
206165// This function provides the BBCluster information associated with a function.
207166// Returns true if a valid association exists and false otherwise.
208- static bool getBBClusterInfoForFunction (
209- const MachineFunction &MF, const StringMap<StringRef> FuncAliasMap,
210- const ProgramBBClusterInfoMapTy &ProgramBBClusterInfo ,
167+ bool getBBClusterInfoForFunction (
168+ const MachineFunction &MF,
169+ BasicBlockSectionsProfileReader *BBSectionsProfileReader ,
211170 std::vector<Optional<BBClusterInfo>> &V) {
212- // Get the main alias name for the function.
213- auto FuncName = MF.getName ();
214- auto R = FuncAliasMap.find (FuncName);
215- StringRef AliasName = R == FuncAliasMap.end () ? FuncName : R->second ;
216171
217172 // Find the assoicated cluster information.
218- auto P = ProgramBBClusterInfo.find (AliasName);
219- if (P == ProgramBBClusterInfo.end ())
173+ std::pair<bool , SmallVector<BBClusterInfo, 4 >> P =
174+ BBSectionsProfileReader->getBBClusterInfoForFunction (MF.getName ());
175+ if (!P.first )
220176 return false ;
221177
222- if (P-> second .empty ()) {
178+ if (P. second .empty ()) {
223179 // This indicates that sections are desired for all basic blocks of this
224180 // function. We clear the BBClusterInfo vector to denote this.
225181 V.clear ();
226182 return true ;
227183 }
228184
229185 V.resize (MF.getNumBlockIDs ());
230- for (auto bbClusterInfo : P-> second ) {
186+ for (auto bbClusterInfo : P. second ) {
231187 // Bail out if the cluster information contains invalid MBB numbers.
232188 if (bbClusterInfo.MBBNumber >= MF.getNumBlockIDs ())
233189 return false ;
@@ -376,9 +332,11 @@ bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) {
376332 return true ;
377333 }
378334
335+ BBSectionsProfileReader = &getAnalysis<BasicBlockSectionsProfileReader>();
336+
379337 std::vector<Optional<BBClusterInfo>> FuncBBClusterInfo;
380338 if (BBSectionsType == BasicBlockSection::List &&
381- !getBBClusterInfoForFunction (MF, FuncAliasMap, ProgramBBClusterInfo ,
339+ !getBBClusterInfoForFunction (MF, BBSectionsProfileReader ,
382340 FuncBBClusterInfo))
383341 return true ;
384342 MF.setBBSectionsType (BBSectionsType);
@@ -426,107 +384,12 @@ bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) {
426384 return true ;
427385}
428386
429- // Basic Block Sections can be enabled for a subset of machine basic blocks.
430- // This is done by passing a file containing names of functions for which basic
431- // block sections are desired. Additionally, machine basic block ids of the
432- // functions can also be specified for a finer granularity. Moreover, a cluster
433- // of basic blocks could be assigned to the same section.
434- // A file with basic block sections for all of function main and three blocks
435- // for function foo (of which 1 and 2 are placed in a cluster) looks like this:
436- // ----------------------------
437- // list.txt:
438- // !main
439- // !foo
440- // !!1 2
441- // !!4
442- static Error getBBClusterInfo (const MemoryBuffer *MBuf,
443- ProgramBBClusterInfoMapTy &ProgramBBClusterInfo,
444- StringMap<StringRef> &FuncAliasMap) {
445- assert (MBuf);
446- line_iterator LineIt (*MBuf, /* SkipBlanks=*/ true , /* CommentMarker=*/ ' #' );
447-
448- auto invalidProfileError = [&](auto Message) {
449- return make_error<StringError>(
450- Twine (" Invalid profile " + MBuf->getBufferIdentifier () + " at line " +
451- Twine (LineIt.line_number ()) + " : " + Message),
452- inconvertibleErrorCode ());
453- };
454-
455- auto FI = ProgramBBClusterInfo.end ();
456-
457- // Current cluster ID corresponding to this function.
458- unsigned CurrentCluster = 0 ;
459- // Current position in the current cluster.
460- unsigned CurrentPosition = 0 ;
461-
462- // Temporary set to ensure every basic block ID appears once in the clusters
463- // of a function.
464- SmallSet<unsigned , 4 > FuncBBIDs;
465-
466- for (; !LineIt.is_at_eof (); ++LineIt) {
467- StringRef S (*LineIt);
468- if (S[0 ] == ' @' )
469- continue ;
470- // Check for the leading "!"
471- if (!S.consume_front (" !" ) || S.empty ())
472- break ;
473- // Check for second "!" which indicates a cluster of basic blocks.
474- if (S.consume_front (" !" )) {
475- if (FI == ProgramBBClusterInfo.end ())
476- return invalidProfileError (
477- " Cluster list does not follow a function name specifier." );
478- SmallVector<StringRef, 4 > BBIndexes;
479- S.split (BBIndexes, ' ' );
480- // Reset current cluster position.
481- CurrentPosition = 0 ;
482- for (auto BBIndexStr : BBIndexes) {
483- unsigned long long BBIndex;
484- if (getAsUnsignedInteger (BBIndexStr, 10 , BBIndex))
485- return invalidProfileError (Twine (" Unsigned integer expected: '" ) +
486- BBIndexStr + " '." );
487- if (!FuncBBIDs.insert (BBIndex).second )
488- return invalidProfileError (Twine (" Duplicate basic block id found '" ) +
489- BBIndexStr + " '." );
490- if (!BBIndex && CurrentPosition)
491- return invalidProfileError (" Entry BB (0) does not begin a cluster." );
492-
493- FI->second .emplace_back (BBClusterInfo{
494- ((unsigned )BBIndex), CurrentCluster, CurrentPosition++});
495- }
496- CurrentCluster++;
497- } else { // This is a function name specifier.
498- // Function aliases are separated using '/'. We use the first function
499- // name for the cluster info mapping and delegate all other aliases to
500- // this one.
501- SmallVector<StringRef, 4 > Aliases;
502- S.split (Aliases, ' /' );
503- for (size_t i = 1 ; i < Aliases.size (); ++i)
504- FuncAliasMap.try_emplace (Aliases[i], Aliases.front ());
505-
506- // Prepare for parsing clusters of this function name.
507- // Start a new cluster map for this function name.
508- FI = ProgramBBClusterInfo.try_emplace (Aliases.front ()).first ;
509- CurrentCluster = 0 ;
510- FuncBBIDs.clear ();
511- }
512- }
513- return Error::success ();
514- }
515-
516- bool BasicBlockSections::doInitialization (Module &M) {
517- if (!MBuf)
518- return false ;
519- if (auto Err = getBBClusterInfo (MBuf, ProgramBBClusterInfo, FuncAliasMap))
520- report_fatal_error (std::move (Err));
521- return false ;
522- }
523-
524387void BasicBlockSections::getAnalysisUsage (AnalysisUsage &AU) const {
525388 AU.setPreservesAll ();
389+ AU.addRequired <BasicBlockSectionsProfileReader>();
526390 MachineFunctionPass::getAnalysisUsage (AU);
527391}
528392
529- MachineFunctionPass *
530- llvm::createBasicBlockSectionsPass (const MemoryBuffer *Buf) {
531- return new BasicBlockSections (Buf);
393+ MachineFunctionPass *llvm::createBasicBlockSectionsPass () {
394+ return new BasicBlockSections ();
532395}
0 commit comments