Skip to content

[TypeProf][InstrFDO]Implement more efficient comparison sequence for indirect-call-promotion with vtable profiles. #81442

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 24 commits into from
Jun 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
48adcf1
[𝘀𝗽𝗿] changes to main this commit is based on
mingmingl-llvm Feb 7, 2024
3f2da71
run 'git merge main' and resolve conflict
mingmingl-llvm Feb 8, 2024
66dbbfe
[InstrProf] Add vtables with type metadata into symtab to look it up …
mingmingl-llvm Feb 8, 2024
7ebae25
[NFC][CallPromotionUtils]Extract a helper function versionCallSiteWit…
mingmingl-llvm Feb 8, 2024
ac5dc1b
[CallPromotionUtils]Implement conditional indirect call promotion wit…
mingmingl-llvm Feb 10, 2024
29d9cd2
[TypeProf][IndirectCallPromotion]Implement vtable-based transformation
mingmingl-llvm Feb 10, 2024
03538e3
run 'git merge main'
mingmingl-llvm May 20, 2024
ff3c219
[TypeProf][InstrFDO]Implement more efficient comparison sequence for
mingmingl-llvm May 22, 2024
aefda4c
Changes:
mingmingl-llvm May 28, 2024
2c87c47
undo changes to clang/lib/CodeGen/CGVTbles.cpp
mingmingl-llvm May 28, 2024
142845c
follow up on review feedback
mingmingl-llvm May 30, 2024
4f6b7ab
Changes
mingmingl-llvm Jun 7, 2024
de2b9a3
Resolve review feedback
mingmingl-llvm Jun 12, 2024
b607ac3
Changes:
mingmingl-llvm Jun 13, 2024
360e5e6
Changes
mingmingl-llvm Jun 13, 2024
9ac5193
run 'git merge main'
mingmingl-llvm Jun 13, 2024
53be1a6
update after 'git merge main'
mingmingl-llvm Jun 24, 2024
801c3cb
run 'git merge main'
mingmingl-llvm Jun 24, 2024
7cd8630
resolve review feedback
mingmingl-llvm Jun 26, 2024
ac10513
run 'git merge main' and fix compiler-rt test
mingmingl-llvm Jun 27, 2024
5343320
fix unused variable
mingmingl-llvm Jun 28, 2024
7c2b323
add back a variable which is only used by assert
mingmingl-llvm Jun 28, 2024
c929e47
Changes:
mingmingl-llvm Jun 30, 2024
89555e2
run 'git merge main' and resolve conflicts
mingmingl-llvm Jun 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 108 additions & 44 deletions compiler-rt/test/profile/Linux/instrprof-vtable-value-prof.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,59 +5,61 @@
// ld.lld: error: /lib/../lib64/Scrt1.o: ABI version 1 is not supported
// UNSUPPORTED: ppc && host-byteorder-big-endian

// RUN: %clangxx_pgogen -fuse-ld=lld -O2 -g -fprofile-generate=. -mllvm -enable-vtable-value-profiling %s -o %t-test
// RUN: env LLVM_PROFILE_FILE=%t-test.profraw %t-test
// RUN: rm -rf %t && mkdir %t && cd %t

// RUN: %clangxx_pgogen -fuse-ld=lld -O2 -fprofile-generate=. -mllvm -enable-vtable-value-profiling %s -o test
// RUN: env LLVM_PROFILE_FILE=test.profraw ./test

// Show vtable profiles from raw profile.
// RUN: llvm-profdata show --function=main --ic-targets --show-vtables %t-test.profraw | FileCheck %s --check-prefixes=COMMON,RAW
// RUN: llvm-profdata show --function=main --ic-targets --show-vtables test.profraw | FileCheck %s --check-prefixes=COMMON,RAW

