[llvm-commits] [llvm] r127381 - in /llvm/trunk: include/llvm/DebugInfoProbe.h lib/Analysis/LoopPass.cpp lib/VMCore/DebugInfoProbe.cpp lib/VMCore/PassManager.cpp

Chris Lattner clattner at apple.com
Sat May 21 21:09:49 PDT 2011


On Mar 9, 2011, at 4:21 PM, Devang Patel wrote:

> Author: dpatel
> Date: Wed Mar  9 18:21:25 2011
> New Revision: 127381
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=127381&view=rev
> Log:
> Introduce DebugInfoProbe. This is used to monitor how llvm optimizer is treating debugging information. 
> It generates output that lools like
> 
> 8 times line number info lost by Scalar Replacement of Aggregates (SSAUp) 
> 1 times line number info lost by Simplify well-known library calls 
> 12 times variable info lost by Jump Threading

Hi Devang,

This looks like very interesting functionality, but it is really unfortunate that it has to be so intricately intertwined into the core PassManager.  We don't do this for any other functionality, why should this be different?

-Chris

> 
> 
> Added:
>    llvm/trunk/include/llvm/DebugInfoProbe.h
>    llvm/trunk/lib/VMCore/DebugInfoProbe.cpp
> Modified:
>    llvm/trunk/lib/Analysis/LoopPass.cpp
>    llvm/trunk/lib/VMCore/PassManager.cpp
> 
> Added: llvm/trunk/include/llvm/DebugInfoProbe.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfoProbe.h?rev=127381&view=auto
> ==============================================================================
> --- llvm/trunk/include/llvm/DebugInfoProbe.h (added)
> +++ llvm/trunk/include/llvm/DebugInfoProbe.h Wed Mar  9 18:21:25 2011
> @@ -0,0 +1,67 @@
> +//===-- DebugInfoProbe.h - DebugInfo Probe ----------------------*- C++ -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// This file defines a probe, DebugInfoProbe, that can be used by pass
> +// manager to analyze how optimizer is treating debugging information.
> +// 
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_TRANSFORMS_UTILS_DEBUGINFOPROBE_H
> +#define LLVM_TRANSFORMS_UTILS_DEBUGINFOPROBE_H
> +
> +#include "llvm/ADT/StringMap.h"
> +
> +namespace llvm {
> +  class Function;
> +  class Pass;
> +  class DebugInfoProbeImpl;
> +
> +  /// DebugInfoProbe - This class provides a interface to monitor
> +  /// how an optimization pass is preserving debugging information.
> +  class DebugInfoProbe {
> +    public:
> +    DebugInfoProbe();
> +    ~DebugInfoProbe();
> +
> +    /// initialize - Collect information before running an optimization pass.
> +    void initialize(StringRef PName, Function &F);
> +
> +    /// finalize - Collect information after running an optimization pass. This
> +    /// must be used after initialization.
> +    void finalize(Function &F);
> +
> +    /// report - Report findings. This should be invoked after finalize.
> +    void report();
> +
> +    private:
> +    DebugInfoProbeImpl *pImpl;
> +  };
> +
> +  /// DebugInfoProbeInfo - This class provides an interface that a pass manager
> +  /// can use to manage debug info probes.
> +  class DebugInfoProbeInfo {
> +    StringMap<DebugInfoProbe *> Probes;
> +  public:
> +    DebugInfoProbeInfo() {}
> +
> +    /// ~DebugInfoProbeInfo - Report data collected by all probes before deleting
> +    /// them.
> +    ~DebugInfoProbeInfo();
> +
> +    /// initialize - Collect information before running an optimization pass.
> +    void initialize(Pass *P, Function &F);
> +
> +    /// finalize - Collect information after running an optimization pass. This
> +    /// must be used after initialization.
> +    void finalize(Pass *P, Function &F);
> +  };
> +
> +} // End llvm namespace
> +
> +#endif
> 
> Modified: llvm/trunk/lib/Analysis/LoopPass.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopPass.cpp?rev=127381&r1=127380&r2=127381&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Analysis/LoopPass.cpp (original)
> +++ llvm/trunk/lib/Analysis/LoopPass.cpp Wed Mar  9 18:21:25 2011
> @@ -14,8 +14,10 @@
> //===----------------------------------------------------------------------===//
> 
> #include "llvm/Analysis/LoopPass.h"
> +#include "llvm/DebugInfoProbe.h"
> #include "llvm/Assembly/PrintModulePass.h"
> #include "llvm/Support/Debug.h"
> +#include "llvm/Support/ManagedStatic.h"
> #include "llvm/Support/Timer.h"
> using namespace llvm;
> 
> @@ -52,6 +54,20 @@
> }
> 
> //===----------------------------------------------------------------------===//
> +// DebugInfoProbe
> +
> +static DebugInfoProbeInfo *TheDebugProbe;
> +static void createDebugInfoProbe() {
> +  if (TheDebugProbe) return;
> +      
> +  // Constructed the first time this is called. This guarantees that the 
> +  // object will be constructed, if -enable-debug-info-probe is set, 
> +  // before static globals, thus it will be destroyed before them.
> +  static ManagedStatic<DebugInfoProbeInfo> DIP;
> +  TheDebugProbe = &*DIP;
> +}
> +
> +//===----------------------------------------------------------------------===//
> // LPPassManager
> //
> 
> @@ -223,6 +239,7 @@
> bool LPPassManager::runOnFunction(Function &F) {
>   LI = &getAnalysis<LoopInfo>();
>   bool Changed = false;
> +  createDebugInfoProbe();
> 
>   // Collect inherited analysis from Module level pass manager.
>   populateInheritedAnalysis(TPM->activeStack);
> @@ -254,19 +271,21 @@
>     // Run all passes on the current Loop.
>     for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {  
>       LoopPass *P = getContainedPass(Index);
> -
>       dumpPassInfo(P, EXECUTION_MSG, ON_LOOP_MSG,
>                    CurrentLoop->getHeader()->getName());
>       dumpRequiredSet(P);
> 
>       initializeAnalysisImpl(P);
> -
> +      if (TheDebugProbe)
> +        TheDebugProbe->initialize(P, F);
>       {
>         PassManagerPrettyStackEntry X(P, *CurrentLoop->getHeader());
>         TimeRegion PassTimer(getPassTimer(P));
> 
>         Changed |= P->runOnLoop(CurrentLoop, *this);
>       }
> +      if (TheDebugProbe)
> +        TheDebugProbe->finalize(P, F);
> 
>       if (Changed)
>         dumpPassInfo(P, MODIFICATION_MSG, ON_LOOP_MSG,
> 
> Added: llvm/trunk/lib/VMCore/DebugInfoProbe.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/DebugInfoProbe.cpp?rev=127381&view=auto
> ==============================================================================
> --- llvm/trunk/lib/VMCore/DebugInfoProbe.cpp (added)
> +++ llvm/trunk/lib/VMCore/DebugInfoProbe.cpp Wed Mar  9 18:21:25 2011
> @@ -0,0 +1,237 @@
> +//===-- DebugInfoProbe.cpp - DebugInfo Probe ------------------------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// This file implements DebugInfoProbe. This probe can be used by a pass
> +// manager to analyze how optimizer is treating debugging information.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#define DEBUG_TYPE "debuginfoprobe"
> +#include "llvm/DebugInfoProbe.h"
> +#include "llvm/Function.h"
> +#include "llvm/IntrinsicInst.h"
> +#include "llvm/Metadata.h"
> +#include "llvm/PassManager.h"
> +#include "llvm/Support/CommandLine.h"
> +#include "llvm/Support/Debug.h"
> +#include "llvm/Support/DebugLoc.h"
> +#include "llvm/Support/raw_ostream.h"
> +#include "llvm/ADT/StringRef.h"
> +#include <set>
> +#include <string>
> +
> +using namespace llvm;
> +
> +static cl::opt<bool>
> +EnableDebugInfoProbe("enable-debug-info-probe", cl::Hidden,
> +                     cl::desc("Enable debug info probe"));
> +
> +// CreateInfoOutputFile - Return a file stream to print our output on.
> +namespace llvm { extern raw_ostream *CreateInfoOutputFile(); }
> +
> +//===----------------------------------------------------------------------===//
> +// DebugInfoProbeImpl - This class implements a interface to monitor
> +// how an optimization pass is preserving debugging information.
> +
> +namespace llvm {
> +
> +  class DebugInfoProbeImpl {
> +  public:
> +    DebugInfoProbeImpl() : NumDbgLineLost(0),NumDbgValueLost(0) {}
> +    void initialize(StringRef PName, Function &F);
> +    void finalize(Function &F);
> +    void report();
> +  private:
> +    unsigned NumDbgLineLost, NumDbgValueLost;
> +    std::string PassName;
> +    Function *TheFn;
> +    std::set<unsigned> LineNos;
> +    std::set<MDNode *> DbgVariables;
> +  };
> +}
> +
> +//===----------------------------------------------------------------------===//
> +// DebugInfoProbeImpl
> +
> +static void collect(Function &F, std::set<unsigned> &Lines) {
> +  for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
> +    for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); 
> +         BI != BE; ++BI) {
> +      const DebugLoc &DL = BI->getDebugLoc();
> +      unsigned LineNo = 0;
> +      if (!DL.isUnknown()) {
> +        if (MDNode *N = DL.getInlinedAt(F.getContext()))
> +          LineNo = DebugLoc::getFromDILocation(N).getLine();
> +        else
> +          LineNo = DL.getLine();
> +
> +        Lines.insert(LineNo);
> +      }
> +    }
> +}
> +
> +/// initialize - Collect information before running an optimization pass.
> +void DebugInfoProbeImpl::initialize(StringRef PName, Function &F) {
> +  if (!EnableDebugInfoProbe) return;
> +  PassName = PName;
> +  NumDbgLineLost = 0;
> +  NumDbgValueLost = 0;
> +
> +  LineNos.clear();
> +  DbgVariables.clear();
> +  TheFn = &F;
> +  collect(F, LineNos);
> +
> +  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 (!isa<DbgInfoIntrinsic>(BI)) continue;
> +      Value *Addr = NULL;
> +      MDNode *Node = NULL;
> +      if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI)) {
> +        Addr = DDI->getAddress();
> +        Node = DDI->getVariable();
> +      } else if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(BI)) {
> +        Addr = DVI->getValue();
> +        Node = DVI->getVariable();
> +      }
> +      if (Addr) continue;
> +      DbgVariables.insert(Node);
> +    }
> +}
> +
> +/// report - Report findings. This should be invoked after finalize.
> +void DebugInfoProbeImpl::report() {
> +  if (!EnableDebugInfoProbe) return;
> +  if (NumDbgLineLost || NumDbgValueLost) {
> +    raw_ostream *OutStream = CreateInfoOutputFile();
> +    if (NumDbgLineLost)
> +      *OutStream << NumDbgLineLost
> +                 << "\t times line number info lost by "
> +                 << PassName << "\n";
> +    if (NumDbgValueLost)
> +      *OutStream << NumDbgValueLost
> +                 << "\t times variable info lost by    "
> +                 << PassName << "\n";
> +    delete OutStream;
> +  }
> +}
> +
> +/// finalize - Collect information after running an optimization pass. This
> +/// must be used after initialization.
> +void DebugInfoProbeImpl::finalize(Function &F) {
> +  if (!EnableDebugInfoProbe) return;
> +  std::set<unsigned> LineNos2;
> +  collect(F, LineNos2);
> +  assert (TheFn == &F && "Invalid function to measure!");
> +
> +  for (std::set<unsigned>::iterator I = LineNos.begin(),
> +         E = LineNos.end(); I != E; ++I) {
> +    unsigned LineNo = *I;
> +    if (LineNos2.count(LineNo) == 0) {
> +      DEBUG(dbgs() << "Losing dbg info intrinsic at line " << LineNo << " ");
> +      ++NumDbgLineLost;
> +    }
> +  }
> +
> +  std::set<MDNode *>DbgVariables2;
> +  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 (!isa<DbgInfoIntrinsic>(BI)) continue;
> +      Value *Addr = NULL;
> +      MDNode *Node = NULL;
> +      if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI)) {
> +        Addr = DDI->getAddress();
> +        Node = DDI->getVariable();
> +      } else if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(BI)) {
> +        Addr = DVI->getValue();
> +        Node = DVI->getVariable();
> +      }
> +      if (Addr) continue;
> +      DbgVariables2.insert(Node);
> +    }
> +
> +  for (std::set<MDNode *>::iterator I = DbgVariables.begin(), 
> +         E = DbgVariables.end(); I != E; ++I) {
> +    if (DbgVariables2.count(*I) == 0) {
> +      DEBUG(dbgs() << "Losing dbg info for variable: ");
> +      DEBUG((*I)->print(dbgs()));
> +      ++NumDbgValueLost;
> +    }
> +  }
> +}
> +
> +//===----------------------------------------------------------------------===//
> +// DebugInfoProbe
> +
> +DebugInfoProbe::DebugInfoProbe() {
> +  pImpl = new DebugInfoProbeImpl();
> +}
> +
> +DebugInfoProbe::~DebugInfoProbe() {
> +  delete pImpl;
> +}
> +
> +/// initialize - Collect information before running an optimization pass.
> +void DebugInfoProbe::initialize(StringRef PName, Function &F) {
> +  pImpl->initialize(PName, F);
> +}
> +
> +/// finalize - Collect information after running an optimization pass. This
> +/// must be used after initialization.
> +void DebugInfoProbe::finalize(Function &F) {
> +  pImpl->finalize(F);
> +}
> +
> +/// report - Report findings. This should be invoked after finalize.
> +void DebugInfoProbe::report() {
> +  pImpl->report();
> +}
> +
> +//===----------------------------------------------------------------------===//
> +// DebugInfoProbeInfo
> +
> +/// ~DebugInfoProbeInfo - Report data collected by all probes before deleting
> +/// them.
> +DebugInfoProbeInfo::~DebugInfoProbeInfo() {
> +  if (!EnableDebugInfoProbe) return;
> +    for (StringMap<DebugInfoProbe*>::iterator I = Probes.begin(),
> +           E = Probes.end(); I != E; ++I) {
> +      I->second->report();
> +      delete I->second;
> +    }
> +  }
> +
> +/// initialize - Collect information before running an optimization pass.
> +void DebugInfoProbeInfo::initialize(Pass *P, Function &F) {
> +  if (!EnableDebugInfoProbe) return;
> +  if (P->getAsPMDataManager())
> +    return;
> +
> +  StringMapEntry<DebugInfoProbe *> &Entry =
> +    Probes.GetOrCreateValue(P->getPassName());
> +  DebugInfoProbe *&Probe = Entry.getValue();
> +  if (!Probe)
> +    Probe = new DebugInfoProbe();
> +  Probe->initialize(P->getPassName(), F);
> +}
> +
> +/// finalize - Collect information after running an optimization pass. This
> +/// must be used after initialization.
> +void DebugInfoProbeInfo::finalize(Pass *P, Function &F) {
> +  if (!EnableDebugInfoProbe) return;
> +  if (P->getAsPMDataManager())
> +    return;
> +  StringMapEntry<DebugInfoProbe *> &Entry =
> +    Probes.GetOrCreateValue(P->getPassName());
> +  DebugInfoProbe *&Probe = Entry.getValue();
> +  assert (Probe && "DebugInfoProbe is not initialized!");
> +  Probe->finalize(F);
> +}
> 
> Modified: llvm/trunk/lib/VMCore/PassManager.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/PassManager.cpp?rev=127381&r1=127380&r2=127381&view=diff
> ==============================================================================
> --- llvm/trunk/lib/VMCore/PassManager.cpp (original)
> +++ llvm/trunk/lib/VMCore/PassManager.cpp Wed Mar  9 18:21:25 2011
> @@ -14,6 +14,7 @@
> 
> #include "llvm/PassManagers.h"
> #include "llvm/PassManager.h"
> +#include "llvm/DebugInfoProbe.h"
> #include "llvm/Assembly/PrintModulePass.h"
> #include "llvm/Assembly/Writer.h"
> #include "llvm/Support/CommandLine.h"
> @@ -25,6 +26,7 @@
> #include "llvm/Support/PassNameParser.h"
> #include "llvm/Support/raw_ostream.h"
> #include "llvm/Support/Mutex.h"
> +#include "llvm/ADT/StringMap.h"
> #include <algorithm>
> #include <cstdio>
> #include <map>
> @@ -442,6 +444,20 @@
> namespace {
> 
> //===----------------------------------------------------------------------===//
> +// DebugInfoProbe
> +
> +static DebugInfoProbeInfo *TheDebugProbe;
> +static void createDebugInfoProbe() {
> +  if (TheDebugProbe) return;
> +      
> +  // Constructed the first time this is called. This guarantees that the 
> +  // object will be constructed, if -enable-debug-info-probe is set, 
> +  // before static globals, thus it will be destroyed before them.
> +  static ManagedStatic<DebugInfoProbeInfo> DIP;
> +  TheDebugProbe = &*DIP;
> +}
> +
> +//===----------------------------------------------------------------------===//
> /// TimingInfo Class - This class is used to calculate information about the
> /// amount of time each pass takes to execute.  This only happens when
> /// -time-passes is enabled on the command line.
> @@ -1430,6 +1446,7 @@
> bool FunctionPassManagerImpl::run(Function &F) {
>   bool Changed = false;
>   TimingInfo::createTheTimeInfo();
> +  createDebugInfoProbe();
> 
>   initializeAllAnalysisInfo();
>   for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
> @@ -1477,13 +1494,16 @@
>     dumpRequiredSet(FP);
> 
>     initializeAnalysisImpl(FP);
> -
> +    if (TheDebugProbe)
> +      TheDebugProbe->initialize(FP, F);
>     {
>       PassManagerPrettyStackEntry X(FP, F);
>       TimeRegion PassTimer(getPassTimer(FP));
> 
>       LocalChanged |= FP->runOnFunction(F);
>     }
> +    if (TheDebugProbe)
> +      TheDebugProbe->finalize(FP, F);
> 
>     Changed |= LocalChanged;
>     if (LocalChanged)
> @@ -1631,6 +1651,7 @@
> bool PassManagerImpl::run(Module &M) {
>   bool Changed = false;
>   TimingInfo::createTheTimeInfo();
> +  createDebugInfoProbe();
> 
>   dumpArguments();
>   dumpPasses();
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list