diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 0e87a8e2ace0e..f169ab941c457 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -14139,6 +14139,41 @@ Semantics: """""""""" See description of '``llvm.instrprof.increment``' intrinsic. +'``llvm.instrprof.callsite``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +:: + + declare void @llvm.instrprof.callsite(ptr , i64 , + i32 , + i32 , ptr ) + +Overview: +""""""""" + +.. FIXME: detail when it's emitted once the support is added + +The '``llvm.instrprof.callsite``' intrinsic should be emitted before a callsite +that's not to a "fake" callee (like another intrinsic or asm). + +Arguments: +"""""""""" +The first 4 arguments are similar to ``llvm.instrprof.increment``. The indexing +is specific to callsites, meaning callsites are indexed from 0, independent from +the indexes used by the other intrinsics (such as +``llvm.instrprof.increment[.step]``). + +The last argument is the called value of the callsite this intrinsic precedes. + +Semantics: +"""""""""" +.. FIXME: detail how when the lowering pass is added. + +This is lowered by contextual profiling. + '``llvm.instrprof.timestamp``' Intrinsic ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h index 4f22720f1c558..081e72cc82b2c 100644 --- a/llvm/include/llvm/IR/IntrinsicInst.h +++ b/llvm/include/llvm/IR/IntrinsicInst.h @@ -1435,6 +1435,7 @@ class InstrProfInstBase : public IntrinsicInst { case Intrinsic::instrprof_cover: case Intrinsic::instrprof_increment: case Intrinsic::instrprof_increment_step: + case Intrinsic::instrprof_callsite: case Intrinsic::instrprof_timestamp: case Intrinsic::instrprof_value_profile: return true; @@ -1519,6 +1520,21 @@ class InstrProfIncrementInstStep : public InstrProfIncrementInst { } }; +/// This represents the llvm.instrprof.callsite intrinsic. +/// It is structurally like the increment or step counters, hence the +/// inheritance relationship, albeit somewhat tenuous (it's not 'counting' per +/// se) +class InstrProfCallsite : public InstrProfCntrInstBase { +public: + static bool classof(const IntrinsicInst *I) { + return I->getIntrinsicID() == Intrinsic::instrprof_callsite; + } + static bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } + Value *getCallee() const; +}; + /// This represents the llvm.instrprof.timestamp intrinsic. class InstrProfTimestampInst : public InstrProfCntrInstBase { public: diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index 1d20f7e1b1985..a14e9dedef8c9 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -914,6 +914,11 @@ def int_instrprof_increment_step : Intrinsic<[], [llvm_ptr_ty, llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i64_ty]>; +// Callsite instrumentation for contextual profiling +def int_instrprof_callsite : Intrinsic<[], + [llvm_ptr_ty, llvm_i64_ty, + llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty]>; + // A timestamp for instrumentation based profiling. def int_instrprof_timestamp : Intrinsic<[], [llvm_ptr_ty, llvm_i64_ty, llvm_i32_ty, llvm_i32_ty]>; diff --git a/llvm/lib/IR/IntrinsicInst.cpp b/llvm/lib/IR/IntrinsicInst.cpp index 89403e1d7fcb4..8faeb4e9951f7 100644 --- a/llvm/lib/IR/IntrinsicInst.cpp +++ b/llvm/lib/IR/IntrinsicInst.cpp @@ -291,6 +291,12 @@ Value *InstrProfIncrementInst::getStep() const { return ConstantInt::get(Type::getInt64Ty(Context), 1); } +Value *InstrProfCallsite::getCallee() const { + if (isa(this)) + return getArgOperand(4); + return nullptr; +} + std::optional ConstrainedFPIntrinsic::getRoundingMode() const { unsigned NumOperands = arg_size(); Metadata *MD = nullptr; diff --git a/llvm/unittests/IR/IntrinsicsTest.cpp b/llvm/unittests/IR/IntrinsicsTest.cpp index 3fa4b2cf73b6b..dddd2f73d4446 100644 --- a/llvm/unittests/IR/IntrinsicsTest.cpp +++ b/llvm/unittests/IR/IntrinsicsTest.cpp @@ -81,6 +81,7 @@ TEST_F(IntrinsicsTest, InstrProfInheritance) { __ISA(InstrProfCoverInst, InstrProfCntrInstBase); __ISA(InstrProfIncrementInst, InstrProfCntrInstBase); __ISA(InstrProfIncrementInstStep, InstrProfIncrementInst); + __ISA(InstrProfCallsite, InstrProfCntrInstBase); __ISA(InstrProfTimestampInst, InstrProfCntrInstBase); __ISA(InstrProfValueProfileInst, InstrProfCntrInstBase); __ISA(InstrProfMCDCBitmapInstBase, InstrProfInstBase); @@ -94,6 +95,7 @@ TEST_F(IntrinsicsTest, InstrProfInheritance) { {Intrinsic::instrprof_cover, isInstrProfCoverInst}, {Intrinsic::instrprof_increment, isInstrProfIncrementInst}, {Intrinsic::instrprof_increment_step, isInstrProfIncrementInstStep}, + {Intrinsic::instrprof_callsite, isInstrProfCallsite}, {Intrinsic::instrprof_mcdc_condbitmap_update, isInstrProfMCDCCondBitmapUpdate}, {Intrinsic::instrprof_mcdc_parameters,