This is an archive of the discontinued LLVM Phabricator instance.

[DebugInfo] Handle memory locations in LiveDebugValues
Needs ReviewPublic

Authored by rnk on Aug 23 2017, 1:59 PM.

Details

Summary

Track the DIExpression that contains the offset and use it when
comparing variable locations.

Event Timeline

rnk created this revision.Aug 23 2017, 1:59 PM
aprantl edited edge metadata.Aug 23 2017, 2:11 PM

First off: Thanks!
Does this have have any performance impact? If have the time, it would be nice to just compare the wall clock time of building an asanified (that should generate lots of memory locations) llc or clang with and without the patch.

llvm/lib/CodeGen/LiveDebugValues.cpp
124

I wouldn't call it offset if it's the entire expression

aprantl added inline comments.Aug 23 2017, 2:13 PM
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
5173

I think this should be a separate commit?

rnk added inline comments.Aug 24 2017, 10:12 AM
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
5173

Ugh, this doesn't actually do the right thing. Here's my test that comes here:

void useptr(int *);
void use_alloca(int cond) {
  int x = 0;
  int *px = &x;
  if (cond)
    useptr(px);
}

After optimization, px will be described by a dbg.value of x's alloca. This code in InstrEmitter.cpp incorrectly builds an "indirect in memory" DBG_VALUE for px:

if (SD->getKind() == SDDbgValue::FRAMEIX) {
  // Stack address; this needs to be lowered in target-dependent fashion.
  // EmitTargetCodeForFrameDebugValue is responsible for allocation.
  return BuildMI(*MF, DL, TII->get(TargetOpcode::DBG_VALUE))
      .addFrameIndex(SD->getFrameIx())
      .addImm(0)
      .addMetadata(Var)
      .addMetadata(Expr);
}

I guess I'll need to fix that to look for DW_OP_deref.

rnk added inline comments.Aug 24 2017, 10:14 AM
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
5173

Alternatively, you could say I misunderstood DAG.getFrameIndexDbgValue.

zturner edited edge metadata.Aug 24 2017, 10:16 AM

Can you explain this in terms of an actual debugger scenario that this improves? If we were debugging the code in your test case:

int join_memlocs(int cond) {
  int x = getint();
  if (cond) {
    x = 42;     // Dead store, can delete
    dostuff(x); // Can propagate 42
    x = getint();
  }
  escape(&x); // Escape variable to force it in memory
  return x;
}

What would be the debugger's behavior before the patch and after the patch? And did you check (e.g. with MSVC) that there's actually a discernible result in the debugger experience?

aprantl added inline comments.Aug 24 2017, 10:23 AM
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
5173

I think it would be best to split the SelectionDAG change out into a separate review and have a MIR-only test for LiveDebugValues. The LiveDebugValues change should be generally good and uncontroversial (apart from performance considerations) and this change looks like it will generate a longer discussion.

rnk added a comment.Aug 24 2017, 10:26 AM

Can you explain this in terms of an actual debugger scenario that this improves?

No, but this is a necessary pre-requisite to http://llvm.org/pr34136, starting from the bottom up. Clang doesn't generate the dbg.values used in these test cases yet because LLVM doesn't handle them, but it will soon.

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
5173

Agreed.