Skip to content

Commit b0af1e2

Browse files
committed
[llvm][ctx_profile] Add instrumentation
This adds instrumenting callsites to PGOInstrumentation, *if* contextual profiling is requested. The latter also enables inserting counters in the entry basic block and disables value profiling (the latter is a point in time change) This change adds the skeleton of the contextual profiling lowering pass, just so we can introduce the flag controlling that and the API to check that. The actual lowering pass will be introduced in a subsequent patch. (Tracking Issue: llvm#89287, RFC referenced there)
1 parent a5c4f96 commit b0af1e2

File tree

5 files changed

+130
-8
lines changed

5 files changed

+130
-8
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//===-- PGOCtxProfLowering.h - Contextual PGO Instr. Lowering ---*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file declares the PGOCtxProfLoweringPass class.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_PGOCTXPROFLOWERING_H
13+
#define LLVM_TRANSFORMS_INSTRUMENTATION_PGOCTXPROFLOWERING_H
14+
15+
namespace llvm {
16+
class Type;
17+
18+
class PGOCtxProfLoweringPass {
19+
public:
20+
explicit PGOCtxProfLoweringPass() = default;
21+
static bool isContextualIRPGOEnabled();
22+
};
23+
} // namespace llvm
24+
#endif

llvm/lib/Transforms/Instrumentation/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ add_llvm_component_library(LLVMInstrumentation
1414
InstrProfiling.cpp
1515
KCFI.cpp
1616
LowerAllowCheckPass.cpp
17+
PGOCtxProfLowering.cpp
1718
PGOForceFunctionAttrs.cpp
1819
PGOInstrumentation.cpp
1920
PGOMemOPSizeOpt.cpp
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//===- PGOCtxProfLowering.cpp - Contextual PGO Instr. Lowering ------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
10+
#include "llvm/Transforms/Instrumentation/PGOCtxProfLowering.h"
11+
#include "llvm/Support/CommandLine.h"
12+
13+
using namespace llvm;
14+
15+
static cl::list<std::string> ContextRoots("profile-context-root");
16+
17+
bool PGOCtxProfLoweringPass::isContextualIRPGOEnabled() {
18+
return !ContextRoots.empty();
19+
}

llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
#include "llvm/Transforms/Instrumentation.h"
111111
#include "llvm/Transforms/Instrumentation/BlockCoverageInference.h"
112112
#include "llvm/Transforms/Instrumentation/CFGMST.h"
113+
#include "llvm/Transforms/Instrumentation/PGOCtxProfLowering.h"
113114
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
114115
#include "llvm/Transforms/Utils/MisExpect.h"
115116
#include "llvm/Transforms/Utils/ModuleUtils.h"
@@ -333,6 +334,16 @@ extern cl::opt<bool> EnableVTableValueProfiling;
333334
extern cl::opt<InstrProfCorrelator::ProfCorrelatorKind> ProfileCorrelate;
334335
} // namespace llvm
335336

337+
bool shouldInstrumentEntryBB() {
338+
return PGOInstrumentEntry ||
339+
PGOCtxProfLoweringPass::isContextualIRPGOEnabled();
340+
}
341+
342+
bool isValueProfilingDisabled() {
343+
return DisableValueProfiling ||
344+
PGOCtxProfLoweringPass::isContextualIRPGOEnabled();
345+
}
346+
336347
// Return a string describing the branch condition that can be
337348
// used in static branch probability heuristics:
338349
static std::string getBranchCondString(Instruction *TI) {
@@ -379,7 +390,7 @@ static GlobalVariable *createIRLevelProfileFlagVar(Module &M, bool IsCS) {
379390
uint64_t ProfileVersion = (INSTR_PROF_RAW_VERSION | VARIANT_MASK_IR_PROF);
380391
if (IsCS)
381392
ProfileVersion |= VARIANT_MASK_CSIR_PROF;
382-
if (PGOInstrumentEntry)
393+
if (shouldInstrumentEntryBB())
383394
ProfileVersion |= VARIANT_MASK_INSTR_ENTRY;
384395
if (DebugInfoCorrelate || ProfileCorrelate == InstrProfCorrelator::DEBUG_INFO)
385396
ProfileVersion |= VARIANT_MASK_DBG_CORRELATE;
@@ -861,7 +872,7 @@ static void instrumentOneFunc(
861872
}
862873

863874
FuncPGOInstrumentation<PGOEdge, PGOBBInfo> FuncInfo(
864-
F, TLI, ComdatMembers, true, BPI, BFI, IsCS, PGOInstrumentEntry,
875+
F, TLI, ComdatMembers, true, BPI, BFI, IsCS, shouldInstrumentEntryBB(),
865876
PGOBlockCoverage);
866877

867878
auto Name = FuncInfo.FuncNameVar;
@@ -883,6 +894,33 @@ static void instrumentOneFunc(
883894
unsigned NumCounters =
884895
InstrumentBBs.size() + FuncInfo.SIVisitor.getNumOfSelectInsts();
885896

897+
if (PGOCtxProfLoweringPass::isContextualIRPGOEnabled()) {
898+
auto *CSIntrinsic =
899+
Intrinsic::getDeclaration(M, Intrinsic::instrprof_callsite);
900+
auto Visit = [&](llvm::function_ref<void(CallBase * CB)> Visitor) {
901+
for (auto &BB : F)
902+
for (auto &Instr : BB)
903+
if (auto *CS = dyn_cast<CallBase>(&Instr)) {
904+
if ((CS->getCalledFunction() &&
905+
CS->getCalledFunction()->isIntrinsic()) ||
906+
dyn_cast<InlineAsm>(CS->getCalledOperand()))
907+
continue;
908+
Visitor(CS);
909+
}
910+
};
911+
uint32_t TotalNrCallsites = 0;
912+
Visit([&TotalNrCallsites](auto *) { ++TotalNrCallsites; });
913+
uint32_t CallsiteIndex = 0;
914+
915+
Visit([&](auto *CB) {
916+
IRBuilder<> Builder(CB);
917+
Builder.CreateCall(CSIntrinsic,
918+
{Name, CFGHash, Builder.getInt32(TotalNrCallsites),
919+
Builder.getInt32(CallsiteIndex++),
920+
CB->getCalledOperand()});
921+
});
922+
}
923+
886924
uint32_t I = 0;
887925
if (PGOTemporalInstrumentation) {
888926
NumCounters += PGOBlockCoverage ? 8 : 1;
@@ -914,7 +952,7 @@ static void instrumentOneFunc(
914952
FuncInfo.FunctionHash);
915953
assert(I == NumCounters);
916954

917-
if (DisableValueProfiling)
955+
if (isValueProfilingDisabled())
918956
return;
919957

920958
NumOfPGOICall += FuncInfo.ValueSites[IPVK_IndirectCallTarget].size();
@@ -1676,7 +1714,7 @@ void SelectInstVisitor::visitSelectInst(SelectInst &SI) {
16761714

16771715
// Traverse all valuesites and annotate the instructions for all value kind.
16781716
void PGOUseFunc::annotateValueSites() {
1679-
if (DisableValueProfiling)
1717+
if (isValueProfilingDisabled())
16801718
return;
16811719

16821720
// Create the PGOFuncName meta data.
@@ -1779,7 +1817,7 @@ static bool InstrumentAllFunctions(
17791817
function_ref<BlockFrequencyInfo *(Function &)> LookupBFI, bool IsCS) {
17801818
// For the context-sensitve instrumentation, we should have a separated pass
17811819
// (before LTO/ThinLTO linking) to create these variables.
1782-
if (!IsCS)
1820+
if (!IsCS && !PGOCtxProfLoweringPass::isContextualIRPGOEnabled())
17831821
createIRLevelProfileFlagVar(M, /*IsCS=*/false);
17841822

17851823
Triple TT(M.getTargetTriple());
@@ -2015,9 +2053,8 @@ static bool annotateAllFunctions(
20152053

20162054
// If the profile marked as always instrument the entry BB, do the
20172055
// same. Note this can be overwritten by the internal option in CFGMST.h
2018-
bool InstrumentFuncEntry = PGOReader->instrEntryBBEnabled();
2019-
if (PGOInstrumentEntry.getNumOccurrences() > 0)
2020-
InstrumentFuncEntry = PGOInstrumentEntry;
2056+
bool InstrumentFuncEntry =
2057+
PGOReader->instrEntryBBEnabled() || shouldInstrumentEntryBB();
20212058
bool HasSingleByteCoverage = PGOReader->hasSingleByteCoverage();
20222059
for (auto &F : M) {
20232060
if (skipPGOUse(F))
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 4
2+
; RUN: opt -passes=pgo-instr-gen -profile-context-root=an_entrypoint \
3+
; RUN: -S < %s | FileCheck --check-prefix=INSTRUMENT %s
4+
5+
declare void @bar()
6+
7+
;.
8+
; INSTRUMENT: @__profn_foo = private constant [3 x i8] c"foo"
9+
;.
10+
define void @foo(i32 %a, ptr %fct) {
11+
; INSTRUMENT-LABEL: define void @foo(
12+
; INSTRUMENT-SAME: i32 [[A:%.*]], ptr [[FCT:%.*]]) {
13+
; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @__profn_foo, i64 728453322856651412, i32 2, i32 0)
14+
; INSTRUMENT-NEXT: [[T:%.*]] = icmp eq i32 [[A]], 0
15+
; INSTRUMENT-NEXT: br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]]
16+
; INSTRUMENT: yes:
17+
; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @__profn_foo, i64 728453322856651412, i32 2, i32 1)
18+
; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @__profn_foo, i64 728453322856651412, i32 2, i32 0, ptr [[FCT]])
19+
; INSTRUMENT-NEXT: call void [[FCT]](i32 [[A]])
20+
; INSTRUMENT-NEXT: br label [[EXIT:%.*]]
21+
; INSTRUMENT: no:
22+
; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @__profn_foo, i64 728453322856651412, i32 2, i32 1, ptr @bar)
23+
; INSTRUMENT-NEXT: call void @bar()
24+
; INSTRUMENT-NEXT: br label [[EXIT]]
25+
; INSTRUMENT: exit:
26+
; INSTRUMENT-NEXT: ret void
27+
;
28+
%t = icmp eq i32 %a, 0
29+
br i1 %t, label %yes, label %no
30+
yes:
31+
call void %fct(i32 %a)
32+
br label %exit
33+
no:
34+
call void @bar()
35+
br label %exit
36+
exit:
37+
ret void
38+
}
39+
;.
40+
; INSTRUMENT: attributes #[[ATTR0:[0-9]+]] = { nounwind }
41+
;.

0 commit comments

Comments
 (0)