1*67e74705SXin Li //===- LiveVariables.h - Live Variable Analysis for Source CFGs -*- C++ --*-// 2*67e74705SXin Li // 3*67e74705SXin Li // The LLVM Compiler Infrastructure 4*67e74705SXin Li // 5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source 6*67e74705SXin Li // License. See LICENSE.TXT for details. 7*67e74705SXin Li // 8*67e74705SXin Li //===----------------------------------------------------------------------===// 9*67e74705SXin Li // 10*67e74705SXin Li // This file implements Live Variables analysis for source-level CFGs. 11*67e74705SXin Li // 12*67e74705SXin Li //===----------------------------------------------------------------------===// 13*67e74705SXin Li 14*67e74705SXin Li #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_LIVEVARIABLES_H 15*67e74705SXin Li #define LLVM_CLANG_ANALYSIS_ANALYSES_LIVEVARIABLES_H 16*67e74705SXin Li 17*67e74705SXin Li #include "clang/AST/Decl.h" 18*67e74705SXin Li #include "clang/Analysis/AnalysisContext.h" 19*67e74705SXin Li #include "llvm/ADT/DenseMap.h" 20*67e74705SXin Li #include "llvm/ADT/ImmutableSet.h" 21*67e74705SXin Li 22*67e74705SXin Li namespace clang { 23*67e74705SXin Li 24*67e74705SXin Li class CFG; 25*67e74705SXin Li class CFGBlock; 26*67e74705SXin Li class Stmt; 27*67e74705SXin Li class DeclRefExpr; 28*67e74705SXin Li class SourceManager; 29*67e74705SXin Li 30*67e74705SXin Li class LiveVariables : public ManagedAnalysis { 31*67e74705SXin Li public: 32*67e74705SXin Li class LivenessValues { 33*67e74705SXin Li public: 34*67e74705SXin Li 35*67e74705SXin Li llvm::ImmutableSet<const Stmt *> liveStmts; 36*67e74705SXin Li llvm::ImmutableSet<const VarDecl *> liveDecls; 37*67e74705SXin Li 38*67e74705SXin Li bool equals(const LivenessValues &V) const; 39*67e74705SXin Li LivenessValues()40*67e74705SXin Li LivenessValues() 41*67e74705SXin Li : liveStmts(nullptr), liveDecls(nullptr) {} 42*67e74705SXin Li LivenessValues(llvm::ImmutableSet<const Stmt * > LiveStmts,llvm::ImmutableSet<const VarDecl * > LiveDecls)43*67e74705SXin Li LivenessValues(llvm::ImmutableSet<const Stmt *> LiveStmts, 44*67e74705SXin Li llvm::ImmutableSet<const VarDecl *> LiveDecls) 45*67e74705SXin Li : liveStmts(LiveStmts), liveDecls(LiveDecls) {} 46*67e74705SXin Li 47*67e74705SXin Li bool isLive(const Stmt *S) const; 48*67e74705SXin Li bool isLive(const VarDecl *D) const; 49*67e74705SXin Li 50*67e74705SXin Li friend class LiveVariables; 51*67e74705SXin Li }; 52*67e74705SXin Li 53*67e74705SXin Li class Observer { 54*67e74705SXin Li virtual void anchor(); 55*67e74705SXin Li public: ~Observer()56*67e74705SXin Li virtual ~Observer() {} 57*67e74705SXin Li 58*67e74705SXin Li /// A callback invoked right before invoking the 59*67e74705SXin Li /// liveness transfer function on the given statement. observeStmt(const Stmt * S,const CFGBlock * currentBlock,const LivenessValues & V)60*67e74705SXin Li virtual void observeStmt(const Stmt *S, 61*67e74705SXin Li const CFGBlock *currentBlock, 62*67e74705SXin Li const LivenessValues& V) {} 63*67e74705SXin Li 64*67e74705SXin Li /// Called when the live variables analysis registers 65*67e74705SXin Li /// that a variable is killed. observerKill(const DeclRefExpr * DR)66*67e74705SXin Li virtual void observerKill(const DeclRefExpr *DR) {} 67*67e74705SXin Li }; 68*67e74705SXin Li 69*67e74705SXin Li ~LiveVariables() override; 70*67e74705SXin Li 71*67e74705SXin Li /// Compute the liveness information for a given CFG. 72*67e74705SXin Li static LiveVariables *computeLiveness(AnalysisDeclContext &analysisContext, 73*67e74705SXin Li bool killAtAssign); 74*67e74705SXin Li 75*67e74705SXin Li /// Return true if a variable is live at the end of a 76*67e74705SXin Li /// specified block. 77*67e74705SXin Li bool isLive(const CFGBlock *B, const VarDecl *D); 78*67e74705SXin Li 79*67e74705SXin Li /// Returns true if a variable is live at the beginning of the 80*67e74705SXin Li /// the statement. This query only works if liveness information 81*67e74705SXin Li /// has been recorded at the statement level (see runOnAllBlocks), and 82*67e74705SXin Li /// only returns liveness information for block-level expressions. 83*67e74705SXin Li bool isLive(const Stmt *S, const VarDecl *D); 84*67e74705SXin Li 85*67e74705SXin Li /// Returns true the block-level expression "value" is live 86*67e74705SXin Li /// before the given block-level expression (see runOnAllBlocks). 87*67e74705SXin Li bool isLive(const Stmt *Loc, const Stmt *StmtVal); 88*67e74705SXin Li 89*67e74705SXin Li /// Print to stderr the liveness information associated with 90*67e74705SXin Li /// each basic block. 91*67e74705SXin Li void dumpBlockLiveness(const SourceManager& M); 92*67e74705SXin Li 93*67e74705SXin Li void runOnAllBlocks(Observer &obs); 94*67e74705SXin Li create(AnalysisDeclContext & analysisContext)95*67e74705SXin Li static LiveVariables *create(AnalysisDeclContext &analysisContext) { 96*67e74705SXin Li return computeLiveness(analysisContext, true); 97*67e74705SXin Li } 98*67e74705SXin Li 99*67e74705SXin Li static const void *getTag(); 100*67e74705SXin Li 101*67e74705SXin Li private: 102*67e74705SXin Li LiveVariables(void *impl); 103*67e74705SXin Li void *impl; 104*67e74705SXin Li }; 105*67e74705SXin Li 106*67e74705SXin Li class RelaxedLiveVariables : public LiveVariables { 107*67e74705SXin Li public: create(AnalysisDeclContext & analysisContext)108*67e74705SXin Li static LiveVariables *create(AnalysisDeclContext &analysisContext) { 109*67e74705SXin Li return computeLiveness(analysisContext, false); 110*67e74705SXin Li } 111*67e74705SXin Li 112*67e74705SXin Li static const void *getTag(); 113*67e74705SXin Li }; 114*67e74705SXin Li 115*67e74705SXin Li } // end namespace clang 116*67e74705SXin Li 117*67e74705SXin Li #endif 118