[llvm-dev] Proposal for multi location debug info support in LLVM IR

Adrian Prantl via llvm-dev llvm-dev at lists.llvm.org
Tue Jan 5 09:59:03 PST 2016


Thanks for the clarification, Paul!
Keno, just a few more questions for my understanding:

>     - Indicating that a value changed at source level (e.g. because an
>       assignment occurred)

This is done by a key call.

>     - Indicating that the same value is now available in a new location

Additional, alternative locations with identical contents are added by passing in the token from a key call.

>     - Indicating that a value is no longer available in some location


This is done by another key call (possibly with an %undef location).

> > >
> > >     - To add a location with the same value for the same variable, you
> > pass the
> > >       token of the FIRST llvm.dbg.value, as this llvm.dbg.value's first
> > argument
> > >       E.g. to add another location for the variable above:
> > >
> > >         %second =3D call token @llvm.dbg.value(token %first, metadata
> > %val2,
> > >                                             metadata !var, metadata
> > !expr2)
> >
> > Does this invalidate the first location, or does this add an additional
> > location
> > to the set of locations for var at this point? If I want to add a third
> > location,
> > which token do I pass in? Can you explain a bit more what information the
> > token
> > allows us to express that is currently not possible?
> >
> 
> It adds a second location. If you want to add a third location you pass in
> the first token again.
> Thus the first call (key call) indicates a change of values, and all
> locations that have the same value should use the key call's token.
> 

Ok. Looks like this is going to be somewhat verbose for partial updates of SROA’ed aggregates as in the following example:

// struct s { int i, j };
// void foo(struct s) { s.j = 0; ... }

define void @foo(i32 %i, i32 %j) {
  %token = call llvm.dbg.value(token %undef, %i, !Struct, !DIExpression(DW_OP_bit_piece(0, 32)))
           call llvm.dbg.value(token %token, %j, !Struct, !DIExpression(DW_OP_bit_piece(32, 32)))
  ...
  
  ; have to repeat %i here:
  %tok2 = call llvm.dbg.value(token %undef, %i, !Struct, !DIExpression(DW_OP_bit_piece(0, 32)))
          call llvm.dbg.value(token %tok2, metadata i32 0, !Struct, !DIExpression(DW_OP_bit_piece(32, 32)))

On the upside, having all this information explicit could simplify the code in DwarfDebug::buildLocationList().

Is there any information in the tokens that could not be recovered by a static analysis of the debug intrinsics?
Note that having redundant information available explicitly is not necessarily a bad thing.

The one difference I noticed so far is that alternative locations allow earlier locations to outlive locations that are dominated by them:
  %loc = dbg.value(%undef, var, ...)
  ...
  %alt = dbg.value(%loc, var, ...)
  ...
  ; alt becomes unavailable
  ...
  ; %loc is still available here.

Any other advantages that I missed?

-- adrian


More information about the llvm-dev mailing list