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_ANALYSIS_ANALYSES_LIVEVARIABLES_H
15#define LLVM_CLANG_ANALYSIS_ANALYSES_LIVEVARIABLES_H
16
17#include "clang/AST/Decl.h"
18#include "clang/Analysis/AnalysisDeclContext.h"
19#include "llvm/ADT/ImmutableSet.h"
20
21namespace clang {
22
23class CFG;
24class CFGBlock;
25class Stmt;
26class DeclRefExpr;
27class SourceManager;
28
29class LiveVariables : public ManagedAnalysis {
30public:
31 class LivenessValues {
32 public:
33
34 llvm::ImmutableSet<const Stmt *> liveStmts;
35 llvm::ImmutableSet<const VarDecl *> liveDecls;
36 llvm::ImmutableSet<const BindingDecl *> liveBindings;
37
38 bool equals(const LivenessValues &V) const;
39
40 LivenessValues()
41 : liveStmts(nullptr), liveDecls(nullptr), liveBindings(nullptr) {}
42
43 LivenessValues(llvm::ImmutableSet<const Stmt *> LiveStmts,
44 llvm::ImmutableSet<const VarDecl *> LiveDecls,
45 llvm::ImmutableSet<const BindingDecl *> LiveBindings)
46 : liveStmts(LiveStmts), liveDecls(LiveDecls),
47 liveBindings(LiveBindings) {}
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 ~LiveVariables() override;
72
73 /// Compute the liveness information for a given CFG.
74 static LiveVariables *computeLiveness(AnalysisDeclContext &analysisContext,
75 bool killAtAssign);
76
77 /// Return true if a variable is live at the end of a
78 /// specified block.
79 bool isLive(const CFGBlock *B, const VarDecl *D);
80
81 /// Returns true if a variable is live at the beginning of the
82 /// the statement. This query only works if liveness information
83 /// has been recorded at the statement level (see runOnAllBlocks), and
84 /// only returns liveness information for block-level expressions.
85 bool isLive(const Stmt *S, const VarDecl *D);
86
87 /// Returns true the block-level expression "value" is live
88 /// before the given block-level expression (see runOnAllBlocks).
89 bool isLive(const Stmt *Loc, const Stmt *StmtVal);
90
91 /// Print to stderr the liveness information associated with
92 /// each basic block.
93 void dumpBlockLiveness(const SourceManager& M);
94
95 void runOnAllBlocks(Observer &obs);
96
97 static LiveVariables *create(AnalysisDeclContext &analysisContext) {
98 return computeLiveness(analysisContext, true);
99 }
100
101 static const void *getTag();
102
103private:
104 LiveVariables(void *impl);
105 void *impl;
106};
107
108class RelaxedLiveVariables : public LiveVariables {
109public:
110 static LiveVariables *create(AnalysisDeclContext &analysisContext) {
111 return computeLiveness(analysisContext, false);
112 }
113
114 static const void *getTag();
115};
116
117} // end namespace clang
118
119#endif
120