blob: f81019e2c9f02fb056e52c597204aaf59aee4c49 [file] [log] [blame]
Ted Kremenekcf6e41b2007-12-21 21:42:19 +00001#include "clang/Analysis/Analyses/LiveVariables.h"
Ted Kremenek88299892011-07-28 23:07:59 +00002#include "clang/AST/Stmt.h"
Ted Kremeneke41611a2009-07-16 18:13:04 +00003#include "clang/Analysis/CFG.h"
Ted Kremenek1309f9a2010-01-25 04:41:41 +00004#include "clang/Analysis/AnalysisContext.h"
Ted Kremenek88299892011-07-28 23:07:59 +00005#include "clang/AST/StmtVisitor.h"
6
7#include <deque>
8#include <algorithm>
9#include <vector>
Ted Kremeneke4e63342007-09-06 00:17:54 +000010
11using namespace clang;
12
Ted Kremeneke4e63342007-09-06 00:17:54 +000013namespace {
Ted Kremenek88299892011-07-28 23:07:59 +000014 class LiveVariablesImpl {
15 public:
16 AnalysisContext &analysisContext;
17 std::vector<LiveVariables::LivenessValues> cfgBlockValues;
18 llvm::ImmutableSet<const Stmt *>::Factory SSetFact;
19 llvm::ImmutableSet<const VarDecl *>::Factory DSetFact;
20 llvm::DenseMap<const CFGBlock *, LiveVariables::LivenessValues> blocksEndToLiveness;
21 llvm::DenseMap<const CFGBlock *, LiveVariables::LivenessValues> blocksBeginToLiveness;
22 llvm::DenseMap<const Stmt *, LiveVariables::LivenessValues> stmtsToLiveness;
23 llvm::DenseMap<const DeclRefExpr *, unsigned> inAssignment;
24 const bool killAtAssign;
25
26 LiveVariables::LivenessValues
27 merge(LiveVariables::LivenessValues valsA,
28 LiveVariables::LivenessValues valsB);
29
30 LiveVariables::LivenessValues runOnBlock(const CFGBlock *block,
31 LiveVariables::LivenessValues val,
32 LiveVariables::Observer *obs = 0);
Mike Stump1eb44332009-09-09 15:08:12 +000033
Ted Kremenek88299892011-07-28 23:07:59 +000034 void dumpBlockLiveness(const SourceManager& M);
Mike Stump1eb44332009-09-09 15:08:12 +000035
Ted Kremenek88299892011-07-28 23:07:59 +000036 LiveVariablesImpl(AnalysisContext &ac, bool KillAtAssign)
37 : analysisContext(ac), killAtAssign(KillAtAssign) {}
38 };
39}
Ted Kremenek7deed0c2008-04-15 18:35:30 +000040
Ted Kremenek88299892011-07-28 23:07:59 +000041static LiveVariablesImpl &getImpl(void* x) {
42 return *((LiveVariablesImpl *) x);
Ted Kremenekfdd225e2007-09-25 04:31:27 +000043}
Ted Kremeneke4e63342007-09-06 00:17:54 +000044
45//===----------------------------------------------------------------------===//
Ted Kremenek88299892011-07-28 23:07:59 +000046// Operations and queries on LivenessValues.
47//===----------------------------------------------------------------------===//
48
49bool LiveVariables::LivenessValues::isLive(const Stmt *S) const {
50 return liveStmts.contains(S);
51}
52
53bool LiveVariables::LivenessValues::isLive(const VarDecl *D) const {
54 return liveDecls.contains(D);
55}
56
57namespace {
58 template <typename SET>
59 SET mergeSets(typename SET::Factory &F, SET A, SET B) {
60 for (typename SET::iterator it = B.begin(), ei = B.end(); it != ei; ++it) {
61 A = F.add(A, *it);
62 }
63 return A;
64 }
65}
66
67LiveVariables::LivenessValues
68LiveVariablesImpl::merge(LiveVariables::LivenessValues valsA,
69 LiveVariables::LivenessValues valsB) {
70 return LiveVariables::LivenessValues(mergeSets(SSetFact, valsA.liveStmts, valsB.liveStmts),
71 mergeSets(DSetFact, valsA.liveDecls, valsB.liveDecls));
72}
73
74bool LiveVariables::LivenessValues::equals(const LivenessValues &V) const {
75 return liveStmts == V.liveStmts && liveDecls == V.liveDecls;
76}
77
78//===----------------------------------------------------------------------===//
79// Query methods.
80//===----------------------------------------------------------------------===//
81
82static bool isAlwaysAlive(const VarDecl *D) {
83 return D->hasGlobalStorage();
84}
85
86bool LiveVariables::isLive(const CFGBlock *B, const VarDecl *D) {
87 return isAlwaysAlive(D) || getImpl(impl).blocksEndToLiveness[B].isLive(D);
88}
89
90bool LiveVariables::isLive(const Stmt *S, const VarDecl *D) {
91 return isAlwaysAlive(D) || getImpl(impl).stmtsToLiveness[S].isLive(D);
92}
93
94bool LiveVariables::isLive(const Stmt *Loc, const Stmt *S) {
95 return getImpl(impl).stmtsToLiveness[Loc].isLive(S);
96}
97
98//===----------------------------------------------------------------------===//
99// Dataflow computation.
Mike Stump1eb44332009-09-09 15:08:12 +0000100//===----------------------------------------------------------------------===//
Ted Kremeneke4e63342007-09-06 00:17:54 +0000101
102namespace {
Ted Kremenek88299892011-07-28 23:07:59 +0000103class Worklist {
104 llvm::BitVector isBlockEnqueued;
105 std::deque<const CFGBlock *> workListContents;
106public:
107 Worklist(CFG &cfg) : isBlockEnqueued(cfg.getNumBlockIDs()) {}
108
109 bool empty() const { return workListContents.empty(); }
110
111 const CFGBlock *getNextItem() {
112 const CFGBlock *block = workListContents.front();
113 workListContents.pop_front();
114 isBlockEnqueued[block->getBlockID()] = false;
115 return block;
116 }
117
118 void enqueueBlock(const CFGBlock *block) {
119 if (!isBlockEnqueued[block->getBlockID()]) {
120 isBlockEnqueued[block->getBlockID()] = true;
121 workListContents.push_back(block);
122 }
123 }
124};
125
126class TransferFunctions : public StmtVisitor<TransferFunctions> {
127 LiveVariablesImpl &LV;
128 LiveVariables::LivenessValues &val;
129 LiveVariables::Observer *observer;
Ted Kremenek848ec832011-02-11 23:24:26 +0000130 const CFGBlock *currentBlock;
Ted Kremeneke4e63342007-09-06 00:17:54 +0000131public:
Ted Kremenek88299892011-07-28 23:07:59 +0000132 TransferFunctions(LiveVariablesImpl &im,
133 LiveVariables::LivenessValues &Val,
134 LiveVariables::Observer *Observer,
135 const CFGBlock *CurrentBlock)
136 : LV(im), val(Val), observer(Observer), currentBlock(CurrentBlock) {}
Ted Kremenekfdd225e2007-09-25 04:31:27 +0000137
Ted Kremenek88299892011-07-28 23:07:59 +0000138 void VisitBinaryOperator(BinaryOperator *BO);
139 void VisitBlockExpr(BlockExpr *BE);
140 void VisitDeclRefExpr(DeclRefExpr *DR);
141 void VisitDeclStmt(DeclStmt *DS);
142 void VisitObjCForCollectionStmt(ObjCForCollectionStmt *OS);
143 void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE);
144 void VisitUnaryOperator(UnaryOperator *UO);
Mike Stump1eb44332009-09-09 15:08:12 +0000145 void Visit(Stmt *S);
Ted Kremeneke4e63342007-09-06 00:17:54 +0000146};
Ted Kremenek11e72182007-10-01 20:33:52 +0000147}
Ted Kremenek88299892011-07-28 23:07:59 +0000148
149void TransferFunctions::Visit(Stmt *S) {
150 if (observer)
151 observer->observeStmt(S, currentBlock, val);
Ted Kremenekbfbcefb2009-12-24 02:40:30 +0000152
Ted Kremenek88299892011-07-28 23:07:59 +0000153 StmtVisitor<TransferFunctions>::Visit(S);
Ted Kremenekb1a7b652009-11-26 02:31:33 +0000154
Ted Kremenek88299892011-07-28 23:07:59 +0000155 if (isa<Expr>(S)) {
156 val.liveStmts = LV.SSetFact.remove(val.liveStmts, S);
157 }
158
159 // Mark all children expressions live.
160
161 switch (S->getStmtClass()) {
162 default:
163 break;
164 case Stmt::StmtExprClass: {
165 // For statement expressions, look through the compound statement.
166 S = cast<StmtExpr>(S)->getSubStmt();
167 break;
168 }
169 case Stmt::CXXMemberCallExprClass: {
170 // Include the implicit "this" pointer as being live.
171 CXXMemberCallExpr *CE = cast<CXXMemberCallExpr>(S);
172 val.liveStmts =
173 LV.SSetFact.add(val.liveStmts,
174 CE->getImplicitObjectArgument()->IgnoreParens());
175 break;
176 }
177 // FIXME: These cases eventually shouldn't be needed.
178 case Stmt::ExprWithCleanupsClass: {
179 S = cast<ExprWithCleanups>(S)->getSubExpr();
180 break;
181 }
182 case Stmt::CXXBindTemporaryExprClass: {
183 S = cast<CXXBindTemporaryExpr>(S)->getSubExpr();
184 break;
185 }
186 case Stmt::MaterializeTemporaryExprClass: {
187 S = cast<MaterializeTemporaryExpr>(S)->GetTemporaryExpr();
188 break;
189 }
190 }
191
192 for (Stmt::child_iterator it = S->child_begin(), ei = S->child_end();
193 it != ei; ++it) {
194 if (Stmt *child = *it) {
195 if (Expr *Ex = dyn_cast<Expr>(child))
196 child = Ex->IgnoreParens();
197
198 val.liveStmts = LV.SSetFact.add(val.liveStmts, child);
199 }
Ted Kremenekb1a7b652009-11-26 02:31:33 +0000200 }
Ted Kremeneke4e63342007-09-06 00:17:54 +0000201}
Mike Stump1eb44332009-09-09 15:08:12 +0000202
Ted Kremenek88299892011-07-28 23:07:59 +0000203void TransferFunctions::VisitBinaryOperator(BinaryOperator *B) {
204 if (B->isAssignmentOp()) {
205 if (!LV.killAtAssign)
Ted Kremenek06529ae2008-11-14 21:07:14 +0000206 return;
Ted Kremenek88299892011-07-28 23:07:59 +0000207
208 // Assigning to a variable?
209 Expr *LHS = B->getLHS()->IgnoreParens();
210
211 if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS))
212 if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
213 // Assignments to references don't kill the ref's address
214 if (VD->getType()->isReferenceType())
215 return;
Ted Kremeneke97d9db2008-11-11 19:40:47 +0000216
Ted Kremenek88299892011-07-28 23:07:59 +0000217 if (!isAlwaysAlive(VD)) {
218 // The variable is now dead.
219 val.liveDecls = LV.DSetFact.remove(val.liveDecls, VD);
220 }
Ted Kremenek8f5aab62008-11-11 17:42:10 +0000221
Ted Kremenek88299892011-07-28 23:07:59 +0000222 if (observer)
223 observer->observerKill(DR);
Ted Kremenek56206312008-02-22 00:34:10 +0000224 }
Ted Kremenek27b07c52007-09-06 21:26:58 +0000225 }
226}
Mike Stump1eb44332009-09-09 15:08:12 +0000227
Ted Kremenek88299892011-07-28 23:07:59 +0000228void TransferFunctions::VisitBlockExpr(BlockExpr *BE) {
229 AnalysisContext::referenced_decls_iterator I, E;
230 llvm::tie(I, E) =
231 LV.analysisContext.getReferencedBlockVars(BE->getBlockDecl());
232 for ( ; I != E ; ++I) {
233 const VarDecl *VD = *I;
234 if (isAlwaysAlive(VD))
235 continue;
236 val.liveDecls = LV.DSetFact.add(val.liveDecls, VD);
Ted Kremeneke4e63342007-09-06 00:17:54 +0000237 }
Ted Kremeneke4e63342007-09-06 00:17:54 +0000238}
239
Ted Kremenek88299892011-07-28 23:07:59 +0000240void TransferFunctions::VisitDeclRefExpr(DeclRefExpr *DR) {
241 if (const VarDecl *D = dyn_cast<VarDecl>(DR->getDecl()))
242 if (!isAlwaysAlive(D) && LV.inAssignment.find(DR) == LV.inAssignment.end())
243 val.liveDecls = LV.DSetFact.add(val.liveDecls, D);
244}
245
246void TransferFunctions::VisitDeclStmt(DeclStmt *DS) {
Ted Kremenek14f8b4f2008-08-05 20:46:55 +0000247 for (DeclStmt::decl_iterator DI=DS->decl_begin(), DE = DS->decl_end();
248 DI != DE; ++DI)
249 if (VarDecl* VD = dyn_cast<VarDecl>(*DI)) {
Ted Kremenek88299892011-07-28 23:07:59 +0000250 if (!isAlwaysAlive(VD))
251 val.liveDecls = LV.DSetFact.remove(val.liveDecls, VD);
Ted Kremenekdcc48102008-02-25 22:28:54 +0000252 }
Ted Kremenek27b07c52007-09-06 21:26:58 +0000253}
Mike Stump1eb44332009-09-09 15:08:12 +0000254
Ted Kremenek88299892011-07-28 23:07:59 +0000255void TransferFunctions::VisitObjCForCollectionStmt(ObjCForCollectionStmt *OS) {
256 // Kill the iteration variable.
257 DeclRefExpr *DR = 0;
258 const VarDecl *VD = 0;
Ted Kremeneke4e63342007-09-06 00:17:54 +0000259
Ted Kremenek88299892011-07-28 23:07:59 +0000260 Stmt *element = OS->getElement();
261 if (DeclStmt *DS = dyn_cast<DeclStmt>(element)) {
262 VD = cast<VarDecl>(DS->getSingleDecl());
263 }
264 else if ((DR = dyn_cast<DeclRefExpr>(cast<Expr>(element)->IgnoreParens()))) {
265 VD = cast<VarDecl>(DR->getDecl());
266 }
267
268 if (VD) {
269 val.liveDecls = LV.DSetFact.remove(val.liveDecls, VD);
270 if (observer && DR)
271 observer->observerKill(DR);
272 }
Ted Kremenekfdd225e2007-09-25 04:31:27 +0000273}
Ted Kremenek27b07c52007-09-06 21:26:58 +0000274
Ted Kremenek88299892011-07-28 23:07:59 +0000275void TransferFunctions::
276VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE)
277{
278 // While sizeof(var) doesn't technically extend the liveness of 'var', it
279 // does extent the liveness of metadata if 'var' is a VariableArrayType.
280 // We handle that special case here.
281 if (UE->getKind() != UETT_SizeOf || UE->isArgumentType())
282 return;
283
284 const DeclRefExpr *DR =
285 dyn_cast<DeclRefExpr>(UE->getArgumentExpr()->IgnoreParens());
286
287 if (!DR)
288 return;
289
290 const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
291
292 if (VD && VD->getType()->isVariableArrayType())
293 val.liveDecls = LV.DSetFact.add(val.liveDecls, VD);
Ted Kremenek27b07c52007-09-06 21:26:58 +0000294}
295
Ted Kremenek88299892011-07-28 23:07:59 +0000296void TransferFunctions::VisitUnaryOperator(UnaryOperator *UO) {
297 // Treat ++/-- as a kill.
298 // Note we don't actually have to do anything if we don't have an observer,
299 // since a ++/-- acts as both a kill and a "use".
300 if (!observer)
301 return;
302
303 switch (UO->getOpcode()) {
304 default:
305 return;
306 case UO_PostInc:
307 case UO_PostDec:
308 case UO_PreInc:
309 case UO_PreDec:
310 break;
311 }
312
313 if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(UO->getSubExpr()->IgnoreParens()))
314 if (isa<VarDecl>(DR->getDecl())) {
315 // Treat ++/-- as a kill.
316 observer->observerKill(DR);
317 }
Ted Kremenek27b07c52007-09-06 21:26:58 +0000318}
319
Ted Kremenek88299892011-07-28 23:07:59 +0000320LiveVariables::LivenessValues
321LiveVariablesImpl::runOnBlock(const CFGBlock *block,
322 LiveVariables::LivenessValues val,
323 LiveVariables::Observer *obs) {
324
325 TransferFunctions TF(*this, val, obs, block);
326
327 // Visit the terminator (if any).
328 if (const Stmt *term = block->getTerminator())
329 TF.Visit(const_cast<Stmt*>(term));
330
331 // Apply the transfer function for all Stmts in the block.
332 for (CFGBlock::const_reverse_iterator it = block->rbegin(),
333 ei = block->rend(); it != ei; ++it) {
334 const CFGElement &elem = *it;
335 if (!isa<CFGStmt>(elem))
336 continue;
337
338 const Stmt *S = cast<CFGStmt>(elem).getStmt();
339 TF.Visit(const_cast<Stmt*>(S));
340 stmtsToLiveness[S] = val;
341 }
342 return val;
Ted Kremenek055c2752007-09-06 23:00:42 +0000343}
344
Ted Kremenek88299892011-07-28 23:07:59 +0000345void LiveVariables::runOnAllBlocks(LiveVariables::Observer &obs) {
346 const CFG *cfg = getImpl(impl).analysisContext.getCFG();
347 for (CFG::const_iterator it = cfg->begin(), ei = cfg->end(); it != ei; ++it)
348 getImpl(impl).runOnBlock(*it, getImpl(impl).blocksEndToLiveness[*it], &obs);
Ted Kremenek86946742008-01-17 20:48:37 +0000349}
350
Ted Kremenek88299892011-07-28 23:07:59 +0000351LiveVariables::LiveVariables(void *im) : impl(im) {}
352
353LiveVariables::~LiveVariables() {
354 delete (LiveVariablesImpl*) impl;
Ted Kremenek2a9da9c2008-01-18 00:40:21 +0000355}
356
Ted Kremenek88299892011-07-28 23:07:59 +0000357LiveVariables *
358LiveVariables::computeLiveness(AnalysisContext &AC,
359 bool killAtAssign) {
Ted Kremeneke4e63342007-09-06 00:17:54 +0000360
Ted Kremenek88299892011-07-28 23:07:59 +0000361 // No CFG? Bail out.
362 CFG *cfg = AC.getCFG();
363 if (!cfg)
364 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +0000365
Ted Kremenek88299892011-07-28 23:07:59 +0000366 LiveVariablesImpl *LV = new LiveVariablesImpl(AC, killAtAssign);
367
368 // Construct the dataflow worklist. Enqueue the exit block as the
369 // start of the analysis.
370 Worklist worklist(*cfg);
371 llvm::BitVector everAnalyzedBlock(cfg->getNumBlockIDs());
372
373 // FIXME: we should enqueue using post order.
374 for (CFG::const_iterator it = cfg->begin(), ei = cfg->end(); it != ei; ++it) {
375 const CFGBlock *block = *it;
376 worklist.enqueueBlock(block);
377
378 // FIXME: Scan for DeclRefExprs using in the LHS of an assignment.
379 // We need to do this because we lack context in the reverse analysis
380 // to determine if a DeclRefExpr appears in such a context, and thus
381 // doesn't constitute a "use".
382 if (killAtAssign)
383 for (CFGBlock::const_iterator bi = block->begin(), be = block->end();
384 bi != be; ++bi) {
385 if (const CFGStmt *cs = bi->getAs<CFGStmt>()) {
386 if (BinaryOperator *BO = dyn_cast<BinaryOperator>(cs->getStmt())) {
387 if (BO->getOpcode() == BO_Assign) {
388 if (const DeclRefExpr *DR =
389 dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens())) {
390 LV->inAssignment[DR] = 1;
391 }
392 }
393 }
394 }
395 }
396 }
397
398 while (!worklist.empty()) {
399 // Dequeue blocks in FIFO order.
400 const CFGBlock *block = worklist.getNextItem();
401
402 // Determine if the block's end value has changed. If not, we
403 // have nothing left to do for this block.
404 LivenessValues &prevVal = LV->blocksEndToLiveness[block];
405
406 // Merge the values of all successor blocks.
407 LivenessValues val;
408 for (CFGBlock::const_succ_iterator it = block->succ_begin(),
409 ei = block->succ_end(); it != ei; ++it) {
410 if (const CFGBlock *succ = *it)
411 val = LV->merge(val, LV->blocksBeginToLiveness[succ]);
412 }
413
414 if (!everAnalyzedBlock[block->getBlockID()])
415 everAnalyzedBlock[block->getBlockID()] = true;
416 else if (prevVal.equals(val))
417 continue;
418
419 prevVal = val;
420
421 // Update the dataflow value for the start of this block.
422 LV->blocksBeginToLiveness[block] = LV->runOnBlock(block, val);
423
424 // Enqueue the value to the predecessors.
425 for (CFGBlock::const_pred_iterator it = block->pred_begin(),
426 ei = block->pred_end(); it != ei; ++it)
427 {
428 if (const CFGBlock *pred = *it)
429 worklist.enqueueBlock(pred);
430 }
431 }
432
433 return new LiveVariables(LV);
434}
435
436bool compare_entries(const CFGBlock *A, const CFGBlock *B) {
437 return A->getBlockID() < B->getBlockID();
438}
439bool compare_vd_entries(const Decl *A, const Decl *B) {
440 SourceLocation ALoc = A->getLocStart();
441 SourceLocation BLoc = B->getLocStart();
442 return ALoc.getRawEncoding() < BLoc.getRawEncoding();
443}
444
445void LiveVariables::dumpBlockLiveness(const SourceManager &M) {
446 getImpl(impl).dumpBlockLiveness(M);
447}
448
449void LiveVariablesImpl::dumpBlockLiveness(const SourceManager &M) {
450 std::vector<const CFGBlock *> vec;
451 for (llvm::DenseMap<const CFGBlock *, LiveVariables::LivenessValues>::iterator
452 it = blocksEndToLiveness.begin(), ei = blocksEndToLiveness.end();
453 it != ei; ++it) {
454 vec.push_back(it->first);
455 }
456 std::sort(vec.begin(), vec.end(), compare_entries);
457
458 std::vector<const VarDecl*> declVec;
459
460 for (std::vector<const CFGBlock *>::iterator
461 it = vec.begin(), ei = vec.end(); it != ei; ++it) {
462 llvm::errs() << "\n[ B" << (*it)->getBlockID()
463 << " (live variables at block exit) ]\n";
464
465 LiveVariables::LivenessValues vals = blocksEndToLiveness[*it];
466 declVec.clear();
467
468 for (llvm::ImmutableSet<const VarDecl *>::iterator si =
469 vals.liveDecls.begin(),
470 se = vals.liveDecls.end(); si != se; ++si) {
471 declVec.push_back(*si);
472 }
473
474 std::sort(declVec.begin(), declVec.end(), compare_vd_entries);
475
476 for (std::vector<const VarDecl*>::iterator di = declVec.begin(),
477 de = declVec.end(); di != de; ++di) {
478 llvm::errs() << " " << (*di)->getDeclName().getAsString()
479 << " <";
480 (*di)->getLocation().dump(M);
Daniel Dunbarc0d56722009-10-17 18:12:37 +0000481 llvm::errs() << ">\n";
Ted Kremeneke4e63342007-09-06 00:17:54 +0000482 }
Ted Kremenek27b07c52007-09-06 21:26:58 +0000483 }
Ted Kremenek88299892011-07-28 23:07:59 +0000484 llvm::errs() << "\n";
Ted Kremenekc0576ca2007-09-10 17:36:42 +0000485}
Ted Kremenek88299892011-07-28 23:07:59 +0000486