// Generate indexed profile from raw profile and show the data.
// RUN: llvm-profdata merge --keep-vtable-symbols %t-test.profraw -o %t-test.profdata
// RUN: llvm-profdata show --function=main --ic-targets --show-vtables %t-test.profdata | FileCheck %s --check-prefixes=COMMON,INDEXED
// RUN: llvm-profdata merge --keep-vtable-symbols test.profraw -o test.profdata
// RUN: llvm-profdata show --function=main --ic-targets --show-vtables test.profdata | FileCheck %s --check-prefixes=COMMON,INDEXED

// Generate text profile from raw and indexed profiles respectively and show the data.
// RUN: llvm-profdata merge --keep-vtable-symbols --text %t-test.profraw -o %t-raw.proftext
// RUN: llvm-profdata show --function=main --ic-targets --show-vtables --text %t-raw.proftext | FileCheck %s --check-prefix=ICTEXT
// RUN: llvm-profdata merge --keep-vtable-symbols --text %t-test.profdata -o %t-indexed.proftext
// RUN: llvm-profdata show --function=main --ic-targets --show-vtables --text %t-indexed.proftext | FileCheck %s --check-prefix=ICTEXT
// RUN: llvm-profdata merge --keep-vtable-symbols --text test.profraw -o raw.proftext
// RUN: llvm-profdata show --function=main --ic-targets --show-vtables --text raw.proftext | FileCheck %s --check-prefix=ICTEXT
// RUN: llvm-profdata merge --keep-vtable-symbols --text test.profdata -o indexed.proftext
// RUN: llvm-profdata show --function=main --ic-targets --show-vtables --text indexed.proftext | FileCheck %s --check-prefix=ICTEXT

// Generate indexed profile from text profiles and show the data
// RUN: llvm-profdata merge --keep-vtable-symbols --binary %t-raw.proftext -o %t-text.profraw
// RUN: llvm-profdata show --function=main --ic-targets --show-vtables %t-text.profraw | FileCheck %s --check-prefixes=COMMON,INDEXED
// RUN: llvm-profdata merge --keep-vtable-symbols --binary %t-indexed.proftext -o %t-text.profdata
// RUN: llvm-profdata show --function=main --ic-targets --show-vtables %t-text.profdata | FileCheck %s --check-prefixes=COMMON,INDEXED
// RUN: llvm-profdata merge --keep-vtable-symbols --binary raw.proftext -o text.profraw
// RUN: llvm-profdata show --function=main --ic-targets --show-vtables text.profraw | FileCheck %s --check-prefixes=COMMON,INDEXED
// RUN: llvm-profdata merge --keep-vtable-symbols --binary indexed.proftext -o text.profdata
// RUN: llvm-profdata show --function=main --ic-targets --show-vtables text.profdata | FileCheck %s --check-prefixes=COMMON,INDEXED

