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

Devang Patel dpatel at apple.com
Wed Mar 9 16:21:25 PST 2011


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


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();





More information about the llvm-commits mailing list