blob: 89cea66789ec2538ab334a4ca62f7678d91a249f [file] [log] [blame]
Ted Kremeneke4e63342007-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 Kremenek27b07c52007-09-06 21:26:58 +000015#include "clang/Basic/SourceManager.h"
Ted Kremeneke4e63342007-09-06 00:17:54 +000016#include "clang/AST/Expr.h"
17#include "clang/AST/CFG.h"
Ted Kremenekf1758052007-09-12 19:10:52 +000018#include "clang/Analysis/DataflowStmtVisitor.h"
Ted Kremeneke4e63342007-09-06 00:17:54 +000019#include "clang/Lex/IdentifierTable.h"
20#include "llvm/ADT/SmallPtrSet.h"
21
Ted Kremenek27b07c52007-09-06 21:26:58 +000022#include <string.h>
23#include <stdio.h>
Ted Kremeneke4e63342007-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 Kremeneke2ca1422007-09-06 23:25:10 +000043 void VisitDeclStmt(DeclStmt* DS);
Steve Naroff94745042007-09-13 23:52:58 +000044 void Register(ScopedDecl* D);
45 void RegisterDeclChain(ScopedDecl* D);
Ted Kremeneke4e63342007-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 Kremeneke2ca1422007-09-06 23:25:10 +000055 RegisterDeclChain(DR->getDecl());
56}
57
58void RegisterDecls::VisitDeclStmt(DeclStmt* DS) {
59 RegisterDeclChain(DS->getDecl());
60}
61
Steve Naroff94745042007-09-13 23:52:58 +000062void RegisterDecls::RegisterDeclChain(ScopedDecl* D) {
Ted Kremeneke2ca1422007-09-06 23:25:10 +000063 for (; D != NULL ; D = D->getNextDeclarator())
Ted Kremeneke4e63342007-09-06 00:17:54 +000064 Register(D);
65}
66
Steve Naroff94745042007-09-13 23:52:58 +000067void RegisterDecls::Register(ScopedDecl* D) {
Ted Kremenekc0576ca2007-09-10 17:36:42 +000068 if (VarDecl* V = dyn_cast<VarDecl>(D)) {
69 LiveVariables::VPair& VP = L.getVarInfoMap()[V];
Ted Kremeneke4e63342007-09-06 00:17:54 +000070
Ted Kremenekc0576ca2007-09-10 17:36:42 +000071 VP.V.AliveBlocks.resize(cfg.getNumBlockIDs());
72 VP.Idx = L.getNumDecls()++;
73 }
Ted Kremeneke4e63342007-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
Ted Kremenekf1758052007-09-12 19:10:52 +0000115class LivenessTFuncs : public DataflowStmtVisitor<LivenessTFuncs,
116 dataflow::backward_analysis_tag> {
Ted Kremeneke4e63342007-09-06 00:17:54 +0000117 LiveVariables& L;
118 llvm::BitVector Live;
Ted Kremenek27b07c52007-09-06 21:26:58 +0000119 llvm::BitVector KilledAtLeastOnce;
120 Stmt* CurrentStmt;
121 const CFGBlock* CurrentBlock;
122 bool blockPreviouslyProcessed;
Ted Kremenekb00c95e2007-09-10 15:56:38 +0000123 LiveVariablesObserver* Observer;
Ted Kremenekf1758052007-09-12 19:10:52 +0000124
Ted Kremeneke4e63342007-09-06 00:17:54 +0000125public:
Ted Kremenekb00c95e2007-09-10 15:56:38 +0000126 LivenessTFuncs(LiveVariables& l, LiveVariablesObserver* A = NULL)
Ted Kremenek27b07c52007-09-06 21:26:58 +0000127 : L(l), CurrentStmt(NULL), CurrentBlock(NULL),
Ted Kremenekf1758052007-09-12 19:10:52 +0000128 blockPreviouslyProcessed(false), Observer(A) {
Ted Kremeneke4e63342007-09-06 00:17:54 +0000129 Live.resize(l.getNumDecls());
Ted Kremenek27b07c52007-09-06 21:26:58 +0000130 KilledAtLeastOnce.resize(l.getNumDecls());
Ted Kremeneke4e63342007-09-06 00:17:54 +0000131 }
Ted Kremenekf1758052007-09-12 19:10:52 +0000132
Ted Kremeneke4e63342007-09-06 00:17:54 +0000133 void VisitDeclRefExpr(DeclRefExpr* DR);
134 void VisitBinaryOperator(BinaryOperator* B);
135 void VisitAssign(BinaryOperator* B);
Ted Kremenek27b07c52007-09-06 21:26:58 +0000136 void VisitDeclStmt(DeclStmt* DS);
137 void VisitUnaryOperator(UnaryOperator* U);
Ted Kremenekf1758052007-09-12 19:10:52 +0000138 void ObserveStmt(Stmt* S);
Ted Kremeneke4e63342007-09-06 00:17:54 +0000139
Ted Kremenekc0576ca2007-09-10 17:36:42 +0000140 unsigned getIdx(const VarDecl* D) {
Ted Kremeneke4e63342007-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 Kremenek27b07c52007-09-06 21:26:58 +0000148 llvm::BitVector* getBlockEntryLiveness(const CFGBlock* B);
Ted Kremenekc0576ca2007-09-10 17:36:42 +0000149 LiveVariables::VarInfo& KillVar(VarDecl* D);
Ted Kremeneke4e63342007-09-06 00:17:54 +0000150};
151
Ted Kremenekf1758052007-09-12 19:10:52 +0000152void LivenessTFuncs::ObserveStmt(Stmt* S) {
153 if (Observer) Observer->ObserveStmt(S,L,Live);
Ted Kremeneke4e63342007-09-06 00:17:54 +0000154}
155
156void LivenessTFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
157 // Register a use of the variable.
Ted Kremenekc0576ca2007-09-10 17:36:42 +0000158 if (VarDecl* V = dyn_cast<VarDecl>(DR->getDecl()))
159 Live.set(getIdx(V));
Ted Kremeneke4e63342007-09-06 00:17:54 +0000160}
Ted Kremeneke4e63342007-09-06 00:17:54 +0000161
Ted Kremenekf1758052007-09-12 19:10:52 +0000162void LivenessTFuncs::VisitBinaryOperator(BinaryOperator* B) {
163 if (B->isAssignmentOp()) VisitAssign(B);
164 else VisitStmt(B);
Ted Kremeneke4e63342007-09-06 00:17:54 +0000165}
166
Ted Kremenek27b07c52007-09-06 21:26:58 +0000167void LivenessTFuncs::VisitUnaryOperator(UnaryOperator* U) {
168 switch (U->getOpcode()) {
169 case UnaryOperator::PostInc:
170 case UnaryOperator::PostDec:
171 case UnaryOperator::PreInc:
172 case UnaryOperator::PreDec:
Ted Kremenek97487a02007-09-12 20:28:48 +0000173 case UnaryOperator::AddrOf:
Ted Kremenek27b07c52007-09-06 21:26:58 +0000174 // Walk through the subexpressions, blasting through ParenExprs until
175 // we either find a DeclRefExpr or some non-DeclRefExpr expression.
176 for (Stmt* S = U->getSubExpr() ; ; ) {
177 if (ParenExpr* P = dyn_cast<ParenExpr>(S)) {
178 S = P->getSubExpr();
179 continue;
180 }
181 else if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S)) {
182 // Treat the --/++/& operator as a kill.
Ted Kremenekc0576ca2007-09-10 17:36:42 +0000183 LiveVariables::VarInfo& V =
184 KillVar(cast<VarDecl>(DR->getDecl()));
Ted Kremenek27b07c52007-09-06 21:26:58 +0000185
186 if (!blockPreviouslyProcessed)
187 V.AddKill(CurrentStmt,DR);
188
189 VisitDeclRefExpr(DR);
190 }
Ted Kremenek97487a02007-09-12 20:28:48 +0000191 else Visit(S);
Ted Kremenek27b07c52007-09-06 21:26:58 +0000192
193 break;
194 }
195 break;
196
197 default:
Ted Kremenek37f97012007-09-12 20:11:39 +0000198 Visit(U->getSubExpr());
Ted Kremenek27b07c52007-09-06 21:26:58 +0000199 break;
200 }
201}
202
Ted Kremenekc0576ca2007-09-10 17:36:42 +0000203LiveVariables::VarInfo& LivenessTFuncs::KillVar(VarDecl* D) {
Ted Kremenek27b07c52007-09-06 21:26:58 +0000204 LiveVariables::VarInfoMap::iterator I = L.getVarInfoMap().find(D);
205
206 assert (I != L.getVarInfoMap().end() &&
207 "Declaration not managed by variable map in LiveVariables");
208
209 // Mark the variable dead, and remove the current block from
210 // the set of blocks where the variable may be alive the entire time.
211 Live.reset(I->second.Idx);
212 I->second.V.AliveBlocks.reset(CurrentBlock->getBlockID());
213
214 return I->second.V;
215}
Ted Kremeneke4e63342007-09-06 00:17:54 +0000216
Ted Kremenekf1758052007-09-12 19:10:52 +0000217void LivenessTFuncs::VisitAssign(BinaryOperator* B) {
Ted Kremenek27b07c52007-09-06 21:26:58 +0000218 // Check if we are assigning to a variable.
Ted Kremeneke4e63342007-09-06 00:17:54 +0000219 Stmt* LHS = B->getLHS();
Ted Kremenek27b07c52007-09-06 21:26:58 +0000220
Ted Kremeneke4e63342007-09-06 00:17:54 +0000221 if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS)) {
Ted Kremenekc0576ca2007-09-10 17:36:42 +0000222 LiveVariables::VarInfo& V = KillVar(cast<VarDecl>(DR->getDecl()));
Ted Kremenek27b07c52007-09-06 21:26:58 +0000223
224 // We only need to register kills once, so we check if this block
225 // has been previously processed.
226 if (!blockPreviouslyProcessed)
Ted Kremenek83522a32007-09-06 23:39:53 +0000227 V.AddKill(CurrentStmt,DR);
228
229 if (B->getOpcode() != BinaryOperator::Assign)
230 Visit(LHS);
Ted Kremeneke4e63342007-09-06 00:17:54 +0000231 }
Ted Kremenek27b07c52007-09-06 21:26:58 +0000232 else
233 Visit(LHS);
Ted Kremeneke4e63342007-09-06 00:17:54 +0000234
235 Visit(B->getRHS());
236}
237
Ted Kremenek27b07c52007-09-06 21:26:58 +0000238void LivenessTFuncs::VisitDeclStmt(DeclStmt* DS) {
Ted Kremenek27b07c52007-09-06 21:26:58 +0000239 // Declarations effectively "kill" a variable since they cannot possibly
240 // be live before they are declared. Declarations, however, are not kills
241 // in the sense that the value is obliterated, so we do not register
242 // DeclStmts as a "kill site" for a variable.
Steve Naroff94745042007-09-13 23:52:58 +0000243 for (ScopedDecl* D = DS->getDecl(); D != NULL ; D = D->getNextDeclarator())
Ted Kremenekc0576ca2007-09-10 17:36:42 +0000244 KillVar(cast<VarDecl>(D));
Ted Kremenek27b07c52007-09-06 21:26:58 +0000245}
Ted Kremeneke4e63342007-09-06 00:17:54 +0000246
Ted Kremenek27b07c52007-09-06 21:26:58 +0000247llvm::BitVector* LivenessTFuncs::getBlockEntryLiveness(const CFGBlock* B) {
Ted Kremeneke4e63342007-09-06 00:17:54 +0000248 LiveVariables::BlockLivenessMap& BMap = L.getLiveAtBlockEntryMap();
249
250 LiveVariables::BlockLivenessMap::iterator I = BMap.find(B);
251 return (I == BMap.end()) ? NULL : &(I->second);
252}
253
Ted Kremenekf1758052007-09-12 19:10:52 +0000254
Ted Kremeneke4e63342007-09-06 00:17:54 +0000255bool LivenessTFuncs::ProcessBlock(const CFGBlock* B) {
Ted Kremenek27b07c52007-09-06 21:26:58 +0000256
257 CurrentBlock = B;
Ted Kremeneke4e63342007-09-06 00:17:54 +0000258 Live.reset();
Ted Kremenek27b07c52007-09-06 21:26:58 +0000259 KilledAtLeastOnce.reset();
Ted Kremeneke4e63342007-09-06 00:17:54 +0000260
Ted Kremenek27b07c52007-09-06 21:26:58 +0000261 // Check if this block has been previously processed.
262 LiveVariables::BlockLivenessMap& BMap = L.getLiveAtBlockEntryMap();
263 LiveVariables::BlockLivenessMap::iterator BI = BMap.find(B);
264
265 blockPreviouslyProcessed = BI != BMap.end();
266
267 // Merge liveness information from all predecessors.
Ted Kremeneke4e63342007-09-06 00:17:54 +0000268 for (CFGBlock::const_succ_iterator I=B->succ_begin(),E=B->succ_end();I!=E;++I)
Ted Kremenek27b07c52007-09-06 21:26:58 +0000269 if (llvm::BitVector* V = getBlockEntryLiveness(*I))
Ted Kremeneke4e63342007-09-06 00:17:54 +0000270 Live |= *V;
Ted Kremenek27b07c52007-09-06 21:26:58 +0000271
Ted Kremenekb00c95e2007-09-10 15:56:38 +0000272 if (Observer)
Ted Kremenekf1758052007-09-12 19:10:52 +0000273 Observer->ObserveBlockExit(B,L,Live);
Ted Kremenek27b07c52007-09-06 21:26:58 +0000274
275 // Tentatively mark all variables alive at the end of the current block
276 // as being alive during the whole block. We then cull these out as
277 // we process the statements of this block.
278 for (LiveVariables::VarInfoMap::iterator
279 I=L.getVarInfoMap().begin(), E=L.getVarInfoMap().end(); I != E; ++I)
280 if (Live[I->second.Idx])
281 I->second.V.AliveBlocks.set(B->getBlockID());
Ted Kremeneke4e63342007-09-06 00:17:54 +0000282
Ted Kremenekf1758052007-09-12 19:10:52 +0000283 // Visit the statements in reverse order;
284 VisitBlock(B);
285
Ted Kremenek27b07c52007-09-06 21:26:58 +0000286 // Compare the computed "Live" values with what we already have
287 // for the entry to this block.
Ted Kremeneke4e63342007-09-06 00:17:54 +0000288 bool hasChanged = false;
289
Ted Kremenek27b07c52007-09-06 21:26:58 +0000290 if (!blockPreviouslyProcessed) {
291 // We have not previously calculated liveness information for this block.
292 // Lazily instantiate a bitvector, and copy the bits from Live.
Ted Kremeneke4e63342007-09-06 00:17:54 +0000293 hasChanged = true;
294 llvm::BitVector& V = BMap[B];
295 V.resize(L.getNumDecls());
Ted Kremenek27b07c52007-09-06 21:26:58 +0000296 V = Live;
Ted Kremeneke4e63342007-09-06 00:17:54 +0000297 }
Ted Kremenek27b07c52007-09-06 21:26:58 +0000298 else if (BI->second != Live) {
Ted Kremeneke4e63342007-09-06 00:17:54 +0000299 hasChanged = true;
Ted Kremenek27b07c52007-09-06 21:26:58 +0000300 BI->second = Live;
Ted Kremeneke4e63342007-09-06 00:17:54 +0000301 }
302
303 return hasChanged;
304}
305
306} // end anonymous namespace
307
308//===----------------------------------------------------------------------===//
309// runOnCFG - Method to run the actual liveness computation.
310//
311
Ted Kremenekb00c95e2007-09-10 15:56:38 +0000312void LiveVariables::runOnCFG(const CFG& cfg, LiveVariablesObserver* Observer) {
Ted Kremeneke4e63342007-09-06 00:17:54 +0000313 // Scan a CFG for DeclRefStmts. For each one, create a VarInfo object.
314 {
315 RegisterDecls R(*this,cfg);
316 R.RegisterUsedDecls();
317 }
318
319 // Create the worklist and enqueue the exit block.
320 WorkListTy WorkList;
321 WorkList.enqueue(&cfg.getExit());
322
323 // Create the state for transfer functions.
Ted Kremenekb00c95e2007-09-10 15:56:38 +0000324 LivenessTFuncs TF(*this,Observer);
Ted Kremeneke4e63342007-09-06 00:17:54 +0000325
326 // Process the worklist until it is empty.
327
328 while (!WorkList.isEmpty()) {
329 const CFGBlock* B = WorkList.dequeue();
330 if (TF.ProcessBlock(B))
331 for (CFGBlock::const_pred_iterator I = B->pred_begin(), E = B->pred_end();
332 I != E; ++I)
333 WorkList.enqueue(*I);
334 }
335
Ted Kremenek27b07c52007-09-06 21:26:58 +0000336 // Go through each block and reserve a bitvector. This is needed if
337 // a block was never visited by the worklist algorithm.
Ted Kremeneke4e63342007-09-06 00:17:54 +0000338 for (CFG::const_iterator I = cfg.begin(), E = cfg.end(); I != E; ++I)
339 LiveAtBlockEntryMap[&(*I)].resize(NumDecls);
340}
341
Ted Kremenek27b07c52007-09-06 21:26:58 +0000342
Ted Kremenekb00c95e2007-09-10 15:56:38 +0000343void LiveVariables::runOnBlock(const CFGBlock* B,
344 LiveVariablesObserver* Observer)
Ted Kremenek27b07c52007-09-06 21:26:58 +0000345{
Ted Kremenekb00c95e2007-09-10 15:56:38 +0000346 LivenessTFuncs TF(*this,Observer);
Ted Kremenek27b07c52007-09-06 21:26:58 +0000347 TF.ProcessBlock(B);
348}
349
350//===----------------------------------------------------------------------===//
351// liveness queries
352//
353
Ted Kremenekc0576ca2007-09-10 17:36:42 +0000354bool LiveVariables::isLive(const CFGBlock* B, const VarDecl* D) const {
Ted Kremenek27b07c52007-09-06 21:26:58 +0000355 BlockLivenessMap::const_iterator I = LiveAtBlockEntryMap.find(B);
356 assert (I != LiveAtBlockEntryMap.end());
357
358 VarInfoMap::const_iterator VI = VarInfos.find(D);
359 assert (VI != VarInfos.end());
360
361 return I->second[VI->second.Idx];
362}
363
Ted Kremenekc0576ca2007-09-10 17:36:42 +0000364bool LiveVariables::isLive(llvm::BitVector& Live, const VarDecl* D) const {
Ted Kremenek055c2752007-09-06 23:00:42 +0000365 VarInfoMap::const_iterator VI = VarInfos.find(D);
366 assert (VI != VarInfos.end());
367 return Live[VI->second.Idx];
368}
369
Ted Kremenekc0576ca2007-09-10 17:36:42 +0000370bool LiveVariables::KillsVar(const Stmt* S, const VarDecl* D) const {
Ted Kremenek27b07c52007-09-06 21:26:58 +0000371 VarInfoMap::const_iterator VI = VarInfos.find(D);
372 assert (VI != VarInfos.end());
373
374 for (VarInfo::KillsSet::const_iterator
375 I = VI->second.V.Kills.begin(), E = VI->second.V.Kills.end(); I!=E;++I)
376 if (I->first == S)
377 return true;
378
379 return false;
380}
381
Ted Kremenekc0576ca2007-09-10 17:36:42 +0000382LiveVariables::VarInfo& LiveVariables::getVarInfo(const VarDecl* D) {
Ted Kremenek27b07c52007-09-06 21:26:58 +0000383 VarInfoMap::iterator VI = VarInfos.find(D);
384 assert (VI != VarInfos.end());
385 return VI->second.V;
386}
387
Ted Kremenekc0576ca2007-09-10 17:36:42 +0000388const LiveVariables::VarInfo& LiveVariables::getVarInfo(const VarDecl* D) const{
Ted Kremenek27b07c52007-09-06 21:26:58 +0000389 return const_cast<LiveVariables*>(this)->getVarInfo(D);
390}
391
Ted Kremeneke4e63342007-09-06 00:17:54 +0000392//===----------------------------------------------------------------------===//
Ted Kremenekb00c95e2007-09-10 15:56:38 +0000393// Defaults for LiveVariablesObserver
Ted Kremenek055c2752007-09-06 23:00:42 +0000394
Ted Kremenekb00c95e2007-09-10 15:56:38 +0000395void LiveVariablesObserver::ObserveStmt(Stmt* S, LiveVariables& L,
396 llvm::BitVector& V) {}
Ted Kremenek055c2752007-09-06 23:00:42 +0000397
Ted Kremenekb00c95e2007-09-10 15:56:38 +0000398void LiveVariablesObserver::ObserveBlockExit(const CFGBlock* B,
399 LiveVariables& L,
400 llvm::BitVector& V) {}
Ted Kremenek055c2752007-09-06 23:00:42 +0000401
402//===----------------------------------------------------------------------===//
Ted Kremeneke4e63342007-09-06 00:17:54 +0000403// printing liveness state for debugging
404//
405
Ted Kremenek27b07c52007-09-06 21:26:58 +0000406void LiveVariables::dumpLiveness(const llvm::BitVector& V,
407 SourceManager& SM) const {
Ted Kremeneke4e63342007-09-06 00:17:54 +0000408
409 for (VarInfoMap::iterator I = VarInfos.begin(), E=VarInfos.end(); I!=E; ++I) {
410 if (V[I->second.Idx]) {
Ted Kremenek27b07c52007-09-06 21:26:58 +0000411
412 SourceLocation PhysLoc = SM.getPhysicalLoc(I->first->getLocation());
413
414 fprintf(stderr, " %s <%s:%u:%u>\n",
415 I->first->getIdentifier()->getName(),
416 SM.getSourceName(PhysLoc),
417 SM.getLineNumber(PhysLoc),
418 SM.getColumnNumber(PhysLoc));
Ted Kremeneke4e63342007-09-06 00:17:54 +0000419 }
420 }
421}
422
Ted Kremenek27b07c52007-09-06 21:26:58 +0000423void LiveVariables::dumpBlockLiveness(SourceManager& M) const {
Ted Kremeneke4e63342007-09-06 00:17:54 +0000424 for (BlockLivenessMap::iterator I = LiveAtBlockEntryMap.begin(),
425 E = LiveAtBlockEntryMap.end();
426 I != E; ++I) {
Ted Kremeneke4e63342007-09-06 00:17:54 +0000427
Ted Kremenek27b07c52007-09-06 21:26:58 +0000428 fprintf(stderr,
429 "\n[ B%d (live variables at block entry) ]\n",
430 I->first->getBlockID());
431
432 dumpLiveness(I->second,M);
433 }
Ted Kremenekc0576ca2007-09-10 17:36:42 +0000434
435 fprintf(stderr,"\n");
436}
437
438void LiveVariables::dumpVarLiveness(SourceManager& SM) const {
439
440 for (VarInfoMap::iterator I = VarInfos.begin(), E=VarInfos.end(); I!=E; ++I) {
441 SourceLocation PhysLoc = SM.getPhysicalLoc(I->first->getLocation());
442
443 fprintf(stderr, "[ %s <%s:%u:%u> ]\n",
444 I->first->getIdentifier()->getName(),
445 SM.getSourceName(PhysLoc),
446 SM.getLineNumber(PhysLoc),
447 SM.getColumnNumber(PhysLoc));
448
449 I->second.V.Dump(SM);
450 }
451}
452
453void LiveVariables::VarInfo::Dump(SourceManager& SM) const {
454 fprintf(stderr," Blocks Alive:");
455 for (unsigned i = 0; i < AliveBlocks.size(); ++i) {
456 if (i % 5 == 0)
457 fprintf(stderr,"\n ");
458
459 fprintf(stderr," B%d", i);
460 }
461
462 fprintf(stderr,"\n Kill Sites:\n");
463 for (KillsSet::const_iterator I = Kills.begin(), E = Kills.end(); I!=E; ++I) {
464 SourceLocation PhysLoc =
465 SM.getPhysicalLoc(I->second->getSourceRange().Begin());
466
467 fprintf(stderr, " <%s:%u:%u>\n",
468 SM.getSourceName(PhysLoc),
469 SM.getLineNumber(PhysLoc),
470 SM.getColumnNumber(PhysLoc));
471 }
472
473 fprintf(stderr,"\n");
Gabor Greif84675832007-09-11 15:32:40 +0000474}