]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - contrib/llvm/lib/VMCore/DebugInfoProbe.cpp
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / contrib / llvm / 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   };
57 }
58
59 //===----------------------------------------------------------------------===//
60 // DebugInfoProbeImpl
61
62 /// initialize - Collect information before running an optimization pass.
63 void DebugInfoProbeImpl::initialize(StringRef PName, Function &F) {
64   if (!EnableDebugInfoProbe) return;
65   PassName = PName;
66
67   DbgVariables.clear();
68   MissingDebugLoc.clear();
69   TheFn = &F;
70
71   for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
72     for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); 
73          BI != BE; ++BI) {
74       if (!isa<PHINode>(BI) && BI->getDebugLoc().isUnknown())
75         MissingDebugLoc.insert(BI);
76       if (!isa<DbgInfoIntrinsic>(BI)) continue;
77       Value *Addr = NULL;
78       MDNode *Node = NULL;
79       if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI)) {
80         Addr = DDI->getAddress();
81         Node = DDI->getVariable();
82       } else if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(BI)) {
83         Addr = DVI->getValue();
84         Node = DVI->getVariable();
85       }
86       if (Addr)
87         DbgVariables.insert(Node);
88     }
89 }
90
91 /// report - Report findings. This should be invoked after finalize.
92 void DebugInfoProbeImpl::report() {
93   if (!EnableDebugInfoProbe) return;
94   if (NumDbgLineLost || NumDbgValueLost) {
95     raw_ostream *OutStream = CreateInfoOutputFile();
96     if (NumDbgLineLost)
97       *OutStream << NumDbgLineLost
98                  << "\t times line number info lost by "
99                  << PassName << "\n";
100     if (NumDbgValueLost)
101       *OutStream << NumDbgValueLost
102                  << "\t times variable info lost by    "
103                  << PassName << "\n";
104     delete OutStream;
105   }
106   NumDbgLineLost = 0;
107   NumDbgValueLost = 0;
108 }
109
110 /// finalize - Collect information after running an optimization pass. This
111 /// must be used after initialization.
112 void DebugInfoProbeImpl::finalize(Function &F) {
113   if (!EnableDebugInfoProbe) return;
114   assert (TheFn == &F && "Invalid function to measure!");
115
116   std::set<MDNode *>DbgVariables2;
117   for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
118     for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); 
119          BI != BE; ++BI) {
120       if (!isa<PHINode>(BI) && BI->getDebugLoc().isUnknown() &&
121           MissingDebugLoc.count(BI) == 0) {
122         ++NumDbgLineLost;
123         DEBUG(dbgs() << "DebugInfoProbe (" << PassName << "): --- ");
124         DEBUG(BI->print(dbgs()));
125         DEBUG(dbgs() << "\n");
126       }
127       if (!isa<DbgInfoIntrinsic>(BI)) continue;
128       Value *Addr = NULL;
129       MDNode *Node = NULL;
130       if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI)) {
131         Addr = DDI->getAddress();
132         Node = DDI->getVariable();
133       } else if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(BI)) {
134         Addr = DVI->getValue();
135         Node = DVI->getVariable();
136       }
137       if (Addr)
138         DbgVariables2.insert(Node);
139     }
140
141   for (std::set<MDNode *>::iterator I = DbgVariables.begin(), 
142          E = DbgVariables.end(); I != E; ++I) {
143     if (DbgVariables2.count(*I) == 0 && (*I)->getNumOperands() >= 2) {
144       DEBUG(dbgs() 
145             << "DebugInfoProbe("
146             << PassName
147             << "): Losing dbg info for variable: ";
148             if (MDString *MDS = dyn_cast_or_null<MDString>(
149                 (*I)->getOperand(2)))
150               dbgs() << MDS->getString();
151             else
152               dbgs() << "...";
153             dbgs() << "\n");
154       ++NumDbgValueLost;
155     }
156   }
157 }
158
159 //===----------------------------------------------------------------------===//
160 // DebugInfoProbe
161
162 DebugInfoProbe::DebugInfoProbe() {
163   pImpl = new DebugInfoProbeImpl();
164 }
165
166 DebugInfoProbe::~DebugInfoProbe() {
167   delete pImpl;
168 }
169
170 /// initialize - Collect information before running an optimization pass.
171 void DebugInfoProbe::initialize(StringRef PName, Function &F) {
172   pImpl->initialize(PName, F);
173 }
174
175 /// finalize - Collect information after running an optimization pass. This
176 /// must be used after initialization.
177 void DebugInfoProbe::finalize(Function &F) {
178   pImpl->finalize(F);
179 }
180
181 /// report - Report findings. This should be invoked after finalize.
182 void DebugInfoProbe::report() {
183   pImpl->report();
184 }
185
186 //===----------------------------------------------------------------------===//
187 // DebugInfoProbeInfo
188
189 /// ~DebugInfoProbeInfo - Report data collected by all probes before deleting
190 /// them.
191 DebugInfoProbeInfo::~DebugInfoProbeInfo() {
192   if (!EnableDebugInfoProbe) return;
193     for (StringMap<DebugInfoProbe*>::iterator I = Probes.begin(),
194            E = Probes.end(); I != E; ++I) {
195       I->second->report();
196       delete I->second;
197     }
198   }
199
200 /// initialize - Collect information before running an optimization pass.
201 void DebugInfoProbeInfo::initialize(Pass *P, Function &F) {
202   if (!EnableDebugInfoProbe) return;
203   if (P->getAsPMDataManager())
204     return;
205
206   StringMapEntry<DebugInfoProbe *> &Entry =
207     Probes.GetOrCreateValue(P->getPassName());
208   DebugInfoProbe *&Probe = Entry.getValue();
209   if (!Probe)
210     Probe = new DebugInfoProbe();
211   Probe->initialize(P->getPassName(), F);
212 }
213
214 /// finalize - Collect information after running an optimization pass. This
215 /// must be used after initialization.
216 void DebugInfoProbeInfo::finalize(Pass *P, Function &F) {
217   if (!EnableDebugInfoProbe) return;
218   if (P->getAsPMDataManager())
219     return;
220   StringMapEntry<DebugInfoProbe *> &Entry =
221     Probes.GetOrCreateValue(P->getPassName());
222   DebugInfoProbe *&Probe = Entry.getValue();
223   assert (Probe && "DebugInfoProbe is not initialized!");
224   Probe->finalize(F);
225 }