LiveVariables.h revision 848ec83483ca4ba52ed72c7e29ebc330f8c87252
1//===- LiveVariables.h - Live Variable Analysis for Source CFGs -*- C++ --*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements Live Variables analysis for source-level CFGs. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_LIVEVARIABLES_H 15#define LLVM_CLANG_LIVEVARIABLES_H 16 17#include "clang/AST/Decl.h" 18#include "clang/Analysis/Support/BlkExprDeclBitVector.h" 19#include "clang/Analysis/FlowSensitive/DataflowValues.h" 20 21namespace clang { 22 23class Stmt; 24class DeclRefExpr; 25class SourceManager; 26class AnalysisContext; 27 28struct LiveVariables_ValueTypes { 29 30 struct ObserverTy; 31 32 // We keep dataflow state for declarations and block-level expressions; 33 typedef StmtDeclBitVector_Types::ValTy ValTy; 34 35 // We need to keep track of both declarations and CFGBlock-level expressions, 36 // (so that we don't explore such expressions twice). We also want 37 // to compute liveness information for block-level expressions, since these 38 // act as "temporary" values. 39 40 struct AnalysisDataTy : public StmtDeclBitVector_Types::AnalysisDataTy { 41 ObserverTy* Observer; 42 ValTy AlwaysLive; 43 AnalysisContext *AC; 44 bool killAtAssign; 45 46 AnalysisDataTy() : Observer(NULL), AC(NULL), killAtAssign(true) {} 47 }; 48 49 //===-----------------------------------------------------===// 50 // ObserverTy - Observer for uninitialized values queries. 51 //===-----------------------------------------------------===// 52 53 struct ObserverTy { 54 virtual ~ObserverTy() {} 55 56 /// ObserveStmt - A callback invoked right before invoking the 57 /// liveness transfer function on the given statement. 58 virtual void ObserveStmt(Stmt* S, const CFGBlock *currentBlock, 59 const AnalysisDataTy& AD, 60 const ValTy& V) {} 61 62 virtual void ObserverKill(DeclRefExpr* DR) {} 63 }; 64}; 65 66class LiveVariables : public DataflowValues<LiveVariables_ValueTypes, 67 dataflow::backward_analysis_tag> { 68 69 70public: 71 typedef LiveVariables_ValueTypes::ObserverTy ObserverTy; 72 73 LiveVariables(AnalysisContext &AC, bool killAtAssign = true); 74 75 /// IsLive - Return true if a variable is live at the end of a 76 /// specified block. 77 bool isLive(const CFGBlock* B, const VarDecl* D) const; 78 79 /// IsLive - Returns true if a variable is live at the beginning of the 80 /// the statement. This query only works if liveness information 81 /// has been recorded at the statement level (see runOnAllBlocks), and 82 /// only returns liveness information for block-level expressions. 83 bool isLive(const Stmt* S, const VarDecl* D) const; 84 85 /// IsLive - Returns true the block-level expression "value" is live 86 /// before the given block-level expression (see runOnAllBlocks). 87 bool isLive(const Stmt* Loc, const Stmt* StmtVal) const; 88 89 /// IsLive - Return true if a variable is live according to the 90 /// provided livness bitvector. 91 bool isLive(const ValTy& V, const VarDecl* D) const; 92 93 /// dumpLiveness - Print to stderr the liveness information encoded 94 /// by a specified bitvector. 95 void dumpLiveness(const ValTy& V, const SourceManager& M) const; 96 97 /// dumpBlockLiveness - Print to stderr the liveness information 98 /// associated with each basic block. 99 void dumpBlockLiveness(const SourceManager& M) const; 100 101 /// getNumDecls - Return the number of variables (declarations) that 102 /// whose liveness status is being tracked by the dataflow 103 /// analysis. 104 unsigned getNumDecls() const { return getAnalysisData().getNumDecls(); } 105 106 /// IntializeValues - This routine can perform extra initialization, but 107 /// for LiveVariables this does nothing since all that logic is in 108 /// the constructor. 109 void InitializeValues(const CFG& cfg) {} 110 111 void runOnCFG(CFG& cfg); 112 113 /// runOnAllBlocks - Propagate the dataflow values once for each block, 114 /// starting from the current dataflow values. 'recordStmtValues' indicates 115 /// whether the method should store dataflow values per each individual 116 /// block-level expression. 117 void runOnAllBlocks(const CFG& cfg, ObserverTy* Obs, 118 bool recordStmtValues=false); 119}; 120 121} // end namespace clang 122 123#endif 124