Skip to content

Commit 2146826

Browse files
authored
[ctxprof] Support for "move" semantics for the contextual root (#134192)
This PR finishes what PR #133992 started.
1 parent b989171 commit 2146826

File tree

4 files changed

+70
-24
lines changed

4 files changed

+70
-24
lines changed

llvm/include/llvm/Transforms/Utils/FunctionImportUtils.h

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -97,29 +97,14 @@ class FunctionImportGlobalProcessing {
9797
/// linkage for a required promotion of a local to global scope.
9898
GlobalValue::LinkageTypes getLinkage(const GlobalValue *SGV, bool DoPromote);
9999

100+
/// The symbols with these names are moved to a different module and should be
101+
/// promoted to external linkage where they are defined.
102+
DenseSet<GlobalValue::GUID> SymbolsToMove;
103+
100104
public:
101105
FunctionImportGlobalProcessing(Module &M, const ModuleSummaryIndex &Index,
102106
SetVector<GlobalValue *> *GlobalsToImport,
103-
bool ClearDSOLocalOnDeclarations)
104-
: M(M), ImportIndex(Index), GlobalsToImport(GlobalsToImport),
105-
ClearDSOLocalOnDeclarations(ClearDSOLocalOnDeclarations) {
106-
// If we have a ModuleSummaryIndex but no function to import,
107-
// then this is the primary module being compiled in a ThinLTO
108-
// backend compilation, and we need to see if it has functions that
109-
// may be exported to another backend compilation.
110-
if (!GlobalsToImport)
111-
HasExportedFunctions = ImportIndex.hasExportedFunctions(M);
112-
113-
#ifndef NDEBUG
114-
SmallVector<GlobalValue *, 4> Vec;
115-
// First collect those in the llvm.used set.
116-
collectUsedGlobalVariables(M, Vec, /*CompilerUsed=*/false);
117-
// Next collect those in the llvm.compiler.used set.
118-
collectUsedGlobalVariables(M, Vec, /*CompilerUsed=*/true);
119-
Used = {llvm::from_range, Vec};
120-
#endif
121-
}
122-
107+
bool ClearDSOLocalOnDeclarations);
123108
void run();
124109
};
125110

llvm/lib/Transforms/IPO/FunctionImport.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,15 @@ static cl::opt<bool> CtxprofMoveRootsToOwnModule(
182182
"their own module."),
183183
cl::Hidden, cl::init(false));
184184

185+
cl::list<GlobalValue::GUID> MoveSymbolGUID(
186+
"thinlto-move-symbols",
187+
cl::desc(
188+
"Move the symbols with the given name. This will delete these symbols "
189+
"wherever they are originally defined, and make sure their "
190+
"linkage is External where they are imported. It is meant to be "
191+
"used with the name of contextual profiling roots."),
192+
cl::Hidden);
193+
185194
namespace llvm {
186195
extern cl::opt<bool> EnableMemProfContextDisambiguation;
187196
}
@@ -1859,6 +1868,15 @@ Expected<bool> FunctionImporter::importFunctions(
18591868
LLVM_DEBUG(dbgs() << "Starting import for Module "
18601869
<< DestModule.getModuleIdentifier() << "\n");
18611870
unsigned ImportedCount = 0, ImportedGVCount = 0;
1871+
// Before carrying out any imports, see if this module defines functions in
1872+
// MoveSymbolGUID. If it does, delete them here (but leave the declaration).
1873+
// The function will be imported elsewhere, as extenal linkage, and the
1874+
// destination doesn't yet have its definition.
1875+
DenseSet<GlobalValue::GUID> MoveSymbolGUIDSet;
1876+
MoveSymbolGUIDSet.insert_range(MoveSymbolGUID);
1877+
for (auto &F : DestModule)
1878+
if (!F.isDeclaration() && MoveSymbolGUIDSet.contains(F.getGUID()))
1879+
F.deleteBody();
18621880

18631881
IRMover Mover(DestModule);
18641882

llvm/lib/Transforms/Utils/FunctionImportUtils.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,31 @@ static cl::opt<bool> UseSourceFilenameForPromotedLocals(
2424
"This requires that the source filename has a unique name / "
2525
"path to avoid name collisions."));
2626