// COMMON: Counters:
// COMMON-NEXT: main:
// COMMON-NEXT: Hash: 0x0f9a16fe6d398548
// COMMON-NEXT: Counters: 2
// COMMON-NEXT: Hash: 0x068617320ec408a0
// COMMON-NEXT: Counters: 4
// COMMON-NEXT: Indirect Call Site Count: 2
// COMMON-NEXT: Number of instrumented vtables: 2
// RAW: Indirect Target Results:
// RAW-NEXT: [ 0, _ZN8Derived15func1Eii, 250 ] (25.00%)
// RAW-NEXT: [ 0, {{.*}}instrprof-vtable-value-prof.cpp;_ZN12_GLOBAL__N_18Derived25func1Eii, 750 ] (75.00%)
// RAW-NEXT: [ 1, _ZN8Derived15func2Eii, 250 ] (25.00%)
// RAW-NEXT: [ 1, {{.*}}instrprof-vtable-value-prof.cpp;_ZN12_GLOBAL__N_18Derived25func2Eii, 750 ] (75.00%)
// RAW-NEXT: [ 0, _ZN8Derived14funcEii, 50 ] (25.00%)
// RAW-NEXT: [ 0, {{.*}}instrprof-vtable-value-prof.cpp;_ZN12_GLOBAL__N_18Derived24funcEii, 150 ] (75.00%)
// RAW-NEXT: [ 1, _ZN8Derived1D0Ev, 250 ] (25.00%)
// RAW-NEXT: [ 1, {{.*}}instrprof-vtable-value-prof.cpp;_ZN12_GLOBAL__N_18Derived2D0Ev, 750 ] (75.00%)
// RAW-NEXT: VTable Results:
// RAW-NEXT: [ 0, _ZTV8Derived1, 250 ] (25.00%)
// RAW-NEXT: [ 0, {{.*}}instrprof-vtable-value-prof.cpp;_ZTVN12_GLOBAL__N_18Derived2E, 750 ] (75.00%)
// RAW-NEXT: [ 0, _ZTV8Derived1, 50 ] (25.00%)
// RAW-NEXT: [ 0, {{.*}}instrprof-vtable-value-prof.cpp;_ZTVN12_GLOBAL__N_18Derived2E, 150 ] (75.00%)
// RAW-NEXT: [ 1, _ZTV8Derived1, 250 ] (25.00%)
// RAW-NEXT: [ 1, {{.*}}instrprof-vtable-value-prof.cpp;_ZTVN12_GLOBAL__N_18Derived2E, 750 ] (75.00%)
// INDEXED: Indirect Target Results:
// INDEXED-NEXT: [ 0, {{.*}}instrprof-vtable-value-prof.cpp;_ZN12_GLOBAL__N_18Derived25func1Eii, 750 ] (75.00%)
// INDEXED-NEXT: [ 0, _ZN8Derived15func1Eii, 250 ] (25.00%)
// INDEXED-NEXT: [ 1, {{.*}}instrprof-vtable-value-prof.cpp;_ZN12_GLOBAL__N_18Derived25func2Eii, 750 ] (75.00%)
// INDEXED-NEXT: [ 1, _ZN8Derived15func2Eii, 250 ] (25.00%)
// INDEXED-NEXT: [ 0, {{.*}}instrprof-vtable-value-prof.cpp;_ZN12_GLOBAL__N_18Derived24funcEii, 150 ] (75.00%)
// INDEXED-NEXT: [ 0, _ZN8Derived14funcEii, 50 ] (25.00%)
// INDEXED-NEXT: [ 1, {{.*}}instrprof-vtable-value-prof.cpp;_ZN12_GLOBAL__N_18Derived2D0Ev, 750 ] (75.00%)
// INDEXED-NEXT: [ 1, _ZN8Derived1D0Ev, 250 ] (25.00%)
// INDEXED-NEXT: VTable Results:
// INDEXED-NEXT: [ 0, {{.*}}instrprof-vtable-value-prof.cpp;_ZTVN12_GLOBAL__N_18Derived2E, 750 ] (75.00%)
// INDEXED-NEXT: [ 0, _ZTV8Derived1, 250 ] (25.00%)
// INDEXED-NEXT: [ 0, {{.*}}instrprof-vtable-value-prof.cpp;_ZTVN12_GLOBAL__N_18Derived2E, 150 ] (75.00%)
// INDEXED-NEXT: [ 0, _ZTV8Derived1, 50 ] (25.00%)
// INDEXED-NEXT: [ 1, {{.*}}instrprof-vtable-value-prof.cpp;_ZTVN12_GLOBAL__N_18Derived2E, 750 ] (75.00%)
// INDEXED-NEXT: [ 1, _ZTV8Derived1, 250 ] (25.00%)
// COMMON: Instrumentation level: IR entry_first = 0
// COMMON-NEXT: Functions shown: 1
// COMMON-NEXT: Total functions: 6
// COMMON-NEXT: Total functions: 7
// COMMON-NEXT: Maximum function count: 1000
// COMMON-NEXT: Maximum internal block count: 250
// COMMON-NEXT: Maximum internal block count: 1000
// COMMON-NEXT: Statistics for indirect call sites profile:
// COMMON-NEXT: Total number of sites: 2
// COMMON-NEXT: Total number of sites with values: 2
Expand All @@ -76,11 +78,13 @@
// ICTEXT: :ir
// ICTEXT: main
// ICTEXT: # Func Hash:
// ICTEXT: 1124236338992350536
// ICTEXT: 470088714870327456
// ICTEXT: # Num Counters:
// ICTEXT: 2
// ICTEXT: 4
// ICTEXT: # Counter Values:
// ICTEXT: 1000
// ICTEXT: 1000
// ICTEXT: 200
// ICTEXT: 1
// ICTEXT: # Num Value Kinds:
// ICTEXT: 2
Expand All @@ -89,41 +93,98 @@
// ICTEXT: # NumValueSites:
// ICTEXT: 2
// ICTEXT: 2
// ICTEXT: {{.*}}instrprof-vtable-value-prof.cpp;_ZN12_GLOBAL__N_18Derived25func1Eii:750
// ICTEXT: _ZN8Derived15func1Eii:250
// ICTEXT: {{.*}}instrprof-vtable-value-prof.cpp;_ZN12_GLOBAL__N_18Derived24funcEii:150
// ICTEXT: _ZN8Derived14funcEii:50
// ICTEXT: 2
// ICTEXT: {{.*}}instrprof-vtable-value-prof.cpp;_ZN12_GLOBAL__N_18Derived25func2Eii:750
// ICTEXT: _ZN8Derived15func2Eii:250
// ICTEXT: {{.*}}instrprof-vtable-value-prof.cpp;_ZN12_GLOBAL__N_18Derived2D0Ev:750
// ICTEXT: _ZN8Derived1D0Ev:250
// ICTEXT: # ValueKind = IPVK_VTableTarget:
// ICTEXT: 2
// ICTEXT: # NumValueSites:
// ICTEXT: 2
// ICTEXT: 2
// ICTEXT: {{.*}}instrprof-vtable-value-prof.cpp;_ZTVN12_GLOBAL__N_18Derived2E:750
// ICTEXT: _ZTV8Derived1:250
// ICTEXT: {{.*}}instrprof-vtable-value-prof.cpp;_ZTVN12_GLOBAL__N_18Derived2E:150
// ICTEXT: _ZTV8Derived1:50
// ICTEXT: 2
// ICTEXT: {{.*}}instrprof-vtable-value-prof.cpp;_ZTVN12_GLOBAL__N_18Derived2E:750
// ICTEXT: _ZTV8Derived1:250

