aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2011-03-10 00:21:25 +0000
committerDevang Patel <dpatel@apple.com>2011-03-10 00:21:25 +0000
commit6af531febe488adb655c7e3de96c7c6bd6536eac (patch)
tree8c6e75ff86035d8621ec2cd8f4a08e0097d80d39
parentb0519e15f70cef7ba16b712f258d4782ade17e13 (diff)
downloadexternal_llvm-6af531febe488adb655c7e3de96c7c6bd6536eac.zip
external_llvm-6af531febe488adb655c7e3de96c7c6bd6536eac.tar.gz
external_llvm-6af531febe488adb655c7e3de96c7c6bd6536eac.tar.bz2
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127381 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/DebugInfoProbe.h67
-rw-r--r--lib/Analysis/LoopPass.cpp23
-rw-r--r--lib/VMCore/DebugInfoProbe.cpp237
-rw-r--r--lib/VMCore/PassManager.cpp23
4 files changed, 347 insertions, 3 deletions
diff --git a/include/llvm/DebugInfoProbe.h b/include/llvm/DebugInfoProbe.h
new file mode 100644
index 0000000..78d00df
--- /dev/null
+++ b/include/llvm/DebugInfoProbe.h
@@ -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
diff --git a/lib/Analysis/LoopPass.cpp b/lib/Analysis/LoopPass.cpp
index 8e1a7bf..10e3f29 100644
--- a/lib/Analysis/LoopPass.cpp
+++ b/lib/Analysis/LoopPass.cpp
@@ -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 @@ char PrintLoopPass::ID = 0;
}
//===----------------------------------------------------------------------===//
+// 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 @@ void LPPassManager::getAnalysisUsage(AnalysisUsage &Info) const {
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 @@ bool LPPassManager::runOnFunction(Function &F) {
// 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,
diff --git a/lib/VMCore/DebugInfoProbe.cpp b/lib/VMCore/DebugInfoProbe.cpp
new file mode 100644
index 0000000..4a5e659
--- /dev/null
+++ b/lib/VMCore/DebugInfoProbe.cpp
@@ -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);
+}
diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp
index cd170df..ca4455a 100644
--- a/lib/VMCore/PassManager.cpp
+++ b/lib/VMCore/PassManager.cpp
@@ -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 @@ char PassManagerImpl::ID = 0;
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 @@ void FunctionPassManagerImpl::releaseMemoryOnTheFly() {
bool FunctionPassManagerImpl::run(Function &F) {
bool Changed = false;
TimingInfo::createTheTimeInfo();
+ createDebugInfoProbe();
initializeAllAnalysisInfo();
for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
@@ -1477,13 +1494,16 @@ bool FPPassManager::runOnFunction(Function &F) {
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 @@ Pass* MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F){
bool PassManagerImpl::run(Module &M) {
bool Changed = false;
TimingInfo::createTheTimeInfo();
+ createDebugInfoProbe();
dumpArguments();
dumpPasses();