diff options
| -rw-r--r-- | llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp | 41 | ||||
| -rw-r--r-- | llvm/test/Transforms/Mem2Reg/ConvertDebugInfo.ll | 31 | 
2 files changed, 69 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp index 9fdcfe5ec3d..d9261ac5a1d 100644 --- a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp +++ b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp @@ -23,6 +23,7 @@  #include "llvm/Function.h"  #include "llvm/Instructions.h"  #include "llvm/IntrinsicInst.h" +#include "llvm/Analysis/DebugInfo.h"  #include "llvm/Analysis/Dominators.h"  #include "llvm/Analysis/AliasSetTracker.h"  #include "llvm/ADT/DenseMap.h" @@ -163,6 +164,7 @@ namespace {      std::vector<AllocaInst*> Allocas;      DominatorTree &DT;      DominanceFrontier &DF; +    DIFactory *DIF;      /// AST - An AliasSetTracker object to update.  If null, don't update it.      /// @@ -199,7 +201,7 @@ namespace {    public:      PromoteMem2Reg(const std::vector<AllocaInst*> &A, DominatorTree &dt,                     DominanceFrontier &df, AliasSetTracker *ast) -      : Allocas(A), DT(dt), DF(df), AST(ast) {} +      : Allocas(A), DT(dt), DF(df), DIF(0), AST(ast) {}      void run(); @@ -241,8 +243,9 @@ namespace {                                    LargeBlockInfo &LBI);      void PromoteSingleBlockAlloca(AllocaInst *AI, AllocaInfo &Info,                                    LargeBlockInfo &LBI); - -     +    void ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, StoreInst* SI, +                                         uint64_t Offset); +                                        void RenamePass(BasicBlock *BB, BasicBlock *Pred,                      RenamePassData::ValVector &IncVals,                      std::vector<RenamePassData> &Worklist); @@ -306,6 +309,19 @@ namespace {  }  // end of anonymous namespace +/// Finds the llvm.dbg.declare intrinsic corresponding to an alloca if any. +static DbgDeclareInst *findDbgDeclare(AllocaInst *AI) { +  Function *F = AI->getParent()->getParent(); +  for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI) +    for (BasicBlock::iterator BI = (*FI).begin(), BE = (*FI).end(); +         BI != BE; ++BI) +      if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI)) +        if (DDI->getAddress() == AI) +          return DDI; + +  return 0; +} +  void PromoteMem2Reg::run() {    Function &F = *DF.getRoot()->getParent(); @@ -344,6 +360,8 @@ void PromoteMem2Reg::run() {        // Finally, after the scan, check to see if the store is all that is left.        if (Info.UsingBlocks.empty()) { +        // Record debuginfo for the store before removing it. +        ConvertDebugDeclareToDebugValue(findDbgDeclare(AI), Info.OnlyStore, 0);          // Remove the (now dead) store and alloca.          Info.OnlyStore->eraseFromParent();          LBI.deleteValue(Info.OnlyStore); @@ -370,8 +388,11 @@ void PromoteMem2Reg::run() {        if (Info.UsingBlocks.empty()) {          // Remove the (now dead) stores and alloca. +        DbgDeclareInst *DDI = findDbgDeclare(AI);          while (!AI->use_empty()) {            StoreInst *SI = cast<StoreInst>(AI->use_back()); +          // Record debuginfo for the store before removing it. +          ConvertDebugDeclareToDebugValue(DDI, SI, 0);            SI->eraseFromParent();            LBI.deleteValue(SI);          } @@ -833,6 +854,18 @@ void PromoteMem2Reg::PromoteSingleBlockAlloca(AllocaInst *AI, AllocaInfo &Info,    }  } +// Inserts a llvm.dbg.value instrinsic before the stores to an alloca'd value +// that has an associated llvm.dbg.decl intrinsic. +void PromoteMem2Reg::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, +                                                     StoreInst* SI, +                                                     uint64_t Offset) { +  if (!DDI) return; + +  if (!DIF) +    DIF = new DIFactory(*SI->getParent()->getParent()->getParent()); +  DIF->InsertDbgValueIntrinsic(SI->getOperand(0), Offset, +                               DIVariable(DDI->getVariable()), SI); +}  // QueuePhiNode - queues a phi-node to be added to a basic-block for a specific  // Alloca returns true if there wasn't already a phi-node for that variable @@ -946,6 +979,8 @@ NextIteration:        // what value were we writing?        IncomingVals[ai->second] = SI->getOperand(0); +      // Record debuginfo for the store before removing it. +      ConvertDebugDeclareToDebugValue(findDbgDeclare(Dest), SI, 0);        BB->getInstList().erase(SI);      }    } diff --git a/llvm/test/Transforms/Mem2Reg/ConvertDebugInfo.ll b/llvm/test/Transforms/Mem2Reg/ConvertDebugInfo.ll new file mode 100644 index 00000000000..8e309c0901e --- /dev/null +++ b/llvm/test/Transforms/Mem2Reg/ConvertDebugInfo.ll @@ -0,0 +1,31 @@ +; RUN: opt < %s -mem2reg -S | FileCheck %s + +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" + +define double @testfunc(i32 %i, double %j) { +	%I = alloca i32		; <i32*> [#uses=4] +  call void @llvm.dbg.declare(metadata !{i32* %I}, metadata !0) +	%J = alloca double		; <double*> [#uses=2] +  call void @llvm.dbg.declare(metadata !{double* %J}, metadata !1) +; CHECK: call void @llvm.dbg.value(metadata !{i32 %i}, i64 0, metadata !0) +	store i32 %i, i32* %I +; CHECK: call void @llvm.dbg.value(metadata !{double %j}, i64 0, metadata !1) +	store double %j, double* %J +	%t1 = load i32* %I		; <i32> [#uses=1] +	%t2 = add i32 %t1, 1		; <i32> [#uses=1] +	store i32 %t2, i32* %I +	%t3 = load i32* %I		; <i32> [#uses=1] +	%t4 = sitofp i32 %t3 to double		; <double> [#uses=1] +	%t5 = load double* %J		; <double> [#uses=1] +	%t6 = fmul double %t4, %t5		; <double> [#uses=1] +	ret double %t6 +} + +declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone + +!bar = !{!0} +!foo = !{!2} + +!0 = metadata !{i32 459008, metadata !1, metadata !"foo", metadata !2, i32 5, metadata !"foo"} ; [ DW_TAG_auto_variable ] +!1 = metadata !{i32 459008, metadata !1, metadata !"foo", metadata !0, i32 5, metadata !1} ; [ DW_TAG_auto_variable ] +!2 = metadata !{i32 458804, i32 0, metadata !2, metadata !"foo", metadata !"bar", metadata !"bar", metadata !2, i32 3, metadata !0, i1 false, i1 true} ; [ DW_TAG_variable ]  | 

