blob: 40d4f764b30a9d7e1e7c27659a2ce1582b9138e3 [file] [log] [blame]
Ted Kremenekaa04c512007-09-06 00:17:54 +00001//==- LiveVariables.cpp - Live Variable Analysis for Source CFGs -*- C++ --*-==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Ted Kremenek and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements Live Variables analysis for source-level CFGs.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Analysis/LiveVariables.h"
Ted Kremenek05334682007-09-06 21:26:58 +000015#include "clang/Basic/SourceManager.h"
Ted Kremenekaa04c512007-09-06 00:17:54 +000016#include "clang/AST/Expr.h"
17#include "clang/AST/CFG.h"
18#include "clang/AST/StmtVisitor.h"
19#include "clang/Lex/IdentifierTable.h"
20#include "llvm/ADT/SmallPtrSet.h"
21
Ted Kremenek05334682007-09-06 21:26:58 +000022#include <string.h>
23#include <stdio.h>
Ted Kremenekaa04c512007-09-06 00:17:54 +000024
25using namespace clang;
26
27//===----------------------------------------------------------------------===//
28// RegisterDecls - Utility class to create VarInfo objects for all
29// Decls referenced in a function.
30//
31
32namespace {
33
34class RegisterDecls : public StmtVisitor<RegisterDecls,void> {
35 LiveVariables& L;
36 const CFG& cfg;
37public:
38 RegisterDecls(LiveVariables& l, const CFG& c)
39 : L(l), cfg(c) {}
40
41 void VisitStmt(Stmt* S);
42 void VisitDeclRefExpr(DeclRefExpr* DR);
Ted Kremenekf63bda52007-09-06 23:25:10 +000043 void VisitDeclStmt(DeclStmt* DS);
Ted Kremenekaa04c512007-09-06 00:17:54 +000044 void Register(Decl* D);
Ted Kremenekf63bda52007-09-06 23:25:10 +000045 void RegisterDeclChain(Decl* D);
Ted Kremenekaa04c512007-09-06 00:17:54 +000046 void RegisterUsedDecls();
47};
48
49void RegisterDecls::VisitStmt(Stmt* S) {
50 for (Stmt::child_iterator I = S->child_begin(),E = S->child_end(); I != E;++I)
51 Visit(*I);
52}
53
54void RegisterDecls::VisitDeclRefExpr(DeclRefExpr* DR) {
Ted Kremenekf63bda52007-09-06 23:25:10 +000055 RegisterDeclChain(DR->getDecl());
56}
57
58void RegisterDecls::VisitDeclStmt(DeclStmt* DS) {
59 RegisterDeclChain(DS->getDecl());
60}
61
62void RegisterDecls::RegisterDeclChain(Decl* D) {
63 for (; D != NULL ; D = D->getNextDeclarator())
Ted Kremenekaa04c512007-09-06 00:17:54 +000064 Register(D);
65}
66
67void RegisterDecls::Register(Decl* D) {
Ted Kremenek6b2b4e32007-09-10 17:36:42 +000068 if (VarDecl* V = dyn_cast<VarDecl>(D)) {
69 LiveVariables::VPair& VP = L.getVarInfoMap()[V];
Ted Kremenekaa04c512007-09-06 00:17:54 +000070
Ted Kremenek6b2b4e32007-09-10 17:36:42 +000071 VP.V.AliveBlocks.resize(cfg.getNumBlockIDs());
72 VP.Idx = L.getNumDecls()++;
73 }
Ted Kremenekaa04c512007-09-06 00:17:54 +000074}
75
76void RegisterDecls::RegisterUsedDecls() {
77 for (CFG::const_iterator BI = cfg.begin(), BE = cfg.end(); BI != BE; ++BI)
78 for (CFGBlock::const_iterator SI=BI->begin(),SE = BI->end();SI != SE;++SI)
79 Visit(const_cast<Stmt*>(*SI));
80}
81
82
83} // end anonymous namespace
84
85//===----------------------------------------------------------------------===//
86// WorkList - Data structure representing the liveness algorithm worklist.
87//
88
89namespace {
90
91class WorkListTy {
92 typedef llvm::SmallPtrSet<const CFGBlock*,20> BlockSet;
93 BlockSet wlist;
94public:
95 void enqueue(const CFGBlock* B) { wlist.insert(B); }
96
97 const CFGBlock* dequeue() {
98 assert (!wlist.empty());
99 const CFGBlock* B = *wlist.begin();
100 wlist.erase(B);
101 return B;
102 }
103
104 bool isEmpty() const { return wlist.empty(); }
105};
106
107} // end anonymous namespace
108
109//===----------------------------------------------------------------------===//
110// TFuncs
111//
112
113namespace {
114
115class LivenessTFuncs : public StmtVisitor<LivenessTFuncs,void> {
116 LiveVariables& L;
117 llvm::BitVector Live;
Ted Kremenek05334682007-09-06 21:26:58 +0000118 llvm::BitVector KilledAtLeastOnce;
119 Stmt* CurrentStmt;
120 const CFGBlock* CurrentBlock;
121 bool blockPreviouslyProcessed;
Ted Kremenekd1d88262007-09-10 15:56:38 +0000122 LiveVariablesObserver* Observer;
Ted Kremenekaa04c512007-09-06 00:17:54 +0000123public:
Ted Kremenekd1d88262007-09-10 15:56:38 +0000124 LivenessTFuncs(LiveVariables& l, LiveVariablesObserver* A = NULL)
Ted Kremenek05334682007-09-06 21:26:58 +0000125 : L(l), CurrentStmt(NULL), CurrentBlock(NULL),
Ted Kremenekd1d88262007-09-10 15:56:38 +0000126 blockPreviouslyProcessed(false), Observer(A)
Ted Kremenek05334682007-09-06 21:26:58 +0000127 {
Ted Kremenekaa04c512007-09-06 00:17:54 +0000128 Live.resize(l.getNumDecls());
Ted Kremenek05334682007-09-06 21:26:58 +0000129 KilledAtLeastOnce.resize(l.getNumDecls());
Ted Kremenekaa04c512007-09-06 00:17:54 +0000130 }
131
132 void VisitStmt(Stmt* S);
133 void VisitDeclRefExpr(DeclRefExpr* DR);
134 void VisitBinaryOperator(BinaryOperator* B);
135 void VisitAssign(BinaryOperator* B);
136 void VisitStmtExpr(StmtExpr* S);
Ted Kremenek05334682007-09-06 21:26:58 +0000137 void VisitDeclStmt(DeclStmt* DS);
138 void VisitUnaryOperator(UnaryOperator* U);
Ted Kremenekaa04c512007-09-06 00:17:54 +0000139
Ted Kremenek6b2b4e32007-09-10 17:36:42 +0000140 unsigned getIdx(const VarDecl* D) {
Ted Kremenekaa04c512007-09-06 00:17:54 +0000141 LiveVariables::VarInfoMap& V = L.getVarInfoMap();
142 LiveVariables::VarInfoMap::iterator I = V.find(D);
143 assert (I != V.end());
144 return I->second.Idx;
145 }
146
147 bool ProcessBlock(const CFGBlock* B);
Ted Kremenek05334682007-09-06 21:26:58 +0000148 llvm::BitVector* getBlockEntryLiveness(const CFGBlock* B);
Ted Kremenek6b2b4e32007-09-10 17:36:42 +0000149 LiveVariables::VarInfo& KillVar(VarDecl* D);
Ted Kremenekaa04c512007-09-06 00:17:54 +0000150};
151
152void LivenessTFuncs::VisitStmt(Stmt* S) {
Ted Kremenekd1d88262007-09-10 15:56:38 +0000153 if (Observer)
154 Observer->ObserveStmt(S,L,Live);
Ted Kremenek05334682007-09-06 21:26:58 +0000155
Ted Kremenekaa04c512007-09-06 00:17:54 +0000156 // Evaluate the transfer functions for all subexpressions. Note that
157 // each invocation of "Visit" will have a side-effect: "Liveness" and "Kills"
Ted Kremenek05334682007-09-06 21:26:58 +0000158 // will be updated.
Ted Kremenekaa04c512007-09-06 00:17:54 +0000159 for (Stmt::child_iterator I = S->child_begin(),E = S->child_end(); I != E;++I)
160 Visit(*I);
161}
162
163void LivenessTFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
Ted Kremenekd1d88262007-09-10 15:56:38 +0000164 if (Observer)
165 Observer->ObserveStmt(DR,L,Live);
Ted Kremenek05334682007-09-06 21:26:58 +0000166
Ted Kremenekaa04c512007-09-06 00:17:54 +0000167 // Register a use of the variable.
Ted Kremenek6b2b4e32007-09-10 17:36:42 +0000168 if (VarDecl* V = dyn_cast<VarDecl>(DR->getDecl()))
169 Live.set(getIdx(V));
Ted Kremenekaa04c512007-09-06 00:17:54 +0000170}
171
172void LivenessTFuncs::VisitStmtExpr(StmtExpr* S) {
173 // Do nothing. The substatements of S are segmented into separate
174 // statements in the CFG.
175}
176
177void LivenessTFuncs::VisitBinaryOperator(BinaryOperator* B) {
178 switch (B->getOpcode()) {
179 case BinaryOperator::LAnd:
180 case BinaryOperator::LOr:
181 case BinaryOperator::Comma:
182 // Do nothing. These operations are broken up into multiple
183 // statements in the CFG. All these expressions do is return
Ted Kremenek05334682007-09-06 21:26:58 +0000184 // the value of their subexpressions, but these subexpressions will
Ted Kremenekaa04c512007-09-06 00:17:54 +0000185 // be evalualated elsewhere in the CFG.
186 break;
187
188 // FIXME: handle '++' and '--'
Ted Kremenek05334682007-09-06 21:26:58 +0000189 default:
Ted Kremenekaa04c512007-09-06 00:17:54 +0000190 if (B->isAssignmentOp()) VisitAssign(B);
Ted Kremenek05334682007-09-06 21:26:58 +0000191 else VisitStmt(B);
Ted Kremenekaa04c512007-09-06 00:17:54 +0000192 }
193}
194
Ted Kremenek05334682007-09-06 21:26:58 +0000195void LivenessTFuncs::VisitUnaryOperator(UnaryOperator* U) {
196 switch (U->getOpcode()) {
197 case UnaryOperator::PostInc:
198 case UnaryOperator::PostDec:
199 case UnaryOperator::PreInc:
200 case UnaryOperator::PreDec:
201 case UnaryOperator::AddrOf:
202 // Walk through the subexpressions, blasting through ParenExprs until
203 // we either find a DeclRefExpr or some non-DeclRefExpr expression.
204 for (Stmt* S = U->getSubExpr() ; ; ) {
205 if (ParenExpr* P = dyn_cast<ParenExpr>(S)) {
206 S = P->getSubExpr();
207 continue;
208 }
209 else if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S)) {
210 // Treat the --/++/& operator as a kill.
Ted Kremenek6b2b4e32007-09-10 17:36:42 +0000211 LiveVariables::VarInfo& V =
212 KillVar(cast<VarDecl>(DR->getDecl()));
Ted Kremenek05334682007-09-06 21:26:58 +0000213
214 if (!blockPreviouslyProcessed)
215 V.AddKill(CurrentStmt,DR);
216
217 VisitDeclRefExpr(DR);
218 }
219 else
220 Visit(S);
221
222 break;
223 }
224 break;
225
226 default:
227 VisitStmt(U->getSubExpr());
228 break;
229 }
230}
231
Ted Kremenek6b2b4e32007-09-10 17:36:42 +0000232LiveVariables::VarInfo& LivenessTFuncs::KillVar(VarDecl* D) {
Ted Kremenek05334682007-09-06 21:26:58 +0000233 LiveVariables::VarInfoMap::iterator I = L.getVarInfoMap().find(D);
234
235 assert (I != L.getVarInfoMap().end() &&
236 "Declaration not managed by variable map in LiveVariables");
237
238 // Mark the variable dead, and remove the current block from
239 // the set of blocks where the variable may be alive the entire time.
240 Live.reset(I->second.Idx);
241 I->second.V.AliveBlocks.reset(CurrentBlock->getBlockID());
242
243 return I->second.V;
244}
Ted Kremenekaa04c512007-09-06 00:17:54 +0000245
246void LivenessTFuncs::VisitAssign(BinaryOperator* B) {
Ted Kremenekd1d88262007-09-10 15:56:38 +0000247 if (Observer)
248 Observer->ObserveStmt(B,L,Live);
Ted Kremenek05334682007-09-06 21:26:58 +0000249
250 // Check if we are assigning to a variable.
Ted Kremenekaa04c512007-09-06 00:17:54 +0000251 Stmt* LHS = B->getLHS();
Ted Kremenek05334682007-09-06 21:26:58 +0000252
Ted Kremenekaa04c512007-09-06 00:17:54 +0000253 if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS)) {
Ted Kremenek6b2b4e32007-09-10 17:36:42 +0000254 LiveVariables::VarInfo& V = KillVar(cast<VarDecl>(DR->getDecl()));
Ted Kremenek05334682007-09-06 21:26:58 +0000255
256 // We only need to register kills once, so we check if this block
257 // has been previously processed.
258 if (!blockPreviouslyProcessed)
Ted Kremenek42276bc2007-09-06 23:39:53 +0000259 V.AddKill(CurrentStmt,DR);
260
261 if (B->getOpcode() != BinaryOperator::Assign)
262 Visit(LHS);
Ted Kremenekaa04c512007-09-06 00:17:54 +0000263 }
Ted Kremenek05334682007-09-06 21:26:58 +0000264 else
265 Visit(LHS);
Ted Kremenekaa04c512007-09-06 00:17:54 +0000266
267 Visit(B->getRHS());
268}
269
Ted Kremenek05334682007-09-06 21:26:58 +0000270void LivenessTFuncs::VisitDeclStmt(DeclStmt* DS) {
Ted Kremenekd1d88262007-09-10 15:56:38 +0000271 if (Observer)
272 Observer->ObserveStmt(DS,L,Live);
Ted Kremenek05334682007-09-06 21:26:58 +0000273
274 // Declarations effectively "kill" a variable since they cannot possibly
275 // be live before they are declared. Declarations, however, are not kills
276 // in the sense that the value is obliterated, so we do not register
277 // DeclStmts as a "kill site" for a variable.
278 for (Decl* D = DS->getDecl(); D != NULL ; D = D->getNextDeclarator())
Ted Kremenek6b2b4e32007-09-10 17:36:42 +0000279 KillVar(cast<VarDecl>(D));
Ted Kremenek05334682007-09-06 21:26:58 +0000280}
Ted Kremenekaa04c512007-09-06 00:17:54 +0000281
Ted Kremenek05334682007-09-06 21:26:58 +0000282llvm::BitVector* LivenessTFuncs::getBlockEntryLiveness(const CFGBlock* B) {
Ted Kremenekaa04c512007-09-06 00:17:54 +0000283 LiveVariables::BlockLivenessMap& BMap = L.getLiveAtBlockEntryMap();
284
285 LiveVariables::BlockLivenessMap::iterator I = BMap.find(B);
286 return (I == BMap.end()) ? NULL : &(I->second);
287}
288
289bool LivenessTFuncs::ProcessBlock(const CFGBlock* B) {
Ted Kremenek05334682007-09-06 21:26:58 +0000290
291 CurrentBlock = B;
Ted Kremenekaa04c512007-09-06 00:17:54 +0000292 Live.reset();
Ted Kremenek05334682007-09-06 21:26:58 +0000293 KilledAtLeastOnce.reset();
Ted Kremenekaa04c512007-09-06 00:17:54 +0000294
Ted Kremenek05334682007-09-06 21:26:58 +0000295 // Check if this block has been previously processed.
296 LiveVariables::BlockLivenessMap& BMap = L.getLiveAtBlockEntryMap();
297 LiveVariables::BlockLivenessMap::iterator BI = BMap.find(B);
298
299 blockPreviouslyProcessed = BI != BMap.end();
300
301 // Merge liveness information from all predecessors.
Ted Kremenekaa04c512007-09-06 00:17:54 +0000302 for (CFGBlock::const_succ_iterator I=B->succ_begin(),E=B->succ_end();I!=E;++I)
Ted Kremenek05334682007-09-06 21:26:58 +0000303 if (llvm::BitVector* V = getBlockEntryLiveness(*I))
Ted Kremenekaa04c512007-09-06 00:17:54 +0000304 Live |= *V;
Ted Kremenek05334682007-09-06 21:26:58 +0000305
Ted Kremenekd1d88262007-09-10 15:56:38 +0000306 if (Observer)
307 Observer->ObserveBlockExit(B,L,Live);
Ted Kremenek05334682007-09-06 21:26:58 +0000308
309 // Tentatively mark all variables alive at the end of the current block
310 // as being alive during the whole block. We then cull these out as
311 // we process the statements of this block.
312 for (LiveVariables::VarInfoMap::iterator
313 I=L.getVarInfoMap().begin(), E=L.getVarInfoMap().end(); I != E; ++I)
314 if (Live[I->second.Idx])
315 I->second.V.AliveBlocks.set(B->getBlockID());
Ted Kremenekaa04c512007-09-06 00:17:54 +0000316
Ted Kremenek05334682007-09-06 21:26:58 +0000317 // March up the statements and process the transfer functions.
Ted Kremenekaa04c512007-09-06 00:17:54 +0000318 for (CFGBlock::const_reverse_iterator I=B->rbegin(), E=B->rend(); I!=E; ++I) {
Ted Kremenek05334682007-09-06 21:26:58 +0000319 CurrentStmt = *I;
320 Visit(CurrentStmt);
Ted Kremenekaa04c512007-09-06 00:17:54 +0000321 }
322
Ted Kremenek05334682007-09-06 21:26:58 +0000323 // Compare the computed "Live" values with what we already have
324 // for the entry to this block.
Ted Kremenekaa04c512007-09-06 00:17:54 +0000325 bool hasChanged = false;
Ted Kremenek05334682007-09-06 21:26:58 +0000326
Ted Kremenekaa04c512007-09-06 00:17:54 +0000327
Ted Kremenek05334682007-09-06 21:26:58 +0000328 if (!blockPreviouslyProcessed) {
329 // We have not previously calculated liveness information for this block.
330 // Lazily instantiate a bitvector, and copy the bits from Live.
Ted Kremenekaa04c512007-09-06 00:17:54 +0000331 hasChanged = true;
332 llvm::BitVector& V = BMap[B];
333 V.resize(L.getNumDecls());
Ted Kremenek05334682007-09-06 21:26:58 +0000334 V = Live;
Ted Kremenekaa04c512007-09-06 00:17:54 +0000335 }
Ted Kremenek05334682007-09-06 21:26:58 +0000336 else if (BI->second != Live) {
Ted Kremenekaa04c512007-09-06 00:17:54 +0000337 hasChanged = true;
Ted Kremenek05334682007-09-06 21:26:58 +0000338 BI->second = Live;
Ted Kremenekaa04c512007-09-06 00:17:54 +0000339 }
340
341 return hasChanged;
342}
343
344} // end anonymous namespace
345
346//===----------------------------------------------------------------------===//
347// runOnCFG - Method to run the actual liveness computation.
348//
349
Ted Kremenekd1d88262007-09-10 15:56:38 +0000350void LiveVariables::runOnCFG(const CFG& cfg, LiveVariablesObserver* Observer) {
Ted Kremenekaa04c512007-09-06 00:17:54 +0000351 // Scan a CFG for DeclRefStmts. For each one, create a VarInfo object.
352 {
353 RegisterDecls R(*this,cfg);
354 R.RegisterUsedDecls();
355 }
356
357 // Create the worklist and enqueue the exit block.
358 WorkListTy WorkList;
359 WorkList.enqueue(&cfg.getExit());
360
361 // Create the state for transfer functions.
Ted Kremenekd1d88262007-09-10 15:56:38 +0000362 LivenessTFuncs TF(*this,Observer);
Ted Kremenekaa04c512007-09-06 00:17:54 +0000363
364 // Process the worklist until it is empty.
365
366 while (!WorkList.isEmpty()) {
367 const CFGBlock* B = WorkList.dequeue();
368 if (TF.ProcessBlock(B))
369 for (CFGBlock::const_pred_iterator I = B->pred_begin(), E = B->pred_end();
370 I != E; ++I)
371 WorkList.enqueue(*I);
372 }
373
Ted Kremenek05334682007-09-06 21:26:58 +0000374 // Go through each block and reserve a bitvector. This is needed if
375 // a block was never visited by the worklist algorithm.
Ted Kremenekaa04c512007-09-06 00:17:54 +0000376 for (CFG::const_iterator I = cfg.begin(), E = cfg.end(); I != E; ++I)
377 LiveAtBlockEntryMap[&(*I)].resize(NumDecls);
378}
379
Ted Kremenek05334682007-09-06 21:26:58 +0000380
Ted Kremenekd1d88262007-09-10 15:56:38 +0000381void LiveVariables::runOnBlock(const CFGBlock* B,
382 LiveVariablesObserver* Observer)
Ted Kremenek05334682007-09-06 21:26:58 +0000383{
Ted Kremenekd1d88262007-09-10 15:56:38 +0000384 LivenessTFuncs TF(*this,Observer);
Ted Kremenek05334682007-09-06 21:26:58 +0000385 TF.ProcessBlock(B);
386}
387
388//===----------------------------------------------------------------------===//
389// liveness queries
390//
391
Ted Kremenek6b2b4e32007-09-10 17:36:42 +0000392bool LiveVariables::isLive(const CFGBlock* B, const VarDecl* D) const {
Ted Kremenek05334682007-09-06 21:26:58 +0000393 BlockLivenessMap::const_iterator I = LiveAtBlockEntryMap.find(B);
394 assert (I != LiveAtBlockEntryMap.end());
395
396 VarInfoMap::const_iterator VI = VarInfos.find(D);
397 assert (VI != VarInfos.end());
398
399 return I->second[VI->second.Idx];
400}
401
Ted Kremenek6b2b4e32007-09-10 17:36:42 +0000402bool LiveVariables::isLive(llvm::BitVector& Live, const VarDecl* D) const {
Ted Kremeneke805c4a2007-09-06 23:00:42 +0000403 VarInfoMap::const_iterator VI = VarInfos.find(D);
404 assert (VI != VarInfos.end());
405 return Live[VI->second.Idx];
406}
407
Ted Kremenek6b2b4e32007-09-10 17:36:42 +0000408bool LiveVariables::KillsVar(const Stmt* S, const VarDecl* D) const {
Ted Kremenek05334682007-09-06 21:26:58 +0000409 VarInfoMap::const_iterator VI = VarInfos.find(D);
410 assert (VI != VarInfos.end());
411
412 for (VarInfo::KillsSet::const_iterator
413 I = VI->second.V.Kills.begin(), E = VI->second.V.Kills.end(); I!=E;++I)
414 if (I->first == S)
415 return true;
416
417 return false;
418}
419
Ted Kremenek6b2b4e32007-09-10 17:36:42 +0000420LiveVariables::VarInfo& LiveVariables::getVarInfo(const VarDecl* D) {
Ted Kremenek05334682007-09-06 21:26:58 +0000421 VarInfoMap::iterator VI = VarInfos.find(D);
422 assert (VI != VarInfos.end());
423 return VI->second.V;
424}
425
Ted Kremenek6b2b4e32007-09-10 17:36:42 +0000426const LiveVariables::VarInfo& LiveVariables::getVarInfo(const VarDecl* D) const{
Ted Kremenek05334682007-09-06 21:26:58 +0000427 return const_cast<LiveVariables*>(this)->getVarInfo(D);
428}
429
Ted Kremenekaa04c512007-09-06 00:17:54 +0000430//===----------------------------------------------------------------------===//
Ted Kremenekd1d88262007-09-10 15:56:38 +0000431// Defaults for LiveVariablesObserver
Ted Kremeneke805c4a2007-09-06 23:00:42 +0000432
Ted Kremenekd1d88262007-09-10 15:56:38 +0000433void LiveVariablesObserver::ObserveStmt(Stmt* S, LiveVariables& L,
434 llvm::BitVector& V) {}
Ted Kremeneke805c4a2007-09-06 23:00:42 +0000435
Ted Kremenekd1d88262007-09-10 15:56:38 +0000436void LiveVariablesObserver::ObserveBlockExit(const CFGBlock* B,
437 LiveVariables& L,
438 llvm::BitVector& V) {}
Ted Kremeneke805c4a2007-09-06 23:00:42 +0000439
440//===----------------------------------------------------------------------===//
Ted Kremenekaa04c512007-09-06 00:17:54 +0000441// printing liveness state for debugging
442//
443
Ted Kremenek05334682007-09-06 21:26:58 +0000444void LiveVariables::dumpLiveness(const llvm::BitVector& V,
445 SourceManager& SM) const {
Ted Kremenekaa04c512007-09-06 00:17:54 +0000446
447 for (VarInfoMap::iterator I = VarInfos.begin(), E=VarInfos.end(); I!=E; ++I) {
448 if (V[I->second.Idx]) {
Ted Kremenek05334682007-09-06 21:26:58 +0000449
450 SourceLocation PhysLoc = SM.getPhysicalLoc(I->first->getLocation());
451
452 fprintf(stderr, " %s <%s:%u:%u>\n",
453 I->first->getIdentifier()->getName(),
454 SM.getSourceName(PhysLoc),
455 SM.getLineNumber(PhysLoc),
456 SM.getColumnNumber(PhysLoc));
Ted Kremenekaa04c512007-09-06 00:17:54 +0000457 }
458 }
459}
460
Ted Kremenek05334682007-09-06 21:26:58 +0000461void LiveVariables::dumpBlockLiveness(SourceManager& M) const {
Ted Kremenekaa04c512007-09-06 00:17:54 +0000462 for (BlockLivenessMap::iterator I = LiveAtBlockEntryMap.begin(),
463 E = LiveAtBlockEntryMap.end();
464 I != E; ++I) {
Ted Kremenekaa04c512007-09-06 00:17:54 +0000465
Ted Kremenek05334682007-09-06 21:26:58 +0000466 fprintf(stderr,
467 "\n[ B%d (live variables at block entry) ]\n",
468 I->first->getBlockID());
469
470 dumpLiveness(I->second,M);
471 }
Ted Kremenek6b2b4e32007-09-10 17:36:42 +0000472
473 fprintf(stderr,"\n");
474}
475
476void LiveVariables::dumpVarLiveness(SourceManager& SM) const {
477
478 for (VarInfoMap::iterator I = VarInfos.begin(), E=VarInfos.end(); I!=E; ++I) {
479 SourceLocation PhysLoc = SM.getPhysicalLoc(I->first->getLocation());
480
481 fprintf(stderr, "[ %s <%s:%u:%u> ]\n",
482 I->first->getIdentifier()->getName(),
483 SM.getSourceName(PhysLoc),
484 SM.getLineNumber(PhysLoc),
485 SM.getColumnNumber(PhysLoc));
486
487 I->second.V.Dump(SM);
488 }
489}
490
491void LiveVariables::VarInfo::Dump(SourceManager& SM) const {
492 fprintf(stderr," Blocks Alive:");
493 for (unsigned i = 0; i < AliveBlocks.size(); ++i) {
494 if (i % 5 == 0)
495 fprintf(stderr,"\n ");
496
497 fprintf(stderr," B%d", i);
498 }
499
500 fprintf(stderr,"\n Kill Sites:\n");
501 for (KillsSet::const_iterator I = Kills.begin(), E = Kills.end(); I!=E; ++I) {
502 SourceLocation PhysLoc =
503 SM.getPhysicalLoc(I->second->getSourceRange().Begin());
504
505 fprintf(stderr, " <%s:%u:%u>\n",
506 SM.getSourceName(PhysLoc),
507 SM.getLineNumber(PhysLoc),
508 SM.getColumnNumber(PhysLoc));
509 }
510
511 fprintf(stderr,"\n");
Gabor Greif61ce98c2007-09-11 15:32:40 +0000512}