Debug info: Infrastructure to support debug locations for fragmented

variables (for example, by-value struct arguments passed in registers, or
large integer values split across several smaller registers).
On the IR level, this adds a new type of complex address operation OpPiece
to DIVariable that describes size and offset of a variable fragment.
On the DWARF emitter level, all pieces describing the same variable are
collected, sorted and emitted as DWARF expressions using the DW_OP_piece
and DW_OP_bit_piece operators.

http://reviews.llvm.org/D3373
rdar://problem/15928306

What this patch doesn't do / Future work:
- This patch only adds the backend machinery to make this work, patches
  that change SROA and SelectionDAG's type legalizer to actually create
  such debug info will follow. (http://reviews.llvm.org/D2680)
- Making the DIVariable complex expressions into an argument of dbg.value
  will reduce the memory footprint of the debug metadata.
- The sorting/uniquing of pieces should be moved into DebugLocEntry,
  to facilitate the merging of multi-piece entries.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214576 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Adrian Prantl
2014-08-01 22:11:58 +00:00
parent 04395213ab
commit 2a39c993eb
18 changed files with 682 additions and 74 deletions

View File

@ -1100,6 +1100,28 @@ DIVariable DIBuilder::createComplexVariable(unsigned Tag, DIDescriptor Scope,
return DIVariable(MDNode::get(VMContext, Elts));
}
/// createVariablePiece - Create a descriptor to describe one part
/// of aggregate variable that is fragmented across multiple Values.
DIVariable DIBuilder::createVariablePiece(DIVariable Variable,
unsigned OffsetInBytes,
unsigned SizeInBytes) {
assert(SizeInBytes > 0 && "zero-size piece");
Value *Addr[] = {
ConstantInt::get(Type::getInt32Ty(VMContext), OpPiece),
ConstantInt::get(Type::getInt32Ty(VMContext), OffsetInBytes),
ConstantInt::get(Type::getInt32Ty(VMContext), SizeInBytes)
};
assert((Variable->getNumOperands() == 8 || Variable.isVariablePiece()) &&
"variable already has a complex address");
SmallVector<Value *, 9> Elts;
for (unsigned i = 0; i < 8; ++i)
Elts.push_back(Variable->getOperand(i));
Elts.push_back(MDNode::get(VMContext, Addr));
return DIVariable(MDNode::get(VMContext, Elts));
}
/// createFunction - Create a new descriptor for the specified function.
/// FIXME: this is added for dragonegg. Once we update dragonegg
/// to call resolve function, this will be removed.