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"
@@ -185,6 +185,10 @@ static cl::opt<bool> ImportAssumeUniqueLocal(
185
185
" user specify the full module path." ),
186
186
cl::Hidden);
187
187
188
+ static cl::opt<std::string>
189
+ ContextualProfile (" thinlto-pgo-ctx-prof" ,
190
+ cl::desc (" Path to a contextual profile." ), cl::Hidden);
191
+
188
192
namespace llvm {
189
193
extern cl::opt<bool > EnableMemProfContextDisambiguation;
190
194
}
@@ -604,13 +608,7 @@ class WorkloadImportsManager : public ModuleImportsManager {
604
608
LLVM_DEBUG (dbgs () << " [Workload] Done\n " );
605
609
}
606
610
607
- public:
608
- WorkloadImportsManager (
609
- function_ref<bool (GlobalValue::GUID, const GlobalValueSummary *)>
610
- IsPrevailing,
611
- const ModuleSummaryIndex &Index,
612
- DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists)
613
- : ModuleImportsManager(IsPrevailing, Index, ExportLists) {
611
+ void loadFromJson () {
614
612
// Since the workload def uses names, we need a quick lookup
615
613
// name->ValueInfo.
616
614
StringMap<ValueInfo> NameToValueInfo;
@@ -680,15 +678,81 @@ class WorkloadImportsManager : public ModuleImportsManager {
680
678
}
681
679
Set.insert (ElemIt->second );
682
680
}
683
- LLVM_DEBUG ({
681
+ }
682
+ }
683
+
684
+ void loadFromCtxProf () {
685
+ std::error_code EC;
686
+ auto BufferOrErr = MemoryBuffer::getFileOrSTDIN (ContextualProfile);
687
+ if (std::error_code EC = BufferOrErr.getError ()) {
688
+ report_fatal_error (" Failed to open contextual profile file" );
689
+ return ;
690
+ }
691
+ auto Buffer = std::move (BufferOrErr.get ());
692
+
693
+ PGOCtxProfileReader Reader (Buffer->getBuffer ());
694
+ auto Ctx = Reader.loadContexts ();
695
+ if (!Ctx) {
696
+ report_fatal_error (" Failed to parse contextual profiles" );
697
+ return ;
698
+ }
699
+ const auto &CtxMap = *Ctx;
700
+ DenseSet<GlobalValue::GUID> ContainedGUIDs;
701
+ for (const auto &[RootGuid, Root] : CtxMap) {
702
+ // Avoid ContainedGUIDs to get in/out of scope. Reuse its memory for
703
+ // subsequent roots, but clear its contents.
704
+ ContainedGUIDs.clear ();
705
+
706
+ auto RootVI = Index.getValueInfo (RootGuid);
707
+ if (!RootVI) {
708
+ LLVM_DEBUG (dbgs () << " [Workload] Root " << RootGuid
709
+ << " not found in this linkage unit.\n " );
710
+ continue ;
711
+ }
712
+ if (RootVI.getSummaryList ().size () != 1 ) {
713
+ LLVM_DEBUG (dbgs () << " [Workload] Root " << RootGuid
714
+ << " should have exactly one summary, but has "
715
+ << RootVI.getSummaryList ().size () << " . Skipping.\n " );
716
+ continue ;
717
+ }
718
+ StringRef RootDefiningModule =
719
+ RootVI.getSummaryList ().front ()->modulePath ();
720
+ LLVM_DEBUG (dbgs () << " [Workload] Root defining module for " << RootGuid
721
+ << " is : " << RootDefiningModule << " \n " );
722
+ auto &Set = Workloads[RootDefiningModule];
723
+ Root.getContainedGuids (ContainedGUIDs);
724
+ for (auto Guid : ContainedGUIDs)
725
+ if (auto VI = Index.getValueInfo (Guid))
726
+ Set.insert (VI);
727
+ }
728
+ }
729
+
730
+ public:
731
+ WorkloadImportsManager (
732
+ function_ref<bool (GlobalValue::GUID, const GlobalValueSummary *)>
733
+ IsPrevailing,
734
+ const ModuleSummaryIndex &Index,
735
+ DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists)
736
+ : ModuleImportsManager(IsPrevailing, Index, ExportLists) {
737
+ if (ContextualProfile.empty () == WorkloadDefinitions.empty ()) {
738
+ report_fatal_error (
739
+ " Pass only one of: -thinlto-pgo-ctx-prof or -thinlto-workload-def" );
740
+ return ;
741
+ }
742
+ if (!ContextualProfile.empty ())
743
+ loadFromCtxProf ();
744
+ else
745
+ loadFromJson ();
746
+ LLVM_DEBUG ({
747
+ for (const auto &[Root, Set] : Workloads) {
684
748
dbgs () << " [Workload] Root: " << Root << " we have " << Set.size ()
685
749
<< " distinct callees.\n " ;
686
750
for (const auto &VI : Set) {
687
751
dbgs () << " [Workload] Root: " << Root
688
752
<< " Would include: " << VI.getGUID () << " \n " ;
689
753
}
690
- });
691
- }
754
+ }
755
+ });
692
756
}
693
757
};
694
758
@@ -697,7 +761,7 @@ std::unique_ptr<ModuleImportsManager> ModuleImportsManager::create(
697
761
IsPrevailing,
698
762
const ModuleSummaryIndex &Index,
699
763
DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists) {
700
- if (WorkloadDefinitions.empty ()) {
764
+ if (WorkloadDefinitions.empty () && ContextualProfile. empty () ) {
701
765
LLVM_DEBUG (dbgs () << " [Workload] Using the regular imports manager.\n " );
702
766
return std::unique_ptr<ModuleImportsManager>(
703
767
new ModuleImportsManager (IsPrevailing, Index, ExportLists));
0 commit comments