382c297148248e0bcb1de150e451a1fa5a4c2970
[oota-llvm.git] / lib / VMCore / DebugInfoProbe.cpp
1 //===-- DebugInfoProbe.cpp - DebugInfo Probe ------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements DebugInfoProbe. This probe can be used by a pass
11 // manager to analyze how optimizer is treating debugging information.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #define DEBUG_TYPE "debuginfoprobe"
16 #include "llvm/DebugInfoProbe.h"
17 #include "llvm/Function.h"
18 #include "llvm/IntrinsicInst.h"
19 #include "llvm/Metadata.h"
20 #include "llvm/PassManager.h"
21 #include "llvm/Support/CommandLine.h"
22 #include "llvm/Support/Debug.h"
23 #include "llvm/Support/DebugLoc.h"
24 #include "llvm/Support/raw_ostream.h"
25 #include "llvm/ADT/StringRef.h"
26 #include <set>
27 #include <string>
28
29 using namespace llvm;
30
31 static cl::opt<bool>
32 EnableDebugInfoProbe("enable-debug-info-probe", cl::Hidden,
33                      cl::desc("Enable debug info probe"));
34
35 // CreateInfoOutputFile - Return a file stream to print our output on.
36 namespace llvm { extern raw_ostream *CreateInfoOutputFile(); }
37
38 //===----------------------------------------------------------------------===//
39 // DebugInfoProbeImpl - This class implements a interface to monitor
40 // how an optimization pass is preserving debugging information.
41
42 namespace llvm {
43
44   class DebugInfoProbeImpl {
45   public:
46     DebugInfoProbeImpl() : NumDbgLineLost(0),NumDbgValueLost(0) {}
47     void initialize(StringRef PName, Function &F);
48     void finalize(Function &F);
49     void report();
50   private:
51     unsigned NumDbgLineLost, NumDbgValueLost;
52     std::string PassName;
53     Function *TheFn;
54     std::set<MDNode *> DbgVariables;
55     std::set<Instruction *> MissingDebugLoc;
56     std::set<unsigned> LineNos;
57   };
58 }
59
60 //===----------------------------------------------------------------------===//
61 // DebugInfoProbeImpl
62
63 /// initialize - Collect information before running an optimization pass.
64 void DebugInfoProbeImpl::initialize(StringRef PName, Function &F) {
65   if (!EnableDebugInfoProbe) return;
66   PassName = PName;
67
68   DbgVariables.clear();
69   MissingDebugLoc.clear();
70   LineNos.clear();
71   TheFn = &F;
72
73   for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
74     for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); 
75          BI != BE; ++BI) {
76       DebugLoc DL = BI->getDebugLoc();
77       if (DL.isUnknown()) {
78         if (!isa<PHINode>(BI))
79           MissingDebugLoc.insert(BI);
80       } else
81         LineNos.insert(DL.getLine());
82        if (!isa<DbgInfoIntrinsic>(BI)) continue;
83       Value *Addr = NULL;
84       MDNode *Node = NULL;
85       if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI)) {
86         Addr = DDI->getAddress();
87         Node = DDI->getVariable();
88       } else if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(BI)) {
89         Addr = DVI->getValue();
90         Node = DVI->getVariable();
91       }
92       if (Addr)
93         DbgVariables.insert(Node);
94     }
95 }
96
97 /// report - Report findings. This should be invoked after finalize.
98 void DebugInfoProbeImpl::report() {
99   if (!EnableDebugInfoProbe) return;
100   if (NumDbgLineLost || NumDbgValueLost) {
101     raw_ostream *OutStream = CreateInfoOutputFile();
102     if (NumDbgLineLost)
103       *OutStream << NumDbgLineLost
104                  << "\t times line number info lost by "
105                  << PassName << "\n";
106     if (NumDbgValueLost)
107       *OutStream << NumDbgValueLost
108                  << "\t times variable info lost by    "
109                  << PassName << "\n";
110     delete OutStream;
111   }
112   NumDbgLineLost = 0;
113   NumDbgValueLost = 0;
114 }
115
116 /// finalize - Collect information after running an optimization pass. This
117 /// must be used after initialization.
118 void DebugInfoProbeImpl::finalize(Function &F) {
119   if (!EnableDebugInfoProbe) return;
120   assert (TheFn == &F && "Invalid function to measure!");
121
122   std::set<MDNode *>DbgVariables2;
123   std::set<unsigned>LineNos2;
124   for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
125     for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); 
126          BI != BE; ++BI) {
127       DebugLoc DL = BI->getDebugLoc();
128       if (DL.isUnknown()) {
129         if (!isa<PHINode>(BI) && MissingDebugLoc.count(BI) == 0) {
130           ++NumDbgLineLost;
131           DEBUG(dbgs() << "DebugInfoProbe (" << PassName << "): --- ");
132           DEBUG(BI->print(dbgs()));
133           DEBUG(dbgs() << "\n");
134         }
135       } else
136         LineNos2.insert(DL.getLine());
137       if (!isa<DbgInfoIntrinsic>(BI)) continue;
138       Value *Addr = NULL;
139       MDNode *Node = NULL;
140       if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI)) {
141         Addr = DDI->getAddress();
142         Node = DDI->getVariable();
143       } else if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(BI)) {
144         Addr = DVI->getValue();
145         Node = DVI->getVariable();
146       }
147       if (Addr)
148         DbgVariables2.insert(Node);
149     }
150
151   for (std::set<unsigned>::iterator I = LineNos.begin(),
152          E = LineNos.end(); I != E; ++I) {
153     unsigned LNO = *I;
154     if (LineNos2.count(LNO) == 0)
155       DEBUG(dbgs() << "DebugInfoProbe dropping line number " << LNO << "\n");
156   }
157   for (std::set<MDNode *>::iterator I = DbgVariables.begin(), 
158          E = DbgVariables.end(); I != E; ++I) {
159     if (DbgVariables2.count(*I) == 0 && (*I)->getNumOperands() >= 2) {
160       DEBUG(dbgs() 
161             << "DebugInfoProbe("
162             << PassName
163             << "): Losing dbg info for variable: ";
164             if (MDString *MDS = dyn_cast_or_null<MDString>(
165                 (*I)->getOperand(2)))
166               dbgs() << MDS->getString();
167             else
168               dbgs() << "...";
169             dbgs() << "\n");
170       ++NumDbgValueLost;
171     }
172   }
173 }
174
175 //===----------------------------------------------------------------------===//
176 // DebugInfoProbe
177
178 DebugInfoProbe::DebugInfoProbe() {
179   pImpl = new DebugInfoProbeImpl();
180 }
181
182 DebugInfoProbe::~DebugInfoProbe() {
183   delete pImpl;
184 }
185
186 /// initialize - Collect information before running an optimization pass.
187 void DebugInfoProbe::initialize(StringRef PName, Function &F) {
188   pImpl->initialize(PName, F);
189 }
190
191 /// finalize - Collect information after running an optimization pass. This
192 /// must be used after initialization.
193 void DebugInfoProbe::finalize(Function &F) {
194   pImpl->finalize(F);
195 }
196
197 /// report - Report findings. This should be invoked after finalize.
198 void DebugInfoProbe::report() {
199   pImpl->report();
200 }
201
202 //===----------------------------------------------------------------------===//
203 // DebugInfoProbeInfo
204
205 /// ~DebugInfoProbeInfo - Report data collected by all probes before deleting
206 /// them.
207 DebugInfoProbeInfo::~DebugInfoProbeInfo() {
208   if (!EnableDebugInfoProbe) return;
209     for (StringMap<DebugInfoProbe*>::iterator I = Probes.begin(),
210            E = Probes.end(); I != E; ++I) {
211       I->second->report();
212       delete I->second;
213     }
214   }
215
216 /// initialize - Collect information before running an optimization pass.
217 void DebugInfoProbeInfo::initialize(Pass *P, Function &F) {
218   if (!EnableDebugInfoProbe) return;
219   if (P->getAsPMDataManager())
220     return;
221
222   StringMapEntry<DebugInfoProbe *> &Entry =
223     Probes.GetOrCreateValue(P->getPassName());
224   DebugInfoProbe *&Probe = Entry.getValue();
225   if (!Probe)
226     Probe = new DebugInfoProbe();
227   Probe->initialize(P->getPassName(), F);
228 }
229
230 /// finalize - Collect information after running an optimization pass. This
231 /// must be used after initialization.
232 void DebugInfoProbeInfo::finalize(Pass *P, Function &F) {
233   if (!EnableDebugInfoProbe) return;
234   if (P->getAsPMDataManager())
235     return;
236   StringMapEntry<DebugInfoProbe *> &Entry =
237     Probes.GetOrCreateValue(P->getPassName());
238   DebugInfoProbe *&Probe = Entry.getValue();
239   assert (Probe && "DebugInfoProbe is not initialized!");
240   Probe->finalize(F);
241 }