Finding the first line number of a function (-g vs -gline-tables-only)

For the sample profiler, I need to determine the location of the first
user instruction in the function. This can be the LOC where the
function header is or the LOC of the actual first instruction, it
doesn't really matter. But it needs to be consistent wrt -g and
-gline-tables-only.

Currently, I'm scanning for the first non-zero line number from the
top of the function. This skips over the frame setup instructions
emitted by the compiler, that have no LOC, but it gives me different
results depending on whether -g or -gline-tables-only is used, and
whether the function has arguments:

- If -g is used, and the function has arguments, the first non-zero
loc instruction is the debug declaration call for the first argument:
call void @llvm.dbg.declare(...)
- If -g is used, and the function has no arguments, the first non-zero
loc instruction is the first user instruction.
- Similarly, if -gline-tables-only is used, we do not emit debug
declarations for the arguments, so the first non-zero loc is the first
user instruction.

I want to modify the scanning I do in my pass to skip over all the
debug setup instruction at the start of the function and latch on the
first user instruction. Is there a straightforward way to do that?
Right now I'm tempted to recognize calls to llvm.dbg.declare(), but I
don't know if that leaves other cases unhandled.

Thanks. Diego.

I just found something that might be what I was looking for:

    if (Loc.getLine() != 0 && !isa<DbgInfoIntrinsic>(Inst))

Will this do?

Thanks. Diego.

Actually, I lied. It turns out that it DOES matter. I need the source
location of the function header itself. So:

1 void
2
3 foo(
4 int x
5
6 )
7
8 {
9 ...

I need '3' to be my base for all the relative offsets I get from the
profiler. So, how do I find out the line number of the symbol 'foo'
itself?

Thanks. Diego.

Hi Diego,

In the metadata. Look for DW_TAG_subprogram:

define i32 @main() #0 {
...
}

...
!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"main",
metadata !"main", metadata !"", i32 6, metadata !6, i1 false, i1 true, i32
0, i32 0, null, i32 256, i1 false, i32 ()* @main, null, null, metadata !2,
i32 6} ; [ DW_TAG_subprogram ] [line 6] [def] [main]

cheers,
--renato

Excellent. Thanks!

Diego.