-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[CodeGen][StaticDataSplitter]Support constant pool partitioning #129781
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 15 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
8eea1ea
[CodeGen][StaticDataPartitioning]Place module-internal global variabl…
mingmingl-llvm 93d9881
add comment for bss22 and data3
mingmingl-llvm 5cbe8f8
run 'git merge main'
mingmingl-llvm 8f21570
apply code review suggestions
mingmingl-llvm f07d34d
record global variable section prefix updates as module updates
mingmingl-llvm 4e096e9
merge with main, and resolve code review comments
mingmingl-llvm 4a2a881
remove blank line
mingmingl-llvm 1f50494
Implement module-wide analysis of global variable hotness.
mingmingl-llvm 967dc03
run 'git merge main'
mingmingl-llvm 072c44f
[CodeGen][StaticDataSplitter]Support constant pool partitioning
mingmingl-llvm 9fae47c
resolve comments
mingmingl-llvm 9302b2b
port code de-duplication based on feedback in the follow up patch (ht…
mingmingl-llvm 23fd549
merge the base branch and resolve comments
mingmingl-llvm 4f91e5c
resolve comments
mingmingl-llvm 99cd531
clang-format
mingmingl-llvm 64aaadc
merge main branch
mingmingl-llvm 5fa795e
clang format
mingmingl-llvm File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| #ifndef LLVM_ANALYSIS_STATICDATAPROFILEINFO_H | ||
| #define LLVM_ANALYSIS_STATICDATAPROFILEINFO_H | ||
|
|
||
| #include "llvm/ADT/DenseMap.h" | ||
| #include "llvm/ADT/DenseSet.h" | ||
| #include "llvm/IR/Constant.h" | ||
| #include "llvm/Pass.h" | ||
|
|
||
| namespace llvm { | ||
|
|
||
| /// A class that holds the constants that represent static data and their | ||
| /// profile information and provides methods to operate on them. | ||
| class StaticDataProfileInfo { | ||
| public: | ||
| /// Accummulate the profile count of a constant that will be lowered to static | ||
| /// data sections. | ||
| DenseMap<const Constant *, uint64_t> ConstantProfileCounts; | ||
|
|
||
| /// Keeps track of the constants that are seen at least once without profile | ||
| /// counts. | ||
| DenseSet<const Constant *> ConstantWithoutCounts; | ||
|
|
||
| public: | ||
| StaticDataProfileInfo() = default; | ||
|
|
||
| /// If \p Count is not nullopt, add it to the profile count of the constant \p | ||
| /// C in a saturating way, and clamp the count to \p getInstrMaxCountValue if | ||
| /// the result exceeds it. Otherwise, mark the constant as having no profile | ||
| /// count. | ||
| void addConstantProfileCount(const Constant *C, | ||
| std::optional<uint64_t> Count); | ||
|
|
||
| /// If \p C has a count, return it. Otherwise, return std::nullopt. | ||
| std::optional<uint64_t> getConstantProfileCount(const Constant *C) const; | ||
|
|
||
| /// Return true if the constant \p C is seen at least once without profiles. | ||
| bool hasUnknownCount(const Constant *C) const { | ||
| return ConstantWithoutCounts.count(C); | ||
| } | ||
| }; | ||
|
|
||
| /// This wraps the StaticDataProfileInfo object as an immutable pass, for a | ||
| /// backend pass to operate on. | ||
| class StaticDataProfileInfoWrapperPass : public ImmutablePass { | ||
| public: | ||
| static char ID; | ||
| StaticDataProfileInfoWrapperPass(); | ||
| bool doInitialization(Module &M) override; | ||
| bool doFinalization(Module &M) override; | ||
|
|
||
| StaticDataProfileInfo &getStaticDataProfileInfo() { return *Info; } | ||
| const StaticDataProfileInfo &getStaticDataProfileInfo() const { | ||
| return *Info; | ||
| } | ||
|
|
||
| /// This pass provides StaticDataProfileInfo for reads/writes but does not | ||
| /// modify \p M or other analysis. All analysis are preserved. | ||
| void getAnalysisUsage(AnalysisUsage &AU) const override { | ||
| AU.setPreservesAll(); | ||
| } | ||
|
|
||
| private: | ||
| std::unique_ptr<StaticDataProfileInfo> Info; | ||
| }; | ||
|
|
||
| } // namespace llvm | ||
|
|
||
| #endif // LLVM_ANALYSIS_STATICDATAPROFILEINFO_H |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| #include "llvm/Analysis/StaticDataProfileInfo.h" | ||
| #include "llvm/IR/Constant.h" | ||
| #include "llvm/IR/GlobalVariable.h" | ||
| #include "llvm/InitializePasses.h" | ||
| #include "llvm/ProfileData/InstrProf.h" | ||
| #include <sys/types.h> | ||
|
|
||
| using namespace llvm; | ||
| void StaticDataProfileInfo::addConstantProfileCount( | ||
| const Constant *C, std::optional<uint64_t> Count) { | ||
| if (!Count) { | ||
| ConstantWithoutCounts.insert(C); | ||
| return; | ||
| } | ||
| uint64_t &OriginalCount = ConstantProfileCounts[C]; | ||
| OriginalCount += llvm::SaturatingAdd(*Count, OriginalCount); | ||
| // Clamp the count to getInstrMaxCountValue. InstrFDO reserves a few | ||
| // large values for special use. | ||
| if (OriginalCount > getInstrMaxCountValue()) | ||
| OriginalCount = getInstrMaxCountValue(); | ||
| } | ||
|
|
||
| std::optional<uint64_t> | ||
| StaticDataProfileInfo::getConstantProfileCount(const Constant *C) const { | ||
| auto I = ConstantProfileCounts.find(C); | ||
| if (I == ConstantProfileCounts.end()) | ||
| return std::nullopt; | ||
| return I->second; | ||
| } | ||
|
|
||
| bool StaticDataProfileInfoWrapperPass::doInitialization(Module &M) { | ||
| Info.reset(new StaticDataProfileInfo()); | ||
| return false; | ||
| } | ||
|
|
||
| bool StaticDataProfileInfoWrapperPass::doFinalization(Module &M) { | ||
| Info.reset(); | ||
| return false; | ||
| } | ||
|
|
||
| INITIALIZE_PASS(StaticDataProfileInfoWrapperPass, "static-data-profile-info", | ||
| "Static Data Profile Info", false, true) | ||
|
|
||
| StaticDataProfileInfoWrapperPass::StaticDataProfileInfoWrapperPass() | ||
| : ImmutablePass(ID) { | ||
| initializeStaticDataProfileInfoWrapperPassPass( | ||
| *PassRegistry::getPassRegistry()); | ||
| } | ||
|
|
||
| char StaticDataProfileInfoWrapperPass::ID = 0; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| //===- StaticDataAnnotator - Annotate static data's section prefix --------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // To reason about module-wide data hotness in a module granularity, this file | ||
| // implements a module pass StaticDataAnnotator to work coordinately with the | ||
| // StaticDataSplitter pass. | ||
| // | ||
| // The StaticDataSplitter pass is a machine function pass. It analyzes data | ||
| // hotness based on code and adds counters in the StaticDataProfileInfo. | ||
| // The StaticDataAnnotator pass is a module pass. It iterates global variables | ||
| // in the module, looks up counters from StaticDataProfileInfo and sets the | ||
| // section prefix based on profiles. | ||
| // | ||
| // The three-pass structure is implemented for practical reasons, to work around | ||
| // the limitation that a module pass based on legacy pass manager cannot make | ||
| // use of MachineBlockFrequencyInfo analysis. In the future, we can consider | ||
| // porting the StaticDataSplitter pass to a module-pass using the new pass | ||
| // manager framework. That way, analysis are lazily computed as opposed to | ||
| // eagerly scheduled, and a module pass can use MachineBlockFrequencyInfo. | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "llvm/Analysis/ProfileSummaryInfo.h" | ||
| #include "llvm/Analysis/StaticDataProfileInfo.h" | ||
| #include "llvm/CodeGen/Passes.h" | ||
| #include "llvm/IR/Analysis.h" | ||
| #include "llvm/IR/Module.h" | ||
| #include "llvm/IR/PassManager.h" | ||
| #include "llvm/InitializePasses.h" | ||
| #include "llvm/Pass.h" | ||
| #include "llvm/Support/raw_ostream.h" | ||
|
|
||
| #define DEBUG_TYPE "static-data-annotator" | ||
|
|
||
| using namespace llvm; | ||
|
|
||
| class StaticDataAnnotator : public ModulePass { | ||
| public: | ||
| static char ID; | ||
|
|
||
| StaticDataProfileInfo *SDPI = nullptr; | ||
| const ProfileSummaryInfo *PSI = nullptr; | ||
|
|
||
| StaticDataAnnotator() : ModulePass(ID) { | ||
| initializeStaticDataAnnotatorPass(*PassRegistry::getPassRegistry()); | ||
| } | ||
|
|
||
| void getAnalysisUsage(AnalysisUsage &AU) const override { | ||
| AU.addRequired<StaticDataProfileInfoWrapperPass>(); | ||
| AU.addRequired<ProfileSummaryInfoWrapperPass>(); | ||
| AU.setPreservesAll(); | ||
| ModulePass::getAnalysisUsage(AU); | ||
| } | ||
|
|
||
| StringRef getPassName() const override { return "Static Data Annotator"; } | ||
|
|
||
| bool runOnModule(Module &M) override; | ||
| }; | ||
|
|
||
| // Returns true if the global variable already has a section prefix that is the | ||
| // same as `Prefix`. | ||
| static bool alreadyHasSectionPrefix(const GlobalVariable &GV, | ||
| StringRef Prefix) { | ||
| std::optional<StringRef> SectionPrefix = GV.getSectionPrefix(); | ||
| return SectionPrefix && (*SectionPrefix == Prefix); | ||
| } | ||
|
|
||
| bool StaticDataAnnotator::runOnModule(Module &M) { | ||
| SDPI = &getAnalysis<StaticDataProfileInfoWrapperPass>() | ||
| .getStaticDataProfileInfo(); | ||
| PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI(); | ||
|
|
||
| if (!PSI->hasProfileSummary()) | ||
| return false; | ||
|
|
||
| bool Changed = false; | ||
| for (auto &GV : M.globals()) { | ||
| if (GV.isDeclarationForLinker()) | ||
| continue; | ||
|
|
||
| // Skip global variables without profile counts. The module may not be | ||
| // profiled or instrumented. | ||
| auto Count = SDPI->getConstantProfileCount(&GV); | ||
| if (!Count) | ||
| continue; | ||
|
|
||
| if (PSI->isHotCount(*Count) && !alreadyHasSectionPrefix(GV, "hot")) { | ||
| // The variable counter is hot, set 'hot' section prefix if the section | ||
| // prefix isn't hot already. | ||
| GV.setSectionPrefix("hot"); | ||
| Changed = true; | ||
| } else if (PSI->isColdCount(*Count) && !SDPI->hasUnknownCount(&GV) && | ||
| !alreadyHasSectionPrefix(GV, "unlikely")) { | ||
| // The variable counter is cold, set 'unlikely' section prefix when | ||
| // 1) the section prefix isn't unlikely already, and | ||
| // 2) the variable is not seen without profile counts. The reason is that | ||
| // a variable without profile counts doesn't have all its uses profiled, | ||
| // for example when a function is not instrumented, or not sampled (new | ||
| // code paths). | ||
| GV.setSectionPrefix("unlikely"); | ||
| Changed = true; | ||
| } | ||
| } | ||
|
|
||
| return Changed; | ||
| } | ||
|
|
||
| char StaticDataAnnotator::ID = 0; | ||
|
|
||
| INITIALIZE_PASS(StaticDataAnnotator, DEBUG_TYPE, "Static Data Annotator", false, | ||
| false) | ||
|
|
||
| ModulePass *llvm::createStaticDataAnnotatorPass() { | ||
| return new StaticDataAnnotator(); | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.