Hello Vedant,
I tried to look into this with Sam and hope my initial analysys will help.
It seems to me that we face some kind of profile counter aliasing:
On slightly different example I see the following in .ll files:
** In inlined code same counters are incremented in 2 differently inlined codes (dpending on define like in the code Sam provided). They look like:
%pgocount.i = load i64, i64* getelementptr inbounds ([2 x i64], [2 x i64]* @__profc__Z22inline_foo_from_headeri, i64 0, i64 0), align 8, !dbg !23
%1 = add i64 %pgocount.i, 1, !dbg !23
store i64 %1, i64* getelementptr inbounds ([2 x i64], [2 x i64]* @__profc__Z22inline_foo_from_headeri, i64 0, i64 0), align 8, !dbg !23 <<<<< Counter #0
…
if.then.i: ; preds = %entry
%pgocount8.i = load i64, i64* getelementptr inbounds ([2 x i64], [2 x i64]* @__profc__Z22inline_foo_from_headeri, i64 0, i64 1), align 8, !dbg !27
%2 = add i64 %pgocount8.i, 1, !dbg !27
store i64 %2, i64* getelementptr inbounds ([2 x i64], [2 x i64]* @__profc__Z22inline_foo_from_headeri, i64 0, i64 1), align 8, !dbg !27 <<<<< Counter #1
The 2nd counter naturally belongs to different code paths in different inlining destination files.
** The counters structure looks like following in both files:
@__profd__Z22inline_foo_from_headeri = linkonce_odr hidden global { i64, i64, i64*, i8*, i8*, i32, [2 x i16] } { i64 -3479956896993626287, i64 10, i64* getelementptr inbounds ([2 x i64], [2 x i64]* @__profc__Z22inline_foo_from_headeri, i32 0, i32 0), i8* bitcast (i32 (i32)* @_Z22inline_foo_from_headeri to i8*), i8* null, i32 2, [2 x i16] zeroinitializer }, section “__llvm_prf_data”, comdat($__profv__Z22inline_foo_from_headeri), align 8
So the counters are definitely shared between inlined instances, This looks reasonable.
** The __llvm_coverage_mapping structures are indeed different, but refere to same counters:
@__llvm_coverage_mapping = internal constant { { i32, i32, i32, i32 }, [2 x <{ i64, i32, i64 }>], [192 x i8] } { { i32, i32, i32, i32 } { i32 2, i32 148, i32 44, i32 1 }, [2 x <{ i64, i32, i64 }>] [<{ i64, i32, i64 }> <{ i64 -2070989330109684161, i32 9, i64 0 }>, <{ i64, i32, i64 }> <{ i64 -3479956896993626287, i32 31, i64 10 }>], [192 x i8] c"\02D/xxxx/xxxxxx/xxx/xxxx/xxxxxxxxx/test/compilation_flags/lib1/lib1.cppM/xxxx/xxxxxx/xxx/xxxx/xxxxxxxxx/test/compilation_flags/header/single_header.h
\01\00\00\01
\01\03\15\02\02\
01\01\ << This is about /xxxx/xxxxxx/xxx/xxxx/xxxxxxxxx/test/compilation_flags/header/single_header.h
01\01\05\ << One expression(counter #0, #1) — There was an else branch in one of my cases
05
01\03\2B\0E\02\ << This is for counter #0
01\03\09\00\0A\ << This is for counter #0
05\01\09\00\14\ << This is for counter #1
02\02\09\00\14\ << This is subtraction for counters #0-#1 according to expression above
10\01\02\04\02\ << This is skipped region because of #ifdef
00\00\00\00" }, section “__llvm_covmap”, align 8
And
@__llvm_coverage_mapping = internal constant { { i32, i32, i32, i32 }, [2 x <{ i64, i32, i64 }>], [184 x i8] } { { i32, i32, i32, i32 } { i32 2, i32 148, i32 36, i32 1 }, [2 x <{ i64, i32, i64 }>] [<{ i64, i32, i64 }> <{ i64 7422656158144208762, i32 9, i64 0 }>, <{ i64, i32, i64 }> <{ i64 -3479956896993626287, i32 24, i64 10 }>], [184 x i8] c"\02D/xxxx/xxxxxx/xxx/xxxx/xxxxxxxxx/test/compilation_flags/lib2/lib2.cppM/xxxx/xxxxxx/xxx/xxxx/xxxxxxxxx/test/compilation_flags/header/single_header.h
\01\00\00\01
01\03\15\02\02\
01\01\ << This is about /xxxx/xxxxxx/xxx/xxxx/xxxxxxxxx/test/compilation_flags/header/single_header.h
00\ << no expressions in this case
04
01\03\2B\0E\02\ << This is for counter #0
10\02\02\05\02\ << This is skipped region because of #ifdef
01\06\09\00\0A\ << This is for counter #0
05\01\09\00\14\ << This is for counter #1
00\00\00" }, section “__llvm_covmap”, align 8