LiveVariables.h revision b1a7b65231e86f7da6aacbf00bcdc16c56350e65
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 45 AnalysisDataTy() : Observer(NULL), AC(NULL) {} 46 }; 47 48 //===-----------------------------------------------------===// 49 // ObserverTy - Observer for uninitialized values queries. 50 //===-----------------------------------------------------===// 51 52 struct ObserverTy { 53 virtual ~ObserverTy() {} 54 55 /// ObserveStmt - A callback invoked right before invoking the 56 /// liveness transfer function on the given statement. 57 virtual void ObserveStmt(Stmt* S, const AnalysisDataTy& AD, 58 const ValTy& V) {} 59 60 virtual void ObserverKill(DeclRefExpr* DR) {} 61 }; 62}; 63 64class LiveVariables : public DataflowValues<LiveVariables_ValueTypes, 65 dataflow::backward_analysis_tag> { 66 67 68public: 69 typedef LiveVariables_ValueTypes::ObserverTy ObserverTy; 70 71 LiveVariables(AnalysisContext &AC); 72 73 /// IsLive - Return true if a variable is live at beginning of a 74 /// specified block. 75 bool isLive(const CFGBlock* B, const VarDecl* D) const; 76 77 /// IsLive - Returns true if a variable is live at the beginning of the 78 /// the statement. This query only works if liveness information 79 /// has been recorded at the statement level (see runOnAllBlocks), and 80 /// only returns liveness information for block-level expressions. 81 bool isLive(const Stmt* S, const VarDecl* D) const; 82 83 /// IsLive - Returns true the block-level expression "value" is live 84 /// before the given block-level expression (see runOnAllBlocks). 85 bool isLive(const Stmt* Loc, const Stmt* StmtVal) const; 86 87 /// IsLive - Return true if a variable is live according to the 88 /// provided livness bitvector. 89 bool isLive(const ValTy& V, const VarDecl* D) const; 90 91 /// dumpLiveness - Print to stderr the liveness information encoded 92 /// by a specified bitvector. 93 void dumpLiveness(const ValTy& V, const SourceManager& M) const; 94 95 /// dumpBlockLiveness - Print to stderr the liveness information 96 /// associated with each basic block. 97 void dumpBlockLiveness(const SourceManager& M) const; 98 99 /// getNumDecls - Return the number of variables (declarations) that 100 /// whose liveness status is being tracked by the dataflow 101 /// analysis. 102 unsigned getNumDecls() const { return getAnalysisData().getNumDecls(); } 103 104 /// IntializeValues - This routine can perform extra initialization, but 105 /// for LiveVariables this does nothing since all that logic is in 106 /// the constructor. 107 void InitializeValues(const CFG& cfg) {} 108 109 void runOnCFG(CFG& cfg); 110 111 /// runOnAllBlocks - Propagate the dataflow values once for each block, 112 /// starting from the current dataflow values. 'recordStmtValues' indicates 113 /// whether the method should store dataflow values per each individual 114 /// block-level expression. 115 void runOnAllBlocks(const CFG& cfg, ObserverTy* Obs, 116 bool recordStmtValues=false); 117}; 118 119} // end namespace clang 120 121#endif 122