summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2015-01-07 20:52:22 +0000
committerAdrian Prantl <aprantl@apple.com>2015-01-07 20:52:22 +0000
commit72b8ee708f2bcf14fbbd656efeb3751d37b9df19 (patch)
treef5ad80b772f3ce3d8eeb4d3692c29049e69ff017 /llvm/lib
parent3dd48c6fde7815533c731fb877dc0cf91243fa8b (diff)
downloadbcm5719-llvm-72b8ee708f2bcf14fbbd656efeb3751d37b9df19.tar.gz
bcm5719-llvm-72b8ee708f2bcf14fbbd656efeb3751d37b9df19.zip
Reapply: Teach SROA how to update debug info for fragmented variables.
The two buildbot failures were addressed in LLVM r225378 and CFE r225359. This rapplies commit 225272 without modifications. llvm-svn: 225379
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/Scalar/SROA.cpp68
1 files changed, 60 insertions, 8 deletions
diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp
index ed161fd4af3..d0c6bd05635 100644
--- a/llvm/lib/Transforms/Scalar/SROA.cpp
+++ b/llvm/lib/Transforms/Scalar/SROA.cpp
@@ -1240,6 +1240,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),
@@ -1257,8 +1261,8 @@ private:
friend class AllocaSliceRewriter;
bool presplitLoadsAndStores(AllocaInst &AI, AllocaSlices &AS);
- bool rewritePartition(AllocaInst &AI, AllocaSlices &AS,
- AllocaSlices::Partition &P);
+ AllocaInst *rewritePartition(AllocaInst &AI, AllocaSlices &AS,
+ AllocaSlices::Partition &P);
bool splitAlloca(AllocaInst &AI, AllocaSlices &AS);
bool runOnAlloca(AllocaInst &AI);
void clobberUse(Use &U);
@@ -3964,8 +3968,8 @@ bool SROA::presplitLoadsAndStores(AllocaInst &AI, AllocaSlices &AS) {
/// appropriate new offsets. It also evaluates how successful the rewrite was
/// at enabling promotion and if it was successful queues the alloca to be
/// promoted.
-bool SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS,
- AllocaSlices::Partition &P) {
+AllocaInst *SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS,
+ AllocaSlices::Partition &P) {
// Try to compute a friendly type for this partition of the alloca. This
// won't always succeed, in which case we fall back to a legal integer type
// or an i8 array of an appropriate size.
@@ -4003,6 +4007,7 @@ bool SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS,
NewAI = &AI;
// FIXME: We should be able to bail at this point with "nothing changed".
// FIXME: We might want to defer PHI speculation until after here.
+ // FIXME: return nullptr;
} else {
unsigned Alignment = AI.getAlignment();
if (!Alignment) {
@@ -4098,7 +4103,7 @@ bool SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS,
PostPromotionWorklist.pop_back();
}
- return true;
+ return NewAI;
}
/// \brief Walks the slices of an alloca and form partitions based on them,
@@ -4137,9 +4142,24 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
if (!IsSorted)
std::sort(AS.begin(), AS.end());
+ /// \brief Describes the allocas introduced by rewritePartition
+ /// in order to migrate the debug info.
+ struct Piece {
+ AllocaInst *Alloca;
+ uint64_t Offset;
+ uint64_t Size;
+ Piece(AllocaInst *AI, uint64_t O, uint64_t S)
+ : Alloca(AI), Offset(O), Size(S) {}
+ };
+ SmallVector<Piece, 4> Pieces;
+
// Rewrite each partition.
for (auto &P : AS.partitions()) {
- Changed |= rewritePartition(AI, AS, P);
+ if (AllocaInst *NewAI = rewritePartition(AI, AS, P)) {
+ Changed = true;
+ if (NewAI != &AI)
+ Pieces.push_back(Piece(NewAI, P.beginOffset(), P.size()));
+ }
++NumPartitions;
}
@@ -4147,6 +4167,28 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
MaxPartitionsPerAlloca =
std::max<unsigned>(NumPartitions, MaxPartitionsPerAlloca);
+ // Migrate debug information from the old alloca to the new alloca(s)
+ // and the individial partitions.
+ if (DbgDeclareInst *DbgDecl = DbgDeclares.lookup(&AI)) {
+ DIVariable Var(DbgDecl->getVariable());
+ DIExpression Expr(DbgDecl->getExpression());
+ DIBuilder DIB(*AI.getParent()->getParent()->getParent(),
+ /*AllowUnresolved*/ false);
+ bool IsSplit = Pieces.size() > 1;
+ for (auto Piece : Pieces) {
+ // Create a piece expression describing the new partition or reuse AI's
+ // expression if there is only one partition.
+ if (IsSplit)
+ Expr = DIB.createPieceExpression(Piece.Offset, Piece.Size);
+ Instruction *NewDDI = DIB.insertDeclare(Piece.Alloca, Var, Expr, &AI);
+ NewDDI->setDebugLoc(DbgDecl->getDebugLoc());
+ assert((!DbgDeclares.count(Piece.Alloca) ||
+ DbgDeclares[Piece.Alloca] == cast<DbgDeclareInst>(NewDDI)
+ ) && "alloca already described");
+ DbgDeclares.insert(std::make_pair(Piece.Alloca,
+ cast<DbgDeclareInst>(NewDDI)));
+ }
+ }
return Changed;
}
@@ -4258,8 +4300,13 @@ void SROA::deleteDeadInstructions(
DeadInsts.insert(U);
}
- if (AllocaInst *AI = dyn_cast<AllocaInst>(I))
+ if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) {
DeletedAllocas.insert(AI);
+ if (DbgDeclareInst *DbgDecl = DbgDeclares.lookup(AI)) {
+ DbgDecl->eraseFromParent();
+ DbgDeclares.erase(AI);
+ }
+ }
++NumDeleted;
I->eraseFromParent();
@@ -4374,11 +4421,16 @@ bool SROA::runOnFunction(Function &F) {
DT = DTWP ? &DTWP->getDomTree() : nullptr;
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
+ DbgDeclares.clear();
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