From a5ba3aa961b8ca8dd369ff8edfce1f5d22908d18 Mon Sep 17 00:00:00 2001 From: Mircea Trofin Date: Fri, 23 Aug 2024 10:31:43 -0700 Subject: [PATCH] [ctx_prof] Remove the dependency on the "name" GlobalVariable (#105731) We don't need that name variable for contextual instrumentation, we just use the function to get its GUID which we pass to the runtime, and rely on metadata to capture it through the various optimization passes. This change removes the need for the name global variable. --- llvm/include/llvm/IR/IntrinsicInst.h | 14 +++++-- .../Instrumentation/PGOCtxProfLowering.cpp | 3 +- .../Instrumentation/PGOInstrumentation.cpp | 15 +++---- .../PGOProfile/ctx-instrumentation.ll | 41 +++++++------------ .../PGOProfile/ctx-prof-use-prelink.ll | 11 ++--- 5 files changed, 39 insertions(+), 45 deletions(-) diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h index c188bec631a239b..b45c89cadb0fde6 100644 --- a/llvm/include/llvm/IR/IntrinsicInst.h +++ b/llvm/include/llvm/IR/IntrinsicInst.h @@ -1503,11 +1503,19 @@ class InstrProfInstBase : public IntrinsicInst { return isCounterBase(*Instr) || isMCDCBitmapBase(*Instr); return false; } - // The name of the instrumented function. + + // The name of the instrumented function, assuming it is a global variable. GlobalVariable *getName() const { - return cast( - const_cast(getArgOperand(0))->stripPointerCasts()); + return cast(getNameValue()); + } + + // The "name" operand of the profile instrumentation instruction - this is the + // operand that can be used to relate the instruction to the function it + // belonged to at instrumentation time. + Value *getNameValue() const { + return const_cast(getArgOperand(0))->stripPointerCasts(); } + // The hash of the CFG for the instrumented function. ConstantInt *getHash() const { return cast(const_cast(getArgOperand(1))); diff --git a/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp b/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp index 9b10cbba84075a4..43bebc99316e067 100644 --- a/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp +++ b/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp @@ -226,7 +226,8 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) { IRBuilder<> Builder(Mark); - Guid = Builder.getInt64(AssignGUIDPass::getGUID(F)); + Guid = Builder.getInt64( + AssignGUIDPass::getGUID(cast(*Mark->getNameValue()))); // The type of the context of this function is now knowable since we have // NrCallsites and NrCounters. We delcare it here because it's more // convenient - we have the Builder. diff --git a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp index 39cf94daab7d3b0..aacfe39f16fbc43 100644 --- a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp +++ b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp @@ -464,7 +464,7 @@ struct SelectInstVisitor : public InstVisitor { VisitMode Mode = VM_counting; // Visiting mode. unsigned *CurCtrIdx = nullptr; // Pointer to current counter index. unsigned TotalNumCtrs = 0; // Total number of counters - GlobalVariable *FuncNameVar = nullptr; + GlobalValue *FuncNameVar = nullptr; uint64_t FuncHash = 0; PGOUseFunc *UseFunc = nullptr; bool HasSingleByteCoverage; @@ -482,7 +482,7 @@ struct SelectInstVisitor : public InstVisitor { // Ind is a pointer to the counter index variable; \p TotalNC // is the total number of counters; \p FNV is the pointer to the // PGO function name var; \p FHash is the function hash. - void instrumentSelects(unsigned *Ind, unsigned TotalNC, GlobalVariable *FNV, + void instrumentSelects(unsigned *Ind, unsigned TotalNC, GlobalValue *FNV, uint64_t FHash) { Mode = VM_instrument; CurCtrIdx = Ind; @@ -901,13 +901,14 @@ void FunctionInstrumenter::instrument() { SplitIndirectBrCriticalEdges(F, /*IgnoreBlocksWithoutPHI=*/false, BPI, BFI); } + const bool IsCtxProf = InstrumentationType == PGOInstrumentationType::CTXPROF; FuncPGOInstrumentation FuncInfo( - F, TLI, ComdatMembers, true, BPI, BFI, + F, TLI, ComdatMembers, /*CreateGlobalVar=*/!IsCtxProf, BPI, BFI, InstrumentationType == PGOInstrumentationType::CSFDO, shouldInstrumentEntryBB(), PGOBlockCoverage); - auto Name = FuncInfo.FuncNameVar; - auto CFGHash = + auto *const Name = IsCtxProf ? cast(&F) : FuncInfo.FuncNameVar; + auto *const CFGHash = ConstantInt::get(Type::getInt64Ty(M.getContext()), FuncInfo.FunctionHash); // Make sure that pointer to global is passed in with zero addrspace // This is relevant during GPU profiling @@ -929,7 +930,7 @@ void FunctionInstrumenter::instrument() { unsigned NumCounters = InstrumentBBs.size() + FuncInfo.SIVisitor.getNumOfSelectInsts(); - if (InstrumentationType == PGOInstrumentationType::CTXPROF) { + if (IsCtxProf) { auto *CSIntrinsic = Intrinsic::getDeclaration(&M, Intrinsic::instrprof_callsite); // We want to count the instrumentable callsites, then instrument them. This @@ -995,7 +996,7 @@ void FunctionInstrumenter::instrument() { } // Now instrument select instructions: - FuncInfo.SIVisitor.instrumentSelects(&I, NumCounters, FuncInfo.FuncNameVar, + FuncInfo.SIVisitor.instrumentSelects(&I, NumCounters, Name, FuncInfo.FunctionHash); assert(I == NumCounters); diff --git a/llvm/test/Transforms/PGOProfile/ctx-instrumentation.ll b/llvm/test/Transforms/PGOProfile/ctx-instrumentation.ll index df4e467567c46ef..c94c2b4da57a98a 100644 --- a/llvm/test/Transforms/PGOProfile/ctx-instrumentation.ll +++ b/llvm/test/Transforms/PGOProfile/ctx-instrumentation.ll @@ -9,19 +9,6 @@ declare void @bar() ;. -; INSTRUMENT: @__profn_foo = private constant [3 x i8] c"foo" -; INSTRUMENT: @__profn_an_entrypoint = private constant [13 x i8] c"an_entrypoint" -; INSTRUMENT: @__profn_another_entrypoint_no_callees = private constant [29 x i8] c"another_entrypoint_no_callees" -; INSTRUMENT: @__profn_simple = private constant [6 x i8] c"simple" -; INSTRUMENT: @__profn_no_callsites = private constant [12 x i8] c"no_callsites" -; INSTRUMENT: @__profn_no_counters = private constant [11 x i8] c"no_counters" -;. -; LOWERING: @__profn_foo = private constant [3 x i8] c"foo" -; LOWERING: @__profn_an_entrypoint = private constant [13 x i8] c"an_entrypoint" -; LOWERING: @__profn_another_entrypoint_no_callees = private constant [29 x i8] c"another_entrypoint_no_callees" -; LOWERING: @__profn_simple = private constant [6 x i8] c"simple" -; LOWERING: @__profn_no_callsites = private constant [12 x i8] c"no_callsites" -; LOWERING: @__profn_no_counters = private constant [11 x i8] c"no_counters" ; LOWERING: @an_entrypoint_ctx_root = global { ptr, ptr, ptr, i8 } zeroinitializer ; LOWERING: @another_entrypoint_no_callees_ctx_root = global { ptr, ptr, ptr, i8 } zeroinitializer ; LOWERING: @__llvm_ctx_profile_callsite = external hidden thread_local global ptr @@ -30,16 +17,16 @@ declare void @bar() define void @foo(i32 %a, ptr %fct) { ; INSTRUMENT-LABEL: define void @foo( ; INSTRUMENT-SAME: i32 [[A:%.*]], ptr [[FCT:%.*]]) { -; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @__profn_foo, i64 728453322856651412, i32 2, i32 0) +; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @foo, i64 728453322856651412, i32 2, i32 0) ; INSTRUMENT-NEXT: [[T:%.*]] = icmp eq i32 [[A]], 0 ; INSTRUMENT-NEXT: br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]] ; INSTRUMENT: yes: -; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @__profn_foo, i64 728453322856651412, i32 2, i32 1) -; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @__profn_foo, i64 728453322856651412, i32 2, i32 0, ptr [[FCT]]) +; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @foo, i64 728453322856651412, i32 2, i32 1) +; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @foo, i64 728453322856651412, i32 2, i32 0, ptr [[FCT]]) ; INSTRUMENT-NEXT: call void [[FCT]](i32 [[A]]) ; INSTRUMENT-NEXT: br label [[EXIT:%.*]] ; INSTRUMENT: no: -; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @__profn_foo, i64 728453322856651412, i32 2, i32 1, ptr @bar) +; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @foo, i64 728453322856651412, i32 2, i32 1, ptr @bar) ; INSTRUMENT-NEXT: call void @bar() ; INSTRUMENT-NEXT: br label [[EXIT]] ; INSTRUMENT: exit: @@ -92,12 +79,12 @@ exit: define void @an_entrypoint(i32 %a) { ; INSTRUMENT-LABEL: define void @an_entrypoint( ; INSTRUMENT-SAME: i32 [[A:%.*]]) { -; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @__profn_an_entrypoint, i64 784007058953177093, i32 2, i32 0) +; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @an_entrypoint, i64 784007058953177093, i32 2, i32 0) ; INSTRUMENT-NEXT: [[T:%.*]] = icmp eq i32 [[A]], 0 ; INSTRUMENT-NEXT: br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]] ; INSTRUMENT: yes: -; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @__profn_an_entrypoint, i64 784007058953177093, i32 2, i32 1) -; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @__profn_an_entrypoint, i64 784007058953177093, i32 1, i32 0, ptr @foo) +; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @an_entrypoint, i64 784007058953177093, i32 2, i32 1) +; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @an_entrypoint, i64 784007058953177093, i32 1, i32 0, ptr @foo) ; INSTRUMENT-NEXT: call void @foo(i32 1, ptr null) ; INSTRUMENT-NEXT: ret void ; INSTRUMENT: no: @@ -144,11 +131,11 @@ no: define void @another_entrypoint_no_callees(i32 %a) { ; INSTRUMENT-LABEL: define void @another_entrypoint_no_callees( ; INSTRUMENT-SAME: i32 [[A:%.*]]) { -; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @__profn_another_entrypoint_no_callees, i64 784007058953177093, i32 2, i32 0) +; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @another_entrypoint_no_callees, i64 784007058953177093, i32 2, i32 0) ; INSTRUMENT-NEXT: [[T:%.*]] = icmp eq i32 [[A]], 0 ; INSTRUMENT-NEXT: br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]] ; INSTRUMENT: yes: -; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @__profn_another_entrypoint_no_callees, i64 784007058953177093, i32 2, i32 1) +; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @another_entrypoint_no_callees, i64 784007058953177093, i32 2, i32 1) ; INSTRUMENT-NEXT: ret void ; INSTRUMENT: no: ; INSTRUMENT-NEXT: ret void @@ -184,7 +171,7 @@ no: define void @simple(i32 %a) { ; INSTRUMENT-LABEL: define void @simple( ; INSTRUMENT-SAME: i32 [[A:%.*]]) { -; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @__profn_simple, i64 742261418966908927, i32 1, i32 0) +; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @simple, i64 742261418966908927, i32 1, i32 0) ; INSTRUMENT-NEXT: ret void ; ; LOWERING-LABEL: define void @simple( @@ -202,11 +189,11 @@ define void @simple(i32 %a) { define i32 @no_callsites(i32 %a) { ; INSTRUMENT-LABEL: define i32 @no_callsites( ; INSTRUMENT-SAME: i32 [[A:%.*]]) { -; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @__profn_no_callsites, i64 784007058953177093, i32 2, i32 0) +; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @no_callsites, i64 784007058953177093, i32 2, i32 0) ; INSTRUMENT-NEXT: [[C:%.*]] = icmp eq i32 [[A]], 0 ; INSTRUMENT-NEXT: br i1 [[C]], label [[YES:%.*]], label [[NO:%.*]] ; INSTRUMENT: yes: -; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @__profn_no_callsites, i64 784007058953177093, i32 2, i32 1) +; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @no_callsites, i64 784007058953177093, i32 2, i32 1) ; INSTRUMENT-NEXT: ret i32 1 ; INSTRUMENT: no: ; INSTRUMENT-NEXT: ret i32 0 @@ -238,8 +225,8 @@ no: define void @no_counters() { ; INSTRUMENT-LABEL: define void @no_counters() { -; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @__profn_no_counters, i64 742261418966908927, i32 1, i32 0) -; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @__profn_no_counters, i64 742261418966908927, i32 1, i32 0, ptr @bar) +; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @no_counters, i64 742261418966908927, i32 1, i32 0) +; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @no_counters, i64 742261418966908927, i32 1, i32 0, ptr @bar) ; INSTRUMENT-NEXT: call void @bar() ; INSTRUMENT-NEXT: ret void ; diff --git a/llvm/test/Transforms/PGOProfile/ctx-prof-use-prelink.ll b/llvm/test/Transforms/PGOProfile/ctx-prof-use-prelink.ll index cb8ab78dc0f4143..7959e4d0760edbe 100644 --- a/llvm/test/Transforms/PGOProfile/ctx-prof-use-prelink.ll +++ b/llvm/test/Transforms/PGOProfile/ctx-prof-use-prelink.ll @@ -7,22 +7,19 @@ declare void @bar() -;. -; CHECK: @__profn_foo = private constant [3 x i8] c"foo" -;. define void @foo(i32 %a, ptr %fct) { ; CHECK-LABEL: define void @foo( ; CHECK-SAME: i32 [[A:%.*]], ptr [[FCT:%.*]]) local_unnamed_addr !guid [[META0:![0-9]+]] { -; CHECK-NEXT: call void @llvm.instrprof.increment(ptr @__profn_foo, i64 728453322856651412, i32 2, i32 0) +; CHECK-NEXT: call void @llvm.instrprof.increment(ptr @foo, i64 728453322856651412, i32 2, i32 0) ; CHECK-NEXT: [[T:%.*]] = icmp eq i32 [[A]], 0 ; CHECK-NEXT: br i1 [[T]], label %[[YES:.*]], label %[[NO:.*]] ; CHECK: [[YES]]: -; CHECK-NEXT: call void @llvm.instrprof.increment(ptr @__profn_foo, i64 728453322856651412, i32 2, i32 1) -; CHECK-NEXT: call void @llvm.instrprof.callsite(ptr @__profn_foo, i64 728453322856651412, i32 2, i32 0, ptr [[FCT]]) +; CHECK-NEXT: call void @llvm.instrprof.increment(ptr @foo, i64 728453322856651412, i32 2, i32 1) +; CHECK-NEXT: call void @llvm.instrprof.callsite(ptr @foo, i64 728453322856651412, i32 2, i32 0, ptr [[FCT]]) ; CHECK-NEXT: call void [[FCT]](i32 0) ; CHECK-NEXT: br label %[[EXIT:.*]] ; CHECK: [[NO]]: -; CHECK-NEXT: call void @llvm.instrprof.callsite(ptr @__profn_foo, i64 728453322856651412, i32 2, i32 1, ptr @bar) +; CHECK-NEXT: call void @llvm.instrprof.callsite(ptr @foo, i64 728453322856651412, i32 2, i32 1, ptr @bar) ; CHECK-NEXT: call void @bar() ; CHECK-NEXT: br label %[[EXIT]] ; CHECK: [[EXIT]]: