19
19
#include " llvm/ADT/StringRef.h"
20
20
#include " llvm/Bitcode/BitcodeReader.h"
21
21
#include " llvm/IR/AutoUpgrade.h"
22
- #include " llvm/IR/Constants.h"
23
22
#include " llvm/IR/Function.h"
24
23
#include " llvm/IR/GlobalAlias.h"
25
24
#include " llvm/IR/GlobalObject.h"
30
29
#include " llvm/IR/ModuleSummaryIndex.h"
31
30
#include " llvm/IRReader/IRReader.h"
32
31
#include " llvm/Linker/IRMover.h"
32
+ #include " llvm/ProfileData/PGOCtxProfReader.h"
33
33
#include " llvm/Support/Casting.h"
34
34
#include " llvm/Support/CommandLine.h"
35
35
#include " llvm/Support/Debug.h"
@@ -176,6 +176,10 @@ static cl::opt<std::string> WorkloadDefinitions(
176
176
177
177
extern cl::opt<std::string> UseCtxProfile;
178
178
179
+ static cl::opt<std::string>
180
+ ContextualProfile (" thinlto-pgo-ctx-prof" ,
181
+ cl::desc (" Path to a contextual profile." ), cl::Hidden);
182
+
179
183
namespace llvm {
180
184
extern cl::opt<bool > EnableMemProfContextDisambiguation;
181
185
}
@@ -634,13 +638,7 @@ class WorkloadImportsManager : public ModuleImportsManager {
634
638
LLVM_DEBUG (dbgs () << " [Workload] Done\n " );
635
639
}
636
640
637
- public:
638
- WorkloadImportsManager (
639
- function_ref<bool (GlobalValue::GUID, const GlobalValueSummary *)>
640
- IsPrevailing,
641
- const ModuleSummaryIndex &Index,
642
- DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists)
643
- : ModuleImportsManager(IsPrevailing, Index, ExportLists) {
641
+ void loadFromJson () {
644
642
// Since the workload def uses names, we need a quick lookup
645
643
// name->ValueInfo.
646
644
StringMap<ValueInfo> NameToValueInfo;
@@ -710,15 +708,81 @@ class WorkloadImportsManager : public ModuleImportsManager {
710
708
}
711
709
Set.insert (ElemIt->second );
712
710
}
713
- LLVM_DEBUG ({
711
+ }
712
+ }
713
+
714
+ void loadFromCtxProf () {
715
+ std::error_code EC;
716
+ auto BufferOrErr = MemoryBuffer::getFileOrSTDIN (ContextualProfile);
717
+ if (std::error_code EC = BufferOrErr.getError ()) {
718
+ report_fatal_error (" Failed to open contextual profile file" );
719
+ return ;
720
+ }
721
+ auto Buffer = std::move (BufferOrErr.get ());
722
+
723
+ PGOCtxProfileReader Reader (Buffer->getBuffer ());
724
+ auto Ctx = Reader.loadContexts ();
725
+ if (!Ctx) {
726
+ report_fatal_error (" Failed to parse contextual profiles" );
727
+ return ;
728
+ }
729
+ const auto &CtxMap = *Ctx;
730
+ DenseSet<GlobalValue::GUID> ContainedGUIDs;
731
+ for (const auto &[RootGuid, Root] : CtxMap) {
732
+ // Avoid ContainedGUIDs to get in/out of scope. Reuse its memory for
733
+ // subsequent roots, but clear its contents.
734
+ ContainedGUIDs.clear ();
735
+
736
+ auto RootVI = Index.getValueInfo (RootGuid);
737
+ if (!RootVI) {
738
+ LLVM_DEBUG (dbgs () << " [Workload] Root " << RootGuid
739
+ << " not found in this linkage unit.\n " );
740
+ continue ;
741
+ }
742
+ if (RootVI.getSummaryList ().size () != 1 ) {
743
+ LLVM_DEBUG (dbgs () << " [Workload] Root " << RootGuid
744
+ << " should have exactly one summary, but has "
745
+ << RootVI.getSummaryList ().size () << " . Skipping.\n " );
746
+ continue ;
747
+ }
748
+ StringRef RootDefiningModule =
749
+ RootVI.getSummaryList ().front ()->modulePath ();
750
+ LLVM_DEBUG (dbgs () << " [Workload] Root defining module for " << RootGuid
751
+ << " is : " << RootDefiningModule << " \n " );
752
+ auto &Set = Workloads[RootDefiningModule];
753
+ Root.getContainedGuids (ContainedGUIDs);
754
+ for (auto Guid : ContainedGUIDs)
755
+ if (auto VI = Index.getValueInfo (Guid))
756
+ Set.insert (VI);
757
+ }
758
+ }
759
+
760
+ public:
761
+ WorkloadImportsManager (
762
+ function_ref<bool (GlobalValue::GUID, const GlobalValueSummary *)>
763
+ IsPrevailing,
764
+ const ModuleSummaryIndex &Index,
765
+ DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists)
766
+ : ModuleImportsManager(IsPrevailing, Index, ExportLists) {
767
+ if (ContextualProfile.empty () == WorkloadDefinitions.empty ()) {
768
+ report_fatal_error (
769
+ " Pass only one of: -thinlto-pgo-ctx-prof or -thinlto-workload-def" );
770
+ return ;
771
+ }
772
+ if (!ContextualProfile.empty ())
773
+ loadFromCtxProf ();
774
+ else
775
+ loadFromJson ();
776
+ LLVM_DEBUG ({
777
+ for (const auto &[Root, Set] : Workloads) {
714
778
dbgs () << " [Workload] Root: " << Root << " we have " << Set.size ()
715
779
<< " distinct callees.\n " ;
716
780
for (const auto &VI : Set) {
717
781
dbgs () << " [Workload] Root: " << Root
718
782
<< " Would include: " << VI.getGUID () << " \n " ;
719
783
}
720
- });
721
- }
784
+ }
785
+ });
722
786
}
723
787
};
724
788
@@ -727,7 +791,7 @@ std::unique_ptr<ModuleImportsManager> ModuleImportsManager::create(
727
791
IsPrevailing,
728
792
const ModuleSummaryIndex &Index,
729
793
DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists) {
730
- if (WorkloadDefinitions.empty ()) {
794
+ if (WorkloadDefinitions.empty () && ContextualProfile. empty () ) {
731
795
LLVM_DEBUG (dbgs () << " [Workload] Using the regular imports manager.\n " );
732
796
return std::unique_ptr<ModuleImportsManager>(
733
797
new ModuleImportsManager (IsPrevailing, Index, ExportLists));
0 commit comments