diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/BasicBlockSections.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/BasicBlockSections.cpp | 181 |
1 files changed, 21 insertions, 160 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/BasicBlockSections.cpp b/contrib/llvm-project/llvm/lib/CodeGen/BasicBlockSections.cpp index c1901bc46d72..f05f5b9f9947 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/BasicBlockSections.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/BasicBlockSections.cpp @@ -60,7 +60,7 @@ // Basic Block Labels // ================== // -// With -fbasic-block-sections=labels, we emit the offsets of BB addresses of +// With -fbasic-block-sections=labels, we encode the offsets of BB addresses of // every function into the .llvm_bb_addr_map section. Along with the function // symbols, this allows for mapping of virtual addresses in PMU profiles back to // the corresponding basic blocks. This logic is implemented in AsmPrinter. This @@ -69,26 +69,17 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/Optional.h" -#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/CodeGen/BasicBlockSectionsProfileReader.h" #include "llvm/CodeGen/BasicBlockSectionUtils.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/InitializePasses.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/LineIterator.h" -#include "llvm/Support/MemoryBuffer.h" #include "llvm/Target/TargetMachine.h" -using llvm::SmallSet; -using llvm::SmallVector; -using llvm::StringMap; -using llvm::StringRef; using namespace llvm; // Placing the cold clusters in a separate section mitigates against poor @@ -108,41 +99,11 @@ cl::opt<bool> BBSectionsDetectSourceDrift( namespace { -// This struct represents the cluster information for a machine basic block. -struct BBClusterInfo { - // MachineBasicBlock ID. - unsigned MBBNumber; - // Cluster ID this basic block belongs to. - unsigned ClusterID; - // Position of basic block within the cluster. - unsigned PositionInCluster; -}; - -using ProgramBBClusterInfoMapTy = StringMap<SmallVector<BBClusterInfo, 4>>; - class BasicBlockSections : public MachineFunctionPass { public: static char ID; - // This contains the basic-block-sections profile. - const MemoryBuffer *MBuf = nullptr; - - // This encapsulates the BB cluster information for the whole program. - // - // For every function name, it contains the cluster information for (all or - // some of) its basic blocks. The cluster information for every basic block - // includes its cluster ID along with the position of the basic block in that - // cluster. - ProgramBBClusterInfoMapTy ProgramBBClusterInfo; - - // Some functions have alias names. We use this map to find the main alias - // name for which we have mapping in ProgramBBClusterInfo. - StringMap<StringRef> FuncAliasMap; - - BasicBlockSections(const MemoryBuffer *Buf) - : MachineFunctionPass(ID), MBuf(Buf) { - initializeBasicBlockSectionsPass(*PassRegistry::getPassRegistry()); - }; + BasicBlockSectionsProfileReader *BBSectionsProfileReader = nullptr; BasicBlockSections() : MachineFunctionPass(ID) { initializeBasicBlockSectionsPass(*PassRegistry::getPassRegistry()); @@ -154,9 +115,6 @@ public: void getAnalysisUsage(AnalysisUsage &AU) const override; - /// Read profiles of basic blocks if available here. - bool doInitialization(Module &M) override; - /// Identify basic blocks that need separate sections and prepare to emit them /// accordingly. bool runOnMachineFunction(MachineFunction &MF) override; @@ -206,21 +164,18 @@ static void updateBranches( // This function provides the BBCluster information associated with a function. // Returns true if a valid association exists and false otherwise. -static bool getBBClusterInfoForFunction( - const MachineFunction &MF, const StringMap<StringRef> FuncAliasMap, - const ProgramBBClusterInfoMapTy &ProgramBBClusterInfo, +bool getBBClusterInfoForFunction( + const MachineFunction &MF, + BasicBlockSectionsProfileReader *BBSectionsProfileReader, std::vector<Optional<BBClusterInfo>> &V) { - // Get the main alias name for the function. - auto FuncName = MF.getName(); - auto R = FuncAliasMap.find(FuncName); - StringRef AliasName = R == FuncAliasMap.end() ? FuncName : R->second; // Find the assoicated cluster information. - auto P = ProgramBBClusterInfo.find(AliasName); - if (P == ProgramBBClusterInfo.end()) + std::pair<bool, SmallVector<BBClusterInfo, 4>> P = + BBSectionsProfileReader->getBBClusterInfoForFunction(MF.getName()); + if (!P.first) return false; - if (P->second.empty()) { + if (P.second.empty()) { // This indicates that sections are desired for all basic blocks of this // function. We clear the BBClusterInfo vector to denote this. V.clear(); @@ -228,7 +183,7 @@ static bool getBBClusterInfoForFunction( } V.resize(MF.getNumBlockIDs()); - for (auto bbClusterInfo : P->second) { + for (auto bbClusterInfo : P.second) { // Bail out if the cluster information contains invalid MBB numbers. if (bbClusterInfo.MBBNumber >= MF.getNumBlockIDs()) return false; @@ -266,7 +221,7 @@ assignSections(MachineFunction &MF, // set every basic block's section ID equal to its number (basic block // id). This further ensures that basic blocks are ordered canonically. MBB.setSectionID({static_cast<unsigned int>(MBB.getNumber())}); - } else if (FuncBBClusterInfo[MBB.getNumber()].hasValue()) + } else if (FuncBBClusterInfo[MBB.getNumber()]) MBB.setSectionID(FuncBBClusterInfo[MBB.getNumber()]->ClusterID); else { // BB goes into the special cold section if it is not specified in the @@ -279,9 +234,8 @@ assignSections(MachineFunction &MF, // If we already have one cluster containing eh_pads, this must be updated // to ExceptionSectionID. Otherwise, we set it equal to the current // section ID. - EHPadsSectionID = EHPadsSectionID.hasValue() - ? MBBSectionID::ExceptionSectionID - : MBB.getSectionID(); + EHPadsSectionID = EHPadsSectionID ? MBBSectionID::ExceptionSectionID + : MBB.getSectionID(); } } @@ -290,7 +244,7 @@ assignSections(MachineFunction &MF, if (EHPadsSectionID == MBBSectionID::ExceptionSectionID) for (auto &MBB : MF) if (MBB.isEHPad()) - MBB.setSectionID(EHPadsSectionID.getValue()); + MBB.setSectionID(*EHPadsSectionID); } void llvm::sortBasicBlocksAndUpdateBranches( @@ -377,9 +331,11 @@ bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) { return true; } + BBSectionsProfileReader = &getAnalysis<BasicBlockSectionsProfileReader>(); + std::vector<Optional<BBClusterInfo>> FuncBBClusterInfo; if (BBSectionsType == BasicBlockSection::List && - !getBBClusterInfoForFunction(MF, FuncAliasMap, ProgramBBClusterInfo, + !getBBClusterInfoForFunction(MF, BBSectionsProfileReader, FuncBBClusterInfo)) return true; MF.setBBSectionsType(BBSectionsType); @@ -427,107 +383,12 @@ bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) { return true; } -// Basic Block Sections can be enabled for a subset of machine basic blocks. -// This is done by passing a file containing names of functions for which basic -// block sections are desired. Additionally, machine basic block ids of the -// functions can also be specified for a finer granularity. Moreover, a cluster -// of basic blocks could be assigned to the same section. -// A file with basic block sections for all of function main and three blocks -// for function foo (of which 1 and 2 are placed in a cluster) looks like this: -// ---------------------------- -// list.txt: -// !main -// !foo -// !!1 2 -// !!4 -static Error getBBClusterInfo(const MemoryBuffer *MBuf, - ProgramBBClusterInfoMapTy &ProgramBBClusterInfo, - StringMap<StringRef> &FuncAliasMap) { - assert(MBuf); - line_iterator LineIt(*MBuf, /*SkipBlanks=*/true, /*CommentMarker=*/'#'); - - auto invalidProfileError = [&](auto Message) { - return make_error<StringError>( - Twine("Invalid profile " + MBuf->getBufferIdentifier() + " at line " + - Twine(LineIt.line_number()) + ": " + Message), - inconvertibleErrorCode()); - }; - - auto FI = ProgramBBClusterInfo.end(); - - // Current cluster ID corresponding to this function. - unsigned CurrentCluster = 0; - // Current position in the current cluster. - unsigned CurrentPosition = 0; - - // Temporary set to ensure every basic block ID appears once in the clusters - // of a function. - SmallSet<unsigned, 4> FuncBBIDs; - - for (; !LineIt.is_at_eof(); ++LineIt) { - StringRef S(*LineIt); - if (S[0] == '@') - continue; - // Check for the leading "!" - if (!S.consume_front("!") || S.empty()) - break; - // Check for second "!" which indicates a cluster of basic blocks. - if (S.consume_front("!")) { - if (FI == ProgramBBClusterInfo.end()) - return invalidProfileError( - "Cluster list does not follow a function name specifier."); - SmallVector<StringRef, 4> BBIndexes; - S.split(BBIndexes, ' '); - // Reset current cluster position. - CurrentPosition = 0; - for (auto BBIndexStr : BBIndexes) { - unsigned long long BBIndex; - if (getAsUnsignedInteger(BBIndexStr, 10, BBIndex)) - return invalidProfileError(Twine("Unsigned integer expected: '") + - BBIndexStr + "'."); - if (!FuncBBIDs.insert(BBIndex).second) - return invalidProfileError(Twine("Duplicate basic block id found '") + - BBIndexStr + "'."); - if (!BBIndex && CurrentPosition) - return invalidProfileError("Entry BB (0) does not begin a cluster."); - - FI->second.emplace_back(BBClusterInfo{ - ((unsigned)BBIndex), CurrentCluster, CurrentPosition++}); - } - CurrentCluster++; - } else { // This is a function name specifier. - // Function aliases are separated using '/'. We use the first function - // name for the cluster info mapping and delegate all other aliases to - // this one. - SmallVector<StringRef, 4> Aliases; - S.split(Aliases, '/'); - for (size_t i = 1; i < Aliases.size(); ++i) - FuncAliasMap.try_emplace(Aliases[i], Aliases.front()); - - // Prepare for parsing clusters of this function name. - // Start a new cluster map for this function name. - FI = ProgramBBClusterInfo.try_emplace(Aliases.front()).first; - CurrentCluster = 0; - FuncBBIDs.clear(); - } - } - return Error::success(); -} - -bool BasicBlockSections::doInitialization(Module &M) { - if (!MBuf) - return false; - if (auto Err = getBBClusterInfo(MBuf, ProgramBBClusterInfo, FuncAliasMap)) - report_fatal_error(std::move(Err)); - return false; -} - void BasicBlockSections::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); + AU.addRequired<BasicBlockSectionsProfileReader>(); MachineFunctionPass::getAnalysisUsage(AU); } -MachineFunctionPass * -llvm::createBasicBlockSectionsPass(const MemoryBuffer *Buf) { - return new BasicBlockSections(Buf); +MachineFunctionPass *llvm::createBasicBlockSectionsPass() { + return new BasicBlockSections(); } |