From 3f8d86814ad40daf5c8cb583f0f66585b057c7b8 Mon Sep 17 00:00:00 2001 From: CodSpeed Bot Date: Fri, 24 Jul 2026 15:21:05 +0000 Subject: [PATCH] perf(callgrind): inline CLG_(get_fn_entry) to remove a per-basic-block call CLG_(setup_bbcc) runs on every basic-block execution and called the out-of-line CLG_(get_fn_entry) in fn.c once per BB (the separate_recursions > 1 path, active by default). Because the accessor lived in a different translation unit, the compiler could not inline what is a single array index. Expose current_fn_active as CLG_(current_fn_active) and move get_fn_entry into global.h as a static __inline__ accessor after CLG_ASSERT. Disassembly of the built tool confirms zero remaining call sites; Callgrind output is byte-for-byte identical (default and --separate-recs=3). --- callgrind/fn.c | 11 ++++------- callgrind/global.h | 18 +++++++++++++++++- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/callgrind/fn.c b/callgrind/fn.c index f1d96aca1..a117bae08 100644 --- a/callgrind/fn.c +++ b/callgrind/fn.c @@ -28,7 +28,10 @@ #define N_INITIAL_FN_ARRAY_SIZE 10071 -static fn_array current_fn_active; +/* The active function array. Defined here but declared in global.h so the + * hot-path accessor CLG_(get_fn_entry) can be inlined. */ +fn_array CLG_(current_fn_active); +#define current_fn_active CLG_(current_fn_active) /* x86_64 defines 4 variants. */ #define MAX_RESOLVE_ADDRS 4 @@ -783,12 +786,6 @@ fn_node* CLG_(get_fn_node)(BB* bb) * levels should be separated. */ -UInt* CLG_(get_fn_entry)(Int n) -{ - CLG_ASSERT(n < current_fn_active.size); - return current_fn_active.array + n; -} - void CLG_(init_fn_array)(fn_array* a) { Int i; diff --git a/callgrind/global.h b/callgrind/global.h index 10d4c53b1..bf3dc664f 100644 --- a/callgrind/global.h +++ b/callgrind/global.h @@ -730,7 +730,12 @@ void CLG_(init_fn_array)(fn_array*); void CLG_(copy_current_fn_array)(fn_array* dst); fn_array* CLG_(get_current_fn_array)(void); void CLG_(set_current_fn_array)(fn_array*); -UInt* CLG_(get_fn_entry)(Int n); + +/* The active function array (function number -> active count). This is on + * the per-BB hot path (setup_bbcc, get_cxt, ...), so the accessor is inlined + * (see CLG_(get_fn_entry) below) to avoid a cross-TU function call for what + * is a single array index. */ +extern fn_array CLG_(current_fn_active); void CLG_(init_obj_table)(void); obj_node* CLG_(get_obj_node)(DebugInfo* si); @@ -853,6 +858,17 @@ extern ULong* CLG_(cost_base); #define CLG_ASSERT(cond) tl_assert(cond); #endif +/* Inlined hot-path accessor for the active function array. Defined after + * CLG_ASSERT so the assertion is available. Called once per basic block from + * setup_bbcc() (and from get_cxt/push_cxt), previously as an out-of-line + * cross-TU call in fn.c. */ +static __inline__ +UInt* CLG_(get_fn_entry)(Int n) +{ + CLG_ASSERT(n < CLG_(current_fn_active).size); + return CLG_(current_fn_active).array + n; +} + /* from debug.c */ void CLG_(print_bbno)(void); void CLG_(print_context)(void);