27+
extern cl::list<GlobalValue::GUID> MoveSymbolGUID;
28+
29+
FunctionImportGlobalProcessing::FunctionImportGlobalProcessing(
30+
Module &M, const ModuleSummaryIndex &Index,
31+
SetVector<GlobalValue *> *GlobalsToImport, bool ClearDSOLocalOnDeclarations)
32+
: M(M), ImportIndex(Index), GlobalsToImport(GlobalsToImport),
33+
ClearDSOLocalOnDeclarations(ClearDSOLocalOnDeclarations) {
34+
// If we have a ModuleSummaryIndex but no function to import,
35+
// then this is the primary module being compiled in a ThinLTO
36+
// backend compilation, and we need to see if it has functions that
37+
// may be exported to another backend compilation.
38+
if (!GlobalsToImport)
39+
HasExportedFunctions = ImportIndex.hasExportedFunctions(M);
40+
41+
#ifndef NDEBUG
42+
SmallVector<GlobalValue *, 4> Vec;
43+
// First collect those in the llvm.used set.
44+
collectUsedGlobalVariables(M, Vec, /*CompilerUsed=*/false);
45+
// Next collect those in the llvm.compiler.used set.
46+
collectUsedGlobalVariables(M, Vec, /*CompilerUsed=*/true);
47+
Used = {llvm::from_range, Vec};
48+
#endif
49+
SymbolsToMove.insert_range(MoveSymbolGUID);
50+
}
51+
2752
/// Checks if we should import SGV as a definition, otherwise import as a
2853
/// declaration.
2954
bool FunctionImportGlobalProcessing::doImportAsDefinition(
@@ -147,7 +172,9 @@ FunctionImportGlobalProcessing::getLinkage(const GlobalValue *SGV,
147172
// and/or optimization, but are turned into declarations later
148173
// during the EliminateAvailableExternally pass.
149174
if (doImportAsDefinition(SGV) && !isa<GlobalAlias>(SGV))
150-
return GlobalValue::AvailableExternallyLinkage;
175+
return SymbolsToMove.contains(SGV->getGUID())
176+
? GlobalValue::ExternalLinkage
177+
: GlobalValue::AvailableExternallyLinkage;
151178
// An imported external declaration stays external.
152179
return SGV->getLinkage();
153180

llvm/test/ThinLTO/X86/ctxprof-separate-module.ll

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,31 @@
2222
; RUN: -r %t/m2.bc,m2_f1,plx \
2323
; RUN: -r %t/m3.bc,m1_f1 \
2424
; RUN: -r %t/m3.bc,m3_f1,plx -debug-only=function-import 2>&1 | FileCheck %s --check-prefix=ABSENT-MSG
25+
26+
; also add the move semantics for the root:
27+
; RUN: llvm-lto2 run %t/m1.bc %t/m2.bc %t/m3.bc %t/6019442868614718803.bc -thinlto-move-ctxprof-trees \
28+
; RUN: -thinlto-move-symbols=6019442868614718803 \
29+
; RUN: -o %t/result-with-move.o -save-temps \
30+
; RUN: -use-ctx-profile=%t/ctxprof.bitstream \
31+
; RUN: -r %t/m1.bc,m1_f1,plx \
32+
; RUN: -r %t/m2.bc,m2_f1,plx \
33+
; RUN: -r %t/m3.bc,m1_f1 \
34+
; RUN: -r %t/m3.bc,m3_f1,plx -debug-only=function-import 2>&1 | FileCheck %s --check-prefix=ABSENT-MSG
35+
2536
; RUN: llvm-dis %t/result.o.4.3.import.bc -o - | FileCheck %s
2637
; RUN: llvm-dis %t/result.o.3.3.import.bc -o - | FileCheck %s --check-prefix=ABSENT
38+
; RUN: llvm-dis %t/result-with-move.o.1.3.import.bc -o - | FileCheck %s --check-prefix=WITHMOVE-SRC
39+
; RUN: llvm-dis %t/result-with-move.o.4.3.import.bc -o - | FileCheck %s --check-prefix=WITHMOVE-DEST
40+
; RUN: llvm-dis %t/result.o.1.3.import.bc -o - | FileCheck %s --check-prefix=WITHOUTMOVE-SRC
2741
;
28-
;
29-
; CHECK: m1_f1()
30-
; CHECK: m2_f1()
42+
; CHECK: define available_externally void @m1_f1()
43+
; CHECK: define available_externally void @m2_f1()
3144
; ABSENT: declare void @m1_f1()
3245
; ABSENT-MSG: Skipping over 6019442868614718803 because its import is handled in a different module.
3346
;
47+
; WITHMOVE-SRC: declare dso_local void @m1_f1
48+
; WITHMOVE-DEST: define dso_local void @m1_f1
49+
; WITHOUTMOVE-SRC: define dso_local void @m1_f1
3450
;--- ctxprof.yaml
3551
Contexts:
3652
-

0 commit comments

Comments
 (0)