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