// Test indirect call promotion transformation using vtable profiles.
// - Build with `-g` to enable debug information.
// - In real world settings, ICP pass is disabled in prelink pipeline. In
// the postlink pipeline, ICP is enabled after whole-program-devirtualization
// pass. Do the same thing in this test.
// - Enable `-fwhole-program-vtables` generate type metadata and intrinsics.
// - Enable `-fno-split-lto-unit` and `-Wl,-lto-whole-program-visibility` to
// preserve type intrinsics for ICP pass.
// RUN: %clangxx -m64 -fprofile-use=test.profdata -Wl,--lto-whole-program-visibility \
// RUN: -mllvm -disable-icp=true -Wl,-mllvm,-disable-icp=false -fuse-ld=lld \
// RUN: -g -flto=thin -fwhole-program-vtables -fno-split-lto-unit -O2 \
// RUN: -mllvm -enable-vtable-value-profiling -Wl,-mllvm,-enable-vtable-value-profiling \
// RUN: -mllvm -enable-vtable-profile-use \
// RUN: -Wl,-mllvm,-enable-vtable-profile-use -Rpass=pgo-icall-prom \
// RUN: -Wl,-mllvm,-print-after=pgo-icall-prom \
// RUN: -Wl,-mllvm,-filter-print-funcs=main %s 2>&1 \
// RUN: | FileCheck %s --check-prefixes=REMARK,IR --implicit-check-not="!VP"

