diff options
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstructionCombining.cpp')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 31 | 
1 files changed, 30 insertions, 1 deletions
| diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 1881f78255b..8f2b44036f6 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -52,6 +52,7 @@  #include "llvm/Analysis/TargetLibraryInfo.h"  #include "llvm/Analysis/ValueTracking.h"  #include "llvm/IR/CFG.h" +#include "llvm/IR/DIBuilder.h"  #include "llvm/IR/DataLayout.h"  #include "llvm/IR/Dominators.h"  #include "llvm/IR/GetElementPtrTypeIterator.h" @@ -91,6 +92,16 @@ static cl::opt<unsigned>  MaxArraySize("instcombine-maxarray-size", cl::init(1024),               cl::desc("Maximum array size considered when doing a combine")); +// FIXME: Remove this flag when it is no longer necessary to convert +// llvm.dbg.declare to avoid inaccurate debug info. Setting this to false +// increases variable availability at the cost of accuracy. Variables that +// cannot be promoted by mem2reg or SROA will be described as living in memory +// for their entire lifetime. However, passes like DSE and instcombine can +// delete stores to the alloca, leading to misleading and inaccurate debug +// information. This flag can be removed when those passes are fixed. +static cl::opt<unsigned> ShouldLowerDbgDeclare("instcombine-lower-dbg-declare", +                                               cl::Hidden, cl::init(true)); +  Value *InstCombiner::EmitGEPOffset(User *GEP) {    return llvm::EmitGEPOffset(&Builder, DL, GEP);  } @@ -2092,6 +2103,16 @@ Instruction *InstCombiner::visitAllocSite(Instruction &MI) {    // to null and free calls, delete the calls and replace the comparisons with    // true or false as appropriate.    SmallVector<WeakTrackingVH, 64> Users; + +  // If we are removing an alloca with a dbg.declare, insert dbg.value calls +  // before each store. +  DbgDeclareInst *DDI = nullptr; +  std::unique_ptr<DIBuilder> DIB; +  if (isa<AllocaInst>(MI)) { +    DDI = FindAllocaDbgDeclare(&MI); +    DIB.reset(new DIBuilder(*MI.getModule(), /*AllowUnresolved=*/false)); +  } +    if (isAllocSiteRemovable(&MI, Users, &TLI)) {      for (unsigned i = 0, e = Users.size(); i != e; ++i) {        // Lowering all @llvm.objectsize calls first because they may @@ -2124,6 +2145,8 @@ Instruction *InstCombiner::visitAllocSite(Instruction &MI) {        } else if (isa<BitCastInst>(I) || isa<GetElementPtrInst>(I) ||                   isa<AddrSpaceCastInst>(I)) {          replaceInstUsesWith(*I, UndefValue::get(I->getType())); +      } else if (DDI && isa<StoreInst>(I)) { +        ConvertDebugDeclareToDebugValue(DDI, cast<StoreInst>(I), *DIB);        }        eraseInstFromFunction(*I);      } @@ -2135,6 +2158,10 @@ Instruction *InstCombiner::visitAllocSite(Instruction &MI) {        InvokeInst::Create(F, II->getNormalDest(), II->getUnwindDest(),                           None, "", II->getParent());      } + +    if (DDI) +      eraseInstFromFunction(*DDI); +      return eraseInstFromFunction(MI);    }    return nullptr; @@ -3188,7 +3215,9 @@ static bool combineInstructionsOverFunction(    // Lower dbg.declare intrinsics otherwise their value may be clobbered    // by instcombiner. -  bool MadeIRChange = LowerDbgDeclare(F); +  bool MadeIRChange = false; +  if (ShouldLowerDbgDeclare) +    MadeIRChange = LowerDbgDeclare(F);    // Iterate while there is work to do.    int Iteration = 0; | 

