diff options
author | Adrian Prantl <aprantl@apple.com> | 2014-12-22 22:26:00 +0000 |
---|---|---|
committer | Adrian Prantl <aprantl@apple.com> | 2014-12-22 22:26:00 +0000 |
commit | a47ace59019721411307ab06eea5b7796cb3dd3e (patch) | |
tree | dc6af538507f68993a92ef695329c47f0dbca13a /llvm/lib/Transforms/Scalar/SROA.cpp | |
parent | 5aabc06c16391fda6424f99fd9a0dad74b1187b4 (diff) | |
download | bcm5719-llvm-a47ace59019721411307ab06eea5b7796cb3dd3e.tar.gz bcm5719-llvm-a47ace59019721411307ab06eea5b7796cb3dd3e.zip |
Debug info: Teach SROA how to update debug info for fragmented variables.
This allows us to generate debug info for extremely advanced code such as
typedef struct { long int a; int b;} S;
int foo(S s) {
return s.b;
}
which at -O1 on x86_64 is codegen'd into
define i32 @foo(i64 %s.coerce0, i32 %s.coerce1) #0 {
ret i32 %s.coerce1, !dbg !24
}
with this patch we emit the following debug info for this
TAG_formal_parameter [3]
AT_location( 0x00000000
0x0000000000000000 - 0x0000000000000006: rdi, piece 0x00000008, rsi, piece 0x00000004
0x0000000000000006 - 0x0000000000000008: rdi, piece 0x00000008, rax, piece 0x00000004 )
AT_name( "s" )
AT_decl_file( "/Volumes/Data/llvm/_build.ninja.release/test.c" )
Thanks to chandlerc, dblaikie, and echristo for their feedback on all
previous iterations of this patch!
llvm-svn: 224739
Diffstat (limited to 'llvm/lib/Transforms/Scalar/SROA.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/SROA.cpp | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp index 91818c8fc15..37772277b58 100644 --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -953,6 +953,10 @@ class SROA : public FunctionPass { /// currently in the promotable queue. SetVector<SelectInst *, SmallVector<SelectInst *, 2>> SpeculatableSelects; + /// Debug intrinsics do not show up as regular uses in the + /// IR. This side-table holds the missing use edges. + DenseMap<AllocaInst *, DbgDeclareInst *> DbgDeclares; + public: SROA(bool RequiresDomTree = true) : FunctionPass(ID), RequiresDomTree(RequiresDomTree), C(nullptr), @@ -3230,6 +3234,27 @@ bool SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS, new AllocaInst(SliceTy, nullptr, Alignment, AI.getName() + ".sroa." + Twine(B - AS.begin()), &AI); ++NumNewAllocas; + + // Migrate debug information from the old alloca to the new alloca + // and the individial slices. + if (DbgDeclareInst *DbgDecl = DbgDeclares.lookup(&AI)) { + DIVariable Var(DbgDecl->getVariable()); + DIExpression Piece; + DIBuilder DIB(*AI.getParent()->getParent()->getParent(), + /*AllowUnresolved*/ false); + // Create a piece expression describing the slice, if the new slize is + // smaller than the old alloca or the old alloca already was described + // with a piece. It would be even better to just compare against the size + // of the type described in the debug info, but then we would need to + // build an expensive DIRefMap. + if (SliceSize < DL->getTypeAllocSize(AI.getAllocatedType()) || + DIExpression(DbgDecl->getExpression()).isVariablePiece()) + Piece = DIB.createPieceExpression(BeginOffset, SliceSize); + Instruction *NewDDI = DIB.insertDeclare(NewAI, Var, Piece, &AI); + NewDDI->setDebugLoc(DbgDecl->getDebugLoc()); + DbgDeclares.insert(std::make_pair(NewAI, cast<DbgDeclareInst>(NewDDI))); + DeadInsts.insert(DbgDecl); + } } DEBUG(dbgs() << "Rewriting alloca partition " @@ -3680,9 +3705,13 @@ bool SROA::runOnFunction(Function &F) { BasicBlock &EntryBB = F.getEntryBlock(); for (BasicBlock::iterator I = EntryBB.begin(), E = std::prev(EntryBB.end()); - I != E; ++I) + I != E; ++I) { if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) Worklist.insert(AI); + else if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I)) + if (auto AI = dyn_cast_or_null<AllocaInst>(DDI->getAddress())) + DbgDeclares.insert(std::make_pair(AI, DDI)); + } bool Changed = false; // A set of deleted alloca instruction pointers which should be removed from |