// For the indirect call site `ptr->func`
// REMARK: instrprof-vtable-value-prof.cpp:205:19: Promote indirect call to _ZN12_GLOBAL__N_18Derived24funcEii with count 150 out of 200, sink 1 instruction(s) and compare 1 vtable(s): {_ZTVN12_GLOBAL__N_18Derived2E}
// REMARK: instrprof-vtable-value-prof.cpp:205:19: Promote indirect call to _ZN8Derived14funcEii with count 50 out of 50, sink 1 instruction(s) and compare 1 vtable(s): {_ZTV8Derived1}
//
// For the indirect call site `delete ptr`
// REMARK: instrprof-vtable-value-prof.cpp:207:5: Promote indirect call to _ZN12_GLOBAL__N_18Derived2D0Ev with count 750 out of 1000, sink 2 instruction(s) and compare 1 vtable(s): {_ZTVN12_GLOBAL__N_18Derived2E}
// REMARK: instrprof-vtable-value-prof.cpp:207:5: Promote indirect call to _ZN8Derived1D0Ev with count 250 out of 250, sink 2 instruction(s) and compare 1 vtable(s): {_ZTV8Derived1}

// The IR matchers for indirect callsite `ptr->func`.
// IR-LABEL: @main
// IR: [[OBJ:%.*]] = {{.*}}call {{.*}} @_Z10createTypei
// IR: [[VTABLE:%.*]] = load ptr, ptr [[OBJ]]
// IR: [[CMP1:%.*]] = icmp eq ptr [[VTABLE]], getelementptr inbounds (i8, ptr @_ZTVN12_GLOBAL__N_18Derived2E, i32 16)
// IR: br i1 [[CMP1]], label %[[BB1:.*]], label %[[BB2:[a-zA-Z0-9_.]+]],
//
// IR: [[BB1]]:
// IR: [[RESBB1:%.*]] = {{.*}}call {{.*}} @_ZN12_GLOBAL__N_18Derived24funcEii
// IR: br label %[[MERGE0:[a-zA-Z0-9_.]+]]
//
// IR: [[BB2]]:
// IR: [[CMP2:%.*]] = icmp eq ptr [[VTABLE]], getelementptr inbounds (i8, ptr @_ZTV8Derived1, i32 16)
// IR: br i1 [[CMP2]], label %[[BB3:.*]], label %[[BB4:[a-zA-Z0-9_.]+]],
//
// IR: [[BB3]]:
// IR: [[RESBB3:%.*]] = {{.*}}call {{.*}} @_ZN8Derived14funcEii
// IR: br label %[[MERGE1:[a-zA-Z0-9_.]+]],
//
// IR: [[BB4]]:
// IR: [[FUNCPTR:%.*]] = load ptr, ptr [[VTABLE]]
// IR: [[RESBB4:%.*]] = {{.*}}call {{.*}} [[FUNCPTR]]
// IR: br label %[[MERGE1]]
//
// IR: [[MERGE1]]:
// IR: [[RES1:%.*]] = phi i32 [ [[RESBB4]], %[[BB4]] ], [ [[RESBB3]], %[[BB3]] ]
// IR: br label %[[MERGE0]]
//
// IR: [[MERGE0]]:
// IR: [[RES2:%.*]] = phi i32 [ [[RES1]], %[[MERGE1]] ], [ [[RESBB1]], %[[BB1]] ]
#include <cstdio>
#include <cstdlib>
class Base {
public:
virtual int func1(int a, int b) = 0;
virtual int func2(int a, int b) = 0;
virtual int func(int a, int b) = 0;

virtual ~Base() {};
};
class Derived1 : public Base {
public:
int func1(int a, int b) override { return a + b; }
int func(int a, int b) override { return a * b; }

int func2(int a, int b) override { return a * b; }
~Derived1() {}
};
namespace {
class Derived2 : public Base {
public:
int func1(int a, int b) override { return a - b; }
int func(int a, int b) override { return a * (a - b); }

int func2(int a, int b) override { return a * (a - b); }
~Derived2() {}
};
} // namespace
__attribute__((noinline)) Base *createType(int a) {
Expand All @@ -140,7 +201,10 @@ int main(int argc, char **argv) {
int a = rand();
int b = rand();
Base *ptr = createType(i);
sum += ptr->func1(a, b) + ptr->func2(b, a);
if (i % 5 == 0)
sum += ptr->func(b, a);

delete ptr;
}
printf("sum is %d\n", sum);
return 0;
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/Analysis/IndirectCallPromotionAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class ICallPromotionAnalysis {
///
/// The returned array space is owned by this class, and overwritten on
/// subsequent calls.
ArrayRef<InstrProfValueData> getPromotionCandidatesForInstruction(
MutableArrayRef<InstrProfValueData> getPromotionCandidatesForInstruction(
const Instruction *I, uint64_t &TotalCount, uint32_t &NumCandidates);
};

Expand Down
4 changes: 3 additions & 1 deletion llvm/include/llvm/Analysis/IndirectCallVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ struct PGOIndirectCallVisitor : public InstVisitor<PGOIndirectCallVisitor> {
// A heuristic is used to find the address feeding instructions.
static Instruction *tryGetVTableInstruction(CallBase *CB) {
assert(CB != nullptr && "Caller guaranteed");
LoadInst *LI = dyn_cast<LoadInst>(CB->getCalledOperand());
if (!CB->isIndirectCall())
return nullptr;

LoadInst *LI = dyn_cast<LoadInst>(CB->getCalledOperand());
if (LI != nullptr) {
Value *FuncPtr = LI->getPointerOperand(); // GEP (or bitcast)
Value *VTablePtr = FuncPtr->stripInBoundsConstantOffsets();
Expand Down
10 changes: 10 additions & 0 deletions llvm/include/llvm/ProfileData/InstrProf.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ getValueProfDataFromInst(const Instruction &Inst, InstrProfValueKind ValueKind,
uint32_t MaxNumValueData, uint32_t &ActualNumValueData,
uint64_t &TotalC, bool GetNoICPValue = false);

// TODO: Unify metadata name 'PGOFuncName' and 'PGOName', by supporting read
// of this metadata for backward compatibility and generating 'PGOName' only.
/// Extract the value profile data from \p Inst and returns them if \p Inst is
/// annotated with value profile data. Returns an empty vector otherwise.
SmallVector<InstrProfValueData, 4>
Expand All @@ -303,6 +305,8 @@ getValueProfDataFromInst(const Instruction &Inst, InstrProfValueKind ValueKind,

inline StringRef getPGOFuncNameMetadataName() { return "PGOFuncName"; }

inline StringRef getPGONameMetadataName() { return "PGOName"; }

/// Return the PGOFuncName meta data associated with a function.
MDNode *getPGOFuncNameMetadata(const Function &F);

Expand All @@ -311,8 +315,14 @@ std::string getPGOName(const GlobalVariable &V, bool InLTO = false);
/// Create the PGOFuncName meta data if PGOFuncName is different from
/// function's raw name. This should only apply to internal linkage functions
/// declared by users only.
/// TODO: Update all callers to 'createPGONameMetadata' and deprecate this
/// function.
void createPGOFuncNameMetadata(Function &F, StringRef PGOFuncName);

/// Create the PGOName metadata if a global object's PGO name is different from
/// its mangled name. This should apply to local-linkage global objects only.
void createPGONameMetadata(GlobalObject &GO, StringRef PGOName);

/// Check if we can use Comdat for profile variables. This will eliminate
/// the duplicated profile variables for Comdat functions.
bool needsComdatForCounter(const GlobalObject &GV, const Module &M);
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,17 @@ uint32_t ICallPromotionAnalysis::getProfitablePromotionCandidates(
return I;
}

ArrayRef<InstrProfValueData>
MutableArrayRef<InstrProfValueData>
ICallPromotionAnalysis::getPromotionCandidatesForInstruction(
const Instruction *I, uint64_t &TotalCount, uint32_t &NumCandidates) {
uint32_t NumVals;
auto Res = getValueProfDataFromInst(*I, IPVK_IndirectCallTarget,
MaxNumPromotions, NumVals, TotalCount);
if (!Res) {
NumCandidates = 0;
return ArrayRef<InstrProfValueData>();
return MutableArrayRef<InstrProfValueData>();
}
ValueDataArray = std::move(Res);
NumCandidates = getProfitablePromotionCandidates(I, NumVals, TotalCount);
return ArrayRef<InstrProfValueData>(ValueDataArray.get(), NumVals);
return MutableArrayRef<InstrProfValueData>(ValueDataArray.get(), NumVals);
}
41 changes: 29 additions & 12 deletions llvm/lib/ProfileData/InstrProf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,12 @@ cl::opt<bool> EnableVTableValueProfiling(
"the types of a C++ pointer. The information is used in indirect "
"call promotion to do selective vtable-based comparison."));

cl::opt<bool> EnableVTableProfileUse(
"enable-vtable-profile-use", cl::init(false),
cl::desc("If ThinLTO and WPD is enabled and this option is true, vtable "
"profiles will be used by ICP pass for more efficient indirect "
"call sequence. If false, type profiles won't be used."));

std::string getInstrProfSectionName(InstrProfSectKind IPSK,
Triple::ObjectFormatType OF,
bool AddSegmentInfo) {
Expand Down Expand Up @@ -391,7 +397,7 @@ std::string getPGOName(const GlobalVariable &V, bool InLTO) {
// PGONameMetadata should be set by compiler at profile use time
// and read by symtab creation to look up symbols corresponding to
// a MD5 hash.
return getIRPGOObjectName(V, InLTO, /*PGONameMetadata=*/nullptr);
return getIRPGOObjectName(V, InLTO, V.getMetadata(getPGONameMetadataName()));
}

// See getIRPGOObjectName() for a discription of the format.
Expand Down Expand Up @@ -480,8 +486,7 @@ Error InstrProfSymtab::create(Module &M, bool InLTO) {
for (GlobalVariable &G : M.globals()) {
if (!G.hasName() || !G.hasMetadata(LLVMContext::MD_type))
continue;
if (Error E = addVTableWithName(
G, getIRPGOObjectName(G, InLTO, /* PGONameMetadata */ nullptr)))
if (Error E = addVTableWithName(G, getPGOName(G, InLTO)))
return E;
}

Expand Down Expand Up @@ -1425,16 +1430,28 @@ MDNode *getPGOFuncNameMetadata(const Function &F) {
return F.getMetadata(getPGOFuncNameMetadataName());
}

void createPGOFuncNameMetadata(Function &F, StringRef PGOFuncName) {
// Only for internal linkage functions.
if (PGOFuncName == F.getName())
return;
// Don't create duplicated meta-data.
if (getPGOFuncNameMetadata(F))
static void createPGONameMetadata(GlobalObject &GO, StringRef MetadataName,
StringRef PGOName) {
// Only for internal linkage functions or global variables. The name is not
// the same as PGO name for these global objects.
if (GO.getName() == PGOName)
return;
LLVMContext &C = F.getContext();
MDNode *N = MDNode::get(C, MDString::get(C, PGOFuncName));
F.setMetadata(getPGOFuncNameMetadataName(), N);

// Don't create duplicated metadata.
if (GO.getMetadata(MetadataName))
return;

LLVMContext &C = GO.getContext();
MDNode *N = MDNode::get(C, MDString::get(C, PGOName));
GO.setMetadata(MetadataName, N);
}

void createPGOFuncNameMetadata(Function &F, StringRef PGOFuncName) {
return createPGONameMetadata(F, getPGOFuncNameMetadataName(), PGOFuncName);
}

void createPGONameMetadata(GlobalObject &GO, StringRef PGOName) {
return createPGONameMetadata(GO, getPGONameMetadataName(), PGOName);
}

bool needsComdatForCounter(const GlobalObject &GO, const Module &M) {
Expand Down
Loading