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
<unsigned> LineNos
;
55 std::set
<MDNode
*> DbgVariables
;
59 //===----------------------------------------------------------------------===//
62 static void collect(Function
&F
, std::set
<unsigned> &Lines
) {
63 for (Function::iterator FI
= F
.begin(), FE
= F
.end(); FI
!= FE
; ++FI
)
64 for (BasicBlock::iterator BI
= FI
->begin(), BE
= FI
->end();
66 const DebugLoc
&DL
= BI
->getDebugLoc();
68 if (!DL
.isUnknown()) {
69 if (MDNode
*N
= DL
.getInlinedAt(F
.getContext()))
70 LineNo
= DebugLoc::getFromDILocation(N
).getLine();
72 LineNo
= DL
.getLine();
79 /// initialize - Collect information before running an optimization pass.
80 void DebugInfoProbeImpl::initialize(StringRef PName
, Function
&F
) {
81 if (!EnableDebugInfoProbe
) return;
89 for (Function::iterator FI
= F
.begin(), FE
= F
.end(); FI
!= FE
; ++FI
)
90 for (BasicBlock::iterator BI
= FI
->begin(), BE
= FI
->end();
92 if (!isa
<DbgInfoIntrinsic
>(BI
)) continue;
95 if (DbgDeclareInst
*DDI
= dyn_cast
<DbgDeclareInst
>(BI
)) {
96 Addr
= DDI
->getAddress();
97 Node
= DDI
->getVariable();
98 } else if (DbgValueInst
*DVI
= dyn_cast
<DbgValueInst
>(BI
)) {
99 Addr
= DVI
->getValue();
100 Node
= DVI
->getVariable();
103 DbgVariables
.insert(Node
);
107 /// report - Report findings. This should be invoked after finalize.
108 void DebugInfoProbeImpl::report() {
109 if (!EnableDebugInfoProbe
) return;
110 if (NumDbgLineLost
|| NumDbgValueLost
) {
111 raw_ostream
*OutStream
= CreateInfoOutputFile();
113 *OutStream
<< NumDbgLineLost
114 << "\t times line number info lost by "
117 *OutStream
<< NumDbgValueLost
118 << "\t times variable info lost by "
126 /// finalize - Collect information after running an optimization pass. This
127 /// must be used after initialization.
128 void DebugInfoProbeImpl::finalize(Function
&F
) {
129 if (!EnableDebugInfoProbe
) return;
130 std::set
<unsigned> LineNos2
;
131 collect(F
, LineNos2
);
132 assert (TheFn
== &F
&& "Invalid function to measure!");
134 for (std::set
<unsigned>::iterator I
= LineNos
.begin(),
135 E
= LineNos
.end(); I
!= E
; ++I
) {
136 unsigned LineNo
= *I
;
137 if (LineNos2
.count(LineNo
) == 0) {
139 << "DebugInfoProbe: Losing dbg info for source line "
145 std::set
<MDNode
*>DbgVariables2
;
146 for (Function::iterator FI
= F
.begin(), FE
= F
.end(); FI
!= FE
; ++FI
)
147 for (BasicBlock::iterator BI
= FI
->begin(), BE
= FI
->end();
149 if (!isa
<DbgInfoIntrinsic
>(BI
)) continue;
152 if (DbgDeclareInst
*DDI
= dyn_cast
<DbgDeclareInst
>(BI
)) {
153 Addr
= DDI
->getAddress();
154 Node
= DDI
->getVariable();
155 } else if (DbgValueInst
*DVI
= dyn_cast
<DbgValueInst
>(BI
)) {
156 Addr
= DVI
->getValue();
157 Node
= DVI
->getVariable();
160 DbgVariables2
.insert(Node
);
163 for (std::set
<MDNode
*>::iterator I
= DbgVariables
.begin(),
164 E
= DbgVariables
.end(); I
!= E
; ++I
) {
165 if (DbgVariables2
.count(*I
) == 0) {
166 DEBUG(dbgs() << "DebugInfoProbe: Losing dbg info for variable: ");
167 DEBUG((*I
)->print(dbgs()));
173 //===----------------------------------------------------------------------===//
176 DebugInfoProbe::DebugInfoProbe() {
177 pImpl
= new DebugInfoProbeImpl();
180 DebugInfoProbe::~DebugInfoProbe() {
184 /// initialize - Collect information before running an optimization pass.
185 void DebugInfoProbe::initialize(StringRef PName
, Function
&F
) {
186 pImpl
->initialize(PName
, F
);
189 /// finalize - Collect information after running an optimization pass. This
190 /// must be used after initialization.
191 void DebugInfoProbe::finalize(Function
&F
) {
195 /// report - Report findings. This should be invoked after finalize.
196 void DebugInfoProbe::report() {
200 //===----------------------------------------------------------------------===//
201 // DebugInfoProbeInfo
203 /// ~DebugInfoProbeInfo - Report data collected by all probes before deleting
205 DebugInfoProbeInfo::~DebugInfoProbeInfo() {
206 if (!EnableDebugInfoProbe
) return;
207 for (StringMap
<DebugInfoProbe
*>::iterator I
= Probes
.begin(),
208 E
= Probes
.end(); I
!= E
; ++I
) {
214 /// initialize - Collect information before running an optimization pass.
215 void DebugInfoProbeInfo::initialize(Pass
*P
, Function
&F
) {
216 if (!EnableDebugInfoProbe
) return;
217 if (P
->getAsPMDataManager())
220 StringMapEntry
<DebugInfoProbe
*> &Entry
=
221 Probes
.GetOrCreateValue(P
->getPassName());
222 DebugInfoProbe
*&Probe
= Entry
.getValue();
224 Probe
= new DebugInfoProbe();
225 Probe
->initialize(P
->getPassName(), F
);
228 /// finalize - Collect information after running an optimization pass. This
229 /// must be used after initialization.
230 void DebugInfoProbeInfo::finalize(Pass
*P
, Function
&F
) {
231 if (!EnableDebugInfoProbe
) return;
232 if (P
->getAsPMDataManager())
234 StringMapEntry
<DebugInfoProbe
*> &Entry
=
235 Probes
.GetOrCreateValue(P
->getPassName());
236 DebugInfoProbe
*&Probe
= Entry
.getValue();
237 assert (Probe
&& "DebugInfoProbe is not initialized!");