aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
authorCameron Zwarich <zwarich@apple.com>2011-05-24 03:10:43 +0000
committerCameron Zwarich <zwarich@apple.com>2011-05-24 03:10:43 +0000
commitc827939046670a9800659b83e2048f1d3a79a531 (patch)
tree6e93cbf3cf2b669154f8e12e884fa01c6e3a2afe /lib/Transforms
parente6657980977ed63df8bbd2604c9fefe513ac4126 (diff)
Make LoadAndStorePromoter preserve debug info and create llvm.dbg.values when
promoting allocas to SSA variables. Fixes <rdar://problem/9479036>. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131953 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Scalar/LICM.cpp5
-rw-r--r--lib/Transforms/Scalar/ScalarReplAggregates.cpp17
-rw-r--r--lib/Transforms/Utils/Local.cpp13
-rw-r--r--lib/Transforms/Utils/PromoteMemoryToRegister.cpp12
-rw-r--r--lib/Transforms/Utils/SSAUpdater.cpp32
5 files changed, 53 insertions, 26 deletions
diff --git a/lib/Transforms/Scalar/LICM.cpp b/lib/Transforms/Scalar/LICM.cpp
index 93de9cf002..f706cc2a55 100644
--- a/lib/Transforms/Scalar/LICM.cpp
+++ b/lib/Transforms/Scalar/LICM.cpp
@@ -602,13 +602,14 @@ namespace {
SmallPtrSet<Value*, 4> &PointerMustAliases;
SmallVectorImpl<BasicBlock*> &LoopExitBlocks;
AliasSetTracker &AST;
+ DIBuilder *DIB; // Only passed to LoadAndStorePromoter.
public:
LoopPromoter(Value *SP,
const SmallVectorImpl<Instruction*> &Insts, SSAUpdater &S,
SmallPtrSet<Value*, 4> &PMA,
SmallVectorImpl<BasicBlock*> &LEB, AliasSetTracker &ast)
- : LoadAndStorePromoter(Insts, S), SomePtr(SP), PointerMustAliases(PMA),
- LoopExitBlocks(LEB), AST(ast) {}
+ : LoadAndStorePromoter(Insts, S, 0, DIB), SomePtr(SP),
+ PointerMustAliases(PMA), LoopExitBlocks(LEB), AST(ast) {}
virtual bool isInstInList(Instruction *I,
const SmallVectorImpl<Instruction*> &) const {
diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
index 5f8ab517df..ebcb88c015 100644
--- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp
+++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
@@ -30,6 +30,7 @@
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
+#include "llvm/Analysis/DIBuilder.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/ValueTracking.h"
@@ -1051,8 +1052,9 @@ namespace {
class AllocaPromoter : public LoadAndStorePromoter {
AllocaInst *AI;
public:
- AllocaPromoter(const SmallVectorImpl<Instruction*> &Insts, SSAUpdater &S)
- : LoadAndStorePromoter(Insts, S), AI(0) {}
+ AllocaPromoter(const SmallVectorImpl<Instruction*> &Insts, SSAUpdater &S,
+ DbgDeclareInst *DD, DIBuilder *&DB)
+ : LoadAndStorePromoter(Insts, S, DD, DB), AI(0) {}
void run(AllocaInst *AI, const SmallVectorImpl<Instruction*> &Insts) {
// Remember which alloca we're promoting (for isInstInList).
@@ -1329,7 +1331,6 @@ static bool tryToMakeAllocaBePromotable(AllocaInst *AI, const TargetData *TD) {
return true;
}
-
bool SROA::performPromotion(Function &F) {
std::vector<AllocaInst*> Allocas;
DominatorTree *DT = 0;
@@ -1340,6 +1341,7 @@ bool SROA::performPromotion(Function &F) {
bool Changed = false;
SmallVector<Instruction*, 64> Insts;
+ DIBuilder *DIB = 0;
while (1) {
Allocas.clear();
@@ -1363,8 +1365,9 @@ bool SROA::performPromotion(Function &F) {
for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end();
UI != E; ++UI)
Insts.push_back(cast<Instruction>(*UI));
-
- AllocaPromoter(Insts, SSA).run(AI, Insts);
+
+ DbgDeclareInst *DDI = FindAllocaDbgDeclare(AI);
+ AllocaPromoter(Insts, SSA, DDI, DIB).run(AI, Insts);
Insts.clear();
}
}
@@ -1372,6 +1375,10 @@ bool SROA::performPromotion(Function &F) {
Changed = true;
}
+ // FIXME: Is there a better way to handle the lazy initialization of DIB
+ // so that there doesn't need to be an explicit delete?
+ delete DIB;
+
return Changed;
}
diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp
index f5a8adacd5..3bdbaa5c09 100644
--- a/lib/Transforms/Utils/Local.cpp
+++ b/lib/Transforms/Utils/Local.cpp
@@ -20,6 +20,7 @@
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/IntrinsicInst.h"
+#include "llvm/Metadata.h"
#include "llvm/Operator.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -877,3 +878,15 @@ bool llvm::LowerDbgDeclare(Function &F) {
}
return true;
}
+
+/// FindAllocaDbgDeclare - Finds the llvm.dbg.declare intrinsic describing the
+/// alloca 'V', if any.
+DbgDeclareInst *llvm::FindAllocaDbgDeclare(Value *V) {
+ if (MDNode *DebugNode = MDNode::getIfExists(V->getContext(), V))
+ for (Value::use_iterator UI = DebugNode->use_begin(),
+ E = DebugNode->use_end(); UI != E; ++UI)
+ if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(*UI))
+ return DDI;
+
+ return 0;
+}
diff --git a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
index 50c9ae204a..a1736b931f 100644
--- a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
+++ b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
@@ -100,18 +100,6 @@ bool llvm::isAllocaPromotable(const AllocaInst *AI) {
return true;
}
-/// FindAllocaDbgDeclare - Finds the llvm.dbg.declare intrinsic describing the
-/// alloca 'V', if any.
-static DbgDeclareInst *FindAllocaDbgDeclare(Value *V) {
- if (MDNode *DebugNode = MDNode::getIfExists(V->getContext(), V))
- for (Value::use_iterator UI = DebugNode->use_begin(),
- E = DebugNode->use_end(); UI != E; ++UI)
- if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(*UI))
- return DDI;
-
- return 0;
-}
-
namespace {
struct AllocaInfo;
diff --git a/lib/Transforms/Utils/SSAUpdater.cpp b/lib/Transforms/Utils/SSAUpdater.cpp
index 2860c3e511..09f0a50cb0 100644
--- a/lib/Transforms/Utils/SSAUpdater.cpp
+++ b/lib/Transforms/Utils/SSAUpdater.cpp
@@ -14,7 +14,9 @@
#define DEBUG_TYPE "ssaupdater"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/Analysis/DIBuilder.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Allocator.h"
@@ -22,6 +24,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/SSAUpdater.h"
#include "llvm/Transforms/Utils/SSAUpdaterImpl.h"
@@ -355,7 +358,8 @@ Value *SSAUpdater::GetValueAtEndOfBlockInternal(BasicBlock *BB) {
LoadAndStorePromoter::
LoadAndStorePromoter(const SmallVectorImpl<Instruction*> &Insts,
- SSAUpdater &S, StringRef BaseName) : SSA(S) {
+ SSAUpdater &S, DbgDeclareInst *DD, DIBuilder *&DB,
+ StringRef BaseName) : SSA(S), DDI(DD), DIB(DB) {
if (Insts.empty()) return;
Value *SomeVal;
@@ -402,9 +406,14 @@ run(const SmallVectorImpl<Instruction*> &Insts) const {
// single user in it, we can rewrite it trivially.
if (BlockUses.size() == 1) {
// If it is a store, it is a trivial def of the value in the block.
- if (StoreInst *SI = dyn_cast<StoreInst>(User))
+ if (StoreInst *SI = dyn_cast<StoreInst>(User)) {
+ if (DDI) {
+ if (!DIB)
+ DIB = new DIBuilder(*SI->getParent()->getParent()->getParent());
+ ConvertDebugDeclareToDebugValue(DDI, SI, *DIB);
+ }
SSA.AddAvailableValue(BB, SI->getOperand(0));
- else
+ } else
// Otherwise it is a load, queue it to rewrite as a live-in load.
LiveInLoads.push_back(cast<LoadInst>(User));
BlockUses.clear();
@@ -453,12 +462,18 @@ run(const SmallVectorImpl<Instruction*> &Insts) const {
continue;
}
- if (StoreInst *S = dyn_cast<StoreInst>(II)) {
+ if (StoreInst *SI = dyn_cast<StoreInst>(II)) {
// If this is a store to an unrelated pointer, ignore it.
- if (!isInstInList(S, Insts)) continue;
-
+ if (!isInstInList(SI, Insts)) continue;
+
+ if (DDI) {
+ if (!DIB)
+ DIB = new DIBuilder(*SI->getParent()->getParent()->getParent());
+ ConvertDebugDeclareToDebugValue(DDI, SI, *DIB);
+ }
+
// Remember that this is the active value in the block.
- StoredValue = S->getOperand(0);
+ StoredValue = SI->getOperand(0);
}
}
@@ -513,4 +528,7 @@ run(const SmallVectorImpl<Instruction*> &Insts) const {
instructionDeleted(User);
User->eraseFromParent();
}
+
+ if (DDI)
+ DDI->eraseFromParent();
}