Skip to content

Commit 4b78647

Browse files
[MemProf] Add CalleeGUIDs from profile to existing VP metadata (llvm#171495)
Previously, we only synthesized VP metadata with the callee GUIDs from the memprof profile if no VP metadata already existed (i.e. from PGO). With this change we will add in any that are not already in the VP metadata, also with count 1.
1 parent 908a5a8 commit 4b78647

File tree

2 files changed

+63
-28
lines changed

2 files changed

+63
-28
lines changed

llvm/lib/Transforms/Instrumentation/MemProfUse.cpp

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -396,38 +396,57 @@ static void addVPMetadata(Module &M, Instruction &I,
396396
if (!ClMemProfAttachCalleeGuids || CalleeGuids.empty())
397397
return;
398398

399+
// Prepare the vector of value data, initializing from any existing
400+
// value-profile metadata present on the instruction so that we merge the
401+
// new CalleeGuids into the existing entries.
402+
SmallVector<InstrProfValueData> VDs;
403+
uint64_t TotalCount = 0;
404+
399405
if (I.getMetadata(LLVMContext::MD_prof)) {
400-
uint64_t Unused;
401-
// TODO: When merging is implemented, increase this to a typical ICP value
402-
// (e.g., 3-6) For now, we only need to check if existing data exists, so 1
403-
// is sufficient
404-
auto ExistingVD = getValueProfDataFromInst(I, IPVK_IndirectCallTarget,
405-
/*MaxNumValueData=*/1, Unused);
406-
// We don't know how to merge value profile data yet.
407-
if (!ExistingVD.empty()) {
408-
return;
409-
}
406+
// Read all existing entries so we can merge them. Use a large
407+
// MaxNumValueData to retrieve all existing entries.
408+
VDs = getValueProfDataFromInst(I, IPVK_IndirectCallTarget,
409+
/*MaxNumValueData=*/UINT32_MAX, TotalCount);
410410
}
411411

412-
SmallVector<InstrProfValueData, 4> VDs;
413-
uint64_t TotalCount = 0;
412+
// Save the original size for use later in detecting whether any were added.
413+
const size_t OriginalSize = VDs.size();
414+
415+
// Initialize the set of existing guids with the original list.
416+
DenseSet<uint64_t> ExistingValues(
417+
llvm::from_range,
418+
llvm::map_range(
419+
VDs, [](const InstrProfValueData &Entry) { return Entry.Value; }));
414420

415-
for (const GlobalValue::GUID CalleeGUID : CalleeGuids) {
416-
InstrProfValueData VD;
417-
VD.Value = CalleeGUID;
421+
// Merge CalleeGuids into list of existing VDs, by appending any that are not
422+
// already included.
423+
VDs.reserve(OriginalSize + CalleeGuids.size());
424+
for (auto G : CalleeGuids) {
425+
if (!ExistingValues.insert(G).second)
426+
continue;
427+
InstrProfValueData NewEntry;
428+
NewEntry.Value = G;
418429
// For MemProf, we don't have actual call counts, so we assign
419430
// a weight of 1 to each potential target.
420431
// TODO: Consider making this weight configurable or increasing it to
421432
// improve effectiveness for ICP.
422-
VD.Count = 1;
423-
VDs.push_back(VD);
424-
TotalCount += VD.Count;
433+
NewEntry.Count = 1;
434+
TotalCount += NewEntry.Count;
435+
VDs.push_back(NewEntry);
425436
}
426437

427-
if (!VDs.empty()) {
428-
annotateValueSite(M, I, VDs, TotalCount, IPVK_IndirectCallTarget,
429-
VDs.size());
430-
}
438+
// Update the VP metadata if we added any new callee GUIDs to the list.
439+
assert(VDs.size() >= OriginalSize);
440+
if (VDs.size() == OriginalSize)
441+
return;
442+
443+
// First clear the existing !prof.
444+
I.setMetadata(LLVMContext::MD_prof, nullptr);
445+
446+
// No need to sort the updated VDs as all appended entries have the same count
447+
// of 1, which is no larger than any existing entries. The incoming list of
448+
// CalleeGuids should already be deterministic for a given profile.
449+
annotateValueSite(M, I, VDs, TotalCount, IPVK_IndirectCallTarget, VDs.size());
431450
}
432451

433452
static void handleAllocSite(

llvm/test/Transforms/PGOProfile/memprof_annotate_indirect_call.test

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,32 +62,47 @@ HeapProfileRecords:
6262
CallSites:
6363
- Frames:
6464
- { Function: _Z3foov, LineOffset: 3, Column: 5, IsInlineFrame: false }
65-
CalleeGuids: [0x123456789abcdef0, 0x23456789abcdef01]
65+
CalleeGuids: [0x123456789abcdef0, 0x23456789abcdef01, 0x7f8d88fcc70a347b]
6666
- Frames:
6767
- { Function: _Z3foov, LineOffset: 5, Column: 5, IsInlineFrame: false }
6868
CalleeGuids: [0x555556789abcdef0, 0x666656789abcdef1]
69+
- Frames:
70+
- { Function: _Z3foov, LineOffset: 6, Column: 5, IsInlineFrame: false }
71+
CalleeGuids: [0xf129122801e64264, 0x7f8d88fcc70a347b]
6972
...
7073

7174
;--- fdo_conflict.ll
7275
define dso_local void @_Z3foov() !dbg !14 {
7376
entry:
7477
%fp = alloca ptr, align 8
7578
%0 = load ptr, ptr %fp, align 8
76-
; This call already has FDO value profile metadata - should NOT be modified
77-
; CHECK-FDO: call void %0(), {{.*}} !prof !6
79+
; This call already has FDO value profile metadata - new GUIDs should be appended.
80+
; The profile contains 0x7f8d88fcc70a347b (9191153033785521275) which already
81+
; exists in VP metadata and should not be re-added or affect count.
82+
; CHECK-FDO: call void %0(), {{.*}} !prof ![[VP1:[0-9]+]]
7883
call void %0(), !dbg !15, !prof !16
7984

8085
%1 = load ptr, ptr %fp, align 8
8186
; This call does NOT have existing metadata - should get MemProf annotation
82-
; CHECK-FDO: call void %1(), {{.*}} !prof !9
87+
; CHECK-FDO: call void %1(), {{.*}} !prof ![[VP2:[0-9]+]]
8388
call void %1(), !dbg !17
89+
90+
%2 = load ptr, ptr %fp, align 8
91+
; This call already has FDO value profile metadata, and the profile contains
92+
; the same 2 callee guids that are already included in the VP metadata:
93+
; 0x7f8d88fcc70a347b (9191153033785521275) and 0xf129122801e64264 which is
94+
; 17377440600225628772 aka -1069303473483922844. The metadata should not be affected.
95+
; CHECK-FDO: call void %2(), {{.*}} !prof ![[VP3:[0-9]+]]
96+
call void %2(), !dbg !18, !prof !19
8497
ret void
8598
}
8699

87100
!16 = !{!"VP", i32 0, i64 100, i64 9191153033785521275, i64 80, i64 -1069303473483922844, i64 20}
101+
!19 = !{!"VP", i32 0, i64 100, i64 9191153033785521275, i64 80, i64 -1069303473483922844, i64 20}
88102

89-
; CHECK-FDO: !6 = !{!"VP", i32 0, i64 100, i64 9191153033785521275, i64 80, i64 -1069303473483922844, i64 20}
90-
; CHECK-FDO: !9 = !{!"VP", i32 0, i64 2, i64 6148915942236413680, i64 1, i64 7378680115485269745, i64 1}
103+
; CHECK-FDO: ![[VP1]] = !{!"VP", i32 0, i64 102, i64 9191153033785521275, i64 80, i64 -1069303473483922844, i64 20, i64 1311768467463790320, i64 1, i64 2541551405711093505, i64 1}
104+
; CHECK-FDO: ![[VP2]] = !{!"VP", i32 0, i64 2, i64 6148915942236413680, i64 1, i64 7378680115485269745, i64 1}
105+
; CHECK-FDO: ![[VP3]] = !{!"VP", i32 0, i64 100, i64 9191153033785521275, i64 80, i64 -1069303473483922844, i64 20}
91106

92107
!llvm.module.flags = !{!12, !13}
93108

@@ -98,3 +113,4 @@ entry:
98113
!14 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !11, file: !11, line: 1, unit: !10)
99114
!15 = !DILocation(line: 4, column: 5, scope: !14)
100115
!17 = !DILocation(line: 6, column: 5, scope: !14)
116+
!18 = !DILocation(line: 7, column: 5, scope: !14)

0 commit comments

Comments
 (0)