summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/SROA.cpp
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2014-12-22 22:26:00 +0000
committerAdrian Prantl <aprantl@apple.com>2014-12-22 22:26:00 +0000
commita47ace59019721411307ab06eea5b7796cb3dd3e (patch)
treedc6af538507f68993a92ef695329c47f0dbca13a /llvm/lib/Transforms/Scalar/SROA.cpp
parent5aabc06c16391fda6424f99fd9a0dad74b1187b4 (diff)
downloadbcm5719-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.cpp31
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
OpenPOWER on IntegriCloud