1 //===-- DebugInfoProbe.cpp - DebugInfo Probe ------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements DebugInfoProbe. This probe can be used by a pass
11 // manager to analyze how optimizer is treating debugging information.
13 //===----------------------------------------------------------------------===//
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"
32 EnableDebugInfoProbe("enable-debug-info-probe", cl::Hidden,
33 cl::desc("Enable debug info probe"));
35 // CreateInfoOutputFile - Return a file stream to print our output on.
36 namespace llvm { extern raw_ostream *CreateInfoOutputFile(); }
38 //===----------------------------------------------------------------------===//
39 // DebugInfoProbeImpl - This class implements a interface to monitor
40 // how an optimization pass is preserving debugging information.
44 class DebugInfoProbeImpl {
46 DebugInfoProbeImpl() : NumDbgLineLost(0),NumDbgValueLost(0) {}
47 void initialize(StringRef PName, Function &F);
48 void finalize(Function &F);
51 unsigned NumDbgLineLost, NumDbgValueLost;
54 std::set<MDNode *> DbgVariables;
55 std::set<Instruction *> MissingDebugLoc;
56 std::set<unsigned> LineNos;
60 //===----------------------------------------------------------------------===//
63 /// initialize - Collect information before running an optimization pass.
64 void DebugInfoProbeImpl::initialize(StringRef PName, Function &F) {
65 if (!EnableDebugInfoProbe) return;
69 MissingDebugLoc.clear();
73 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
74 for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
76 DebugLoc DL = BI->getDebugLoc();
78 if (!isa<PHINode>(BI))
79 MissingDebugLoc.insert(BI);
81 LineNos.insert(DL.getLine());
82 if (!isa<DbgInfoIntrinsic>(BI)) continue;
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();
93 DbgVariables.insert(Node);
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();
103 *OutStream << NumDbgLineLost
104 << "\t times line number info lost by "
107 *OutStream << NumDbgValueLost
108 << "\t times variable info lost by "
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!");
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();
127 DebugLoc DL = BI->getDebugLoc();
128 if (DL.isUnknown()) {
129 if (!isa<PHINode>(BI) && MissingDebugLoc.count(BI) == 0) {
131 DEBUG(dbgs() << "DebugInfoProbe (" << PassName << "): --- ");
132 DEBUG(BI->print(dbgs()));
133 DEBUG(dbgs() << "\n");
136 LineNos2.insert(DL.getLine());
137 if (!isa<DbgInfoIntrinsic>(BI)) continue;
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();
148 DbgVariables2.insert(Node);
151 for (std::set<unsigned>::iterator I = LineNos.begin(),
152 E = LineNos.end(); I != E; ++I) {
154 if (LineNos2.count(LNO) == 0)
155 DEBUG(dbgs() << "DebugInfoProbe dropping line number " << LNO << "\n");
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) {
163 << "): Losing dbg info for variable: ";
164 if (MDString *MDS = dyn_cast_or_null<MDString>(
165 (*I)->getOperand(2)))
166 dbgs() << MDS->getString();
175 //===----------------------------------------------------------------------===//
178 DebugInfoProbe::DebugInfoProbe() {
179 pImpl = new DebugInfoProbeImpl();
182 DebugInfoProbe::~DebugInfoProbe() {
186 /// initialize - Collect information before running an optimization pass.
187 void DebugInfoProbe::initialize(StringRef PName, Function &F) {
188 pImpl->initialize(PName, F);
191 /// finalize - Collect information after running an optimization pass. This
192 /// must be used after initialization.
193 void DebugInfoProbe::finalize(Function &F) {
197 /// report - Report findings. This should be invoked after finalize.
198 void DebugInfoProbe::report() {
202 //===----------------------------------------------------------------------===//
203 // DebugInfoProbeInfo
205 /// ~DebugInfoProbeInfo - Report data collected by all probes before deleting
207 DebugInfoProbeInfo::~DebugInfoProbeInfo() {
208 if (!EnableDebugInfoProbe) return;
209 for (StringMap<DebugInfoProbe*>::iterator I = Probes.begin(),
210 E = Probes.end(); I != E; ++I) {
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())
222 StringMapEntry<DebugInfoProbe *> &Entry =
223 Probes.GetOrCreateValue(P->getPassName());
224 DebugInfoProbe *&Probe = Entry.getValue();
226 Probe = new DebugInfoProbe();
227 Probe->initialize(P->getPassName(), F);
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())
236 StringMapEntry<DebugInfoProbe *> &Entry =
237 Probes.GetOrCreateValue(P->getPassName());
238 DebugInfoProbe *&Probe = Entry.getValue();
239 assert (Probe && "DebugInfoProbe is not initialized!");