xref: /minix3/external/bsd/llvm/dist/clang/lib/Analysis/LiveVariables.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //=- LiveVariables.cpp - Live Variable Analysis for Source CFGs ----------*-==//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file implements Live Variables analysis for source-level CFGs.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc 
14f4a2713aSLionel Sambuc #include "clang/Analysis/Analyses/LiveVariables.h"
15f4a2713aSLionel Sambuc #include "clang/AST/Stmt.h"
16f4a2713aSLionel Sambuc #include "clang/AST/StmtVisitor.h"
17f4a2713aSLionel Sambuc #include "clang/Analysis/Analyses/PostOrderCFGView.h"
18f4a2713aSLionel Sambuc #include "clang/Analysis/AnalysisContext.h"
19f4a2713aSLionel Sambuc #include "clang/Analysis/CFG.h"
20f4a2713aSLionel Sambuc #include "llvm/ADT/DenseMap.h"
21f4a2713aSLionel Sambuc #include "llvm/ADT/PostOrderIterator.h"
22f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
23f4a2713aSLionel Sambuc #include <algorithm>
24f4a2713aSLionel Sambuc #include <vector>
25f4a2713aSLionel Sambuc 
26f4a2713aSLionel Sambuc using namespace clang;
27f4a2713aSLionel Sambuc 
28f4a2713aSLionel Sambuc namespace {
29f4a2713aSLionel Sambuc 
30f4a2713aSLionel Sambuc class DataflowWorklist {
31f4a2713aSLionel Sambuc   SmallVector<const CFGBlock *, 20> worklist;
32f4a2713aSLionel Sambuc   llvm::BitVector enqueuedBlocks;
33f4a2713aSLionel Sambuc   PostOrderCFGView *POV;
34f4a2713aSLionel Sambuc public:
DataflowWorklist(const CFG & cfg,AnalysisDeclContext & Ctx)35f4a2713aSLionel Sambuc   DataflowWorklist(const CFG &cfg, AnalysisDeclContext &Ctx)
36f4a2713aSLionel Sambuc     : enqueuedBlocks(cfg.getNumBlockIDs()),
37f4a2713aSLionel Sambuc       POV(Ctx.getAnalysis<PostOrderCFGView>()) {}
38f4a2713aSLionel Sambuc 
39f4a2713aSLionel Sambuc   void enqueueBlock(const CFGBlock *block);
40f4a2713aSLionel Sambuc   void enqueuePredecessors(const CFGBlock *block);
41f4a2713aSLionel Sambuc 
42f4a2713aSLionel Sambuc   const CFGBlock *dequeue();
43f4a2713aSLionel Sambuc 
44f4a2713aSLionel Sambuc   void sortWorklist();
45f4a2713aSLionel Sambuc };
46f4a2713aSLionel Sambuc 
47f4a2713aSLionel Sambuc }
48f4a2713aSLionel Sambuc 
enqueueBlock(const clang::CFGBlock * block)49f4a2713aSLionel Sambuc void DataflowWorklist::enqueueBlock(const clang::CFGBlock *block) {
50f4a2713aSLionel Sambuc   if (block && !enqueuedBlocks[block->getBlockID()]) {
51f4a2713aSLionel Sambuc     enqueuedBlocks[block->getBlockID()] = true;
52f4a2713aSLionel Sambuc     worklist.push_back(block);
53f4a2713aSLionel Sambuc   }
54f4a2713aSLionel Sambuc }
55f4a2713aSLionel Sambuc 
enqueuePredecessors(const clang::CFGBlock * block)56f4a2713aSLionel Sambuc void DataflowWorklist::enqueuePredecessors(const clang::CFGBlock *block) {
57f4a2713aSLionel Sambuc   const unsigned OldWorklistSize = worklist.size();
58f4a2713aSLionel Sambuc   for (CFGBlock::const_pred_iterator I = block->pred_begin(),
59f4a2713aSLionel Sambuc        E = block->pred_end(); I != E; ++I) {
60f4a2713aSLionel Sambuc     enqueueBlock(*I);
61f4a2713aSLionel Sambuc   }
62f4a2713aSLionel Sambuc 
63f4a2713aSLionel Sambuc   if (OldWorklistSize == 0 || OldWorklistSize == worklist.size())
64f4a2713aSLionel Sambuc     return;
65f4a2713aSLionel Sambuc 
66f4a2713aSLionel Sambuc   sortWorklist();
67f4a2713aSLionel Sambuc }
68f4a2713aSLionel Sambuc 
sortWorklist()69f4a2713aSLionel Sambuc void DataflowWorklist::sortWorklist() {
70f4a2713aSLionel Sambuc   std::sort(worklist.begin(), worklist.end(), POV->getComparator());
71f4a2713aSLionel Sambuc }
72f4a2713aSLionel Sambuc 
dequeue()73f4a2713aSLionel Sambuc const CFGBlock *DataflowWorklist::dequeue() {
74f4a2713aSLionel Sambuc   if (worklist.empty())
75*0a6a1f1dSLionel Sambuc     return nullptr;
76f4a2713aSLionel Sambuc   const CFGBlock *b = worklist.pop_back_val();
77f4a2713aSLionel Sambuc   enqueuedBlocks[b->getBlockID()] = false;
78f4a2713aSLionel Sambuc   return b;
79f4a2713aSLionel Sambuc }
80f4a2713aSLionel Sambuc 
81f4a2713aSLionel Sambuc namespace {
82f4a2713aSLionel Sambuc class LiveVariablesImpl {
83f4a2713aSLionel Sambuc public:
84f4a2713aSLionel Sambuc   AnalysisDeclContext &analysisContext;
85f4a2713aSLionel Sambuc   llvm::ImmutableSet<const Stmt *>::Factory SSetFact;
86f4a2713aSLionel Sambuc   llvm::ImmutableSet<const VarDecl *>::Factory DSetFact;
87f4a2713aSLionel Sambuc   llvm::DenseMap<const CFGBlock *, LiveVariables::LivenessValues> blocksEndToLiveness;
88f4a2713aSLionel Sambuc   llvm::DenseMap<const CFGBlock *, LiveVariables::LivenessValues> blocksBeginToLiveness;
89f4a2713aSLionel Sambuc   llvm::DenseMap<const Stmt *, LiveVariables::LivenessValues> stmtsToLiveness;
90f4a2713aSLionel Sambuc   llvm::DenseMap<const DeclRefExpr *, unsigned> inAssignment;
91f4a2713aSLionel Sambuc   const bool killAtAssign;
92f4a2713aSLionel Sambuc 
93f4a2713aSLionel Sambuc   LiveVariables::LivenessValues
94f4a2713aSLionel Sambuc   merge(LiveVariables::LivenessValues valsA,
95f4a2713aSLionel Sambuc         LiveVariables::LivenessValues valsB);
96f4a2713aSLionel Sambuc 
97*0a6a1f1dSLionel Sambuc   LiveVariables::LivenessValues
98*0a6a1f1dSLionel Sambuc   runOnBlock(const CFGBlock *block, LiveVariables::LivenessValues val,
99*0a6a1f1dSLionel Sambuc              LiveVariables::Observer *obs = nullptr);
100f4a2713aSLionel Sambuc 
101f4a2713aSLionel Sambuc   void dumpBlockLiveness(const SourceManager& M);
102f4a2713aSLionel Sambuc 
LiveVariablesImpl(AnalysisDeclContext & ac,bool KillAtAssign)103f4a2713aSLionel Sambuc   LiveVariablesImpl(AnalysisDeclContext &ac, bool KillAtAssign)
104f4a2713aSLionel Sambuc     : analysisContext(ac),
105f4a2713aSLionel Sambuc       SSetFact(false), // Do not canonicalize ImmutableSets by default.
106f4a2713aSLionel Sambuc       DSetFact(false), // This is a *major* performance win.
107f4a2713aSLionel Sambuc       killAtAssign(KillAtAssign) {}
108f4a2713aSLionel Sambuc };
109f4a2713aSLionel Sambuc }
110f4a2713aSLionel Sambuc 
getImpl(void * x)111f4a2713aSLionel Sambuc static LiveVariablesImpl &getImpl(void *x) {
112f4a2713aSLionel Sambuc   return *((LiveVariablesImpl *) x);
113f4a2713aSLionel Sambuc }
114f4a2713aSLionel Sambuc 
115f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
116f4a2713aSLionel Sambuc // Operations and queries on LivenessValues.
117f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
118f4a2713aSLionel Sambuc 
isLive(const Stmt * S) const119f4a2713aSLionel Sambuc bool LiveVariables::LivenessValues::isLive(const Stmt *S) const {
120f4a2713aSLionel Sambuc   return liveStmts.contains(S);
121f4a2713aSLionel Sambuc }
122f4a2713aSLionel Sambuc 
isLive(const VarDecl * D) const123f4a2713aSLionel Sambuc bool LiveVariables::LivenessValues::isLive(const VarDecl *D) const {
124f4a2713aSLionel Sambuc   return liveDecls.contains(D);
125f4a2713aSLionel Sambuc }
126f4a2713aSLionel Sambuc 
127f4a2713aSLionel Sambuc namespace {
128f4a2713aSLionel Sambuc   template <typename SET>
mergeSets(SET A,SET B)129f4a2713aSLionel Sambuc   SET mergeSets(SET A, SET B) {
130f4a2713aSLionel Sambuc     if (A.isEmpty())
131f4a2713aSLionel Sambuc       return B;
132f4a2713aSLionel Sambuc 
133f4a2713aSLionel Sambuc     for (typename SET::iterator it = B.begin(), ei = B.end(); it != ei; ++it) {
134f4a2713aSLionel Sambuc       A = A.add(*it);
135f4a2713aSLionel Sambuc     }
136f4a2713aSLionel Sambuc     return A;
137f4a2713aSLionel Sambuc   }
138f4a2713aSLionel Sambuc }
139f4a2713aSLionel Sambuc 
anchor()140f4a2713aSLionel Sambuc void LiveVariables::Observer::anchor() { }
141f4a2713aSLionel Sambuc 
142f4a2713aSLionel Sambuc LiveVariables::LivenessValues
merge(LiveVariables::LivenessValues valsA,LiveVariables::LivenessValues valsB)143f4a2713aSLionel Sambuc LiveVariablesImpl::merge(LiveVariables::LivenessValues valsA,
144f4a2713aSLionel Sambuc                          LiveVariables::LivenessValues valsB) {
145f4a2713aSLionel Sambuc 
146f4a2713aSLionel Sambuc   llvm::ImmutableSetRef<const Stmt *>
147f4a2713aSLionel Sambuc     SSetRefA(valsA.liveStmts.getRootWithoutRetain(), SSetFact.getTreeFactory()),
148f4a2713aSLionel Sambuc     SSetRefB(valsB.liveStmts.getRootWithoutRetain(), SSetFact.getTreeFactory());
149f4a2713aSLionel Sambuc 
150f4a2713aSLionel Sambuc 
151f4a2713aSLionel Sambuc   llvm::ImmutableSetRef<const VarDecl *>
152f4a2713aSLionel Sambuc     DSetRefA(valsA.liveDecls.getRootWithoutRetain(), DSetFact.getTreeFactory()),
153f4a2713aSLionel Sambuc     DSetRefB(valsB.liveDecls.getRootWithoutRetain(), DSetFact.getTreeFactory());
154f4a2713aSLionel Sambuc 
155f4a2713aSLionel Sambuc 
156f4a2713aSLionel Sambuc   SSetRefA = mergeSets(SSetRefA, SSetRefB);
157f4a2713aSLionel Sambuc   DSetRefA = mergeSets(DSetRefA, DSetRefB);
158f4a2713aSLionel Sambuc 
159f4a2713aSLionel Sambuc   // asImmutableSet() canonicalizes the tree, allowing us to do an easy
160f4a2713aSLionel Sambuc   // comparison afterwards.
161f4a2713aSLionel Sambuc   return LiveVariables::LivenessValues(SSetRefA.asImmutableSet(),
162f4a2713aSLionel Sambuc                                        DSetRefA.asImmutableSet());
163f4a2713aSLionel Sambuc }
164f4a2713aSLionel Sambuc 
equals(const LivenessValues & V) const165f4a2713aSLionel Sambuc bool LiveVariables::LivenessValues::equals(const LivenessValues &V) const {
166f4a2713aSLionel Sambuc   return liveStmts == V.liveStmts && liveDecls == V.liveDecls;
167f4a2713aSLionel Sambuc }
168f4a2713aSLionel Sambuc 
169f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
170f4a2713aSLionel Sambuc // Query methods.
171f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
172f4a2713aSLionel Sambuc 
isAlwaysAlive(const VarDecl * D)173f4a2713aSLionel Sambuc static bool isAlwaysAlive(const VarDecl *D) {
174f4a2713aSLionel Sambuc   return D->hasGlobalStorage();
175f4a2713aSLionel Sambuc }
176f4a2713aSLionel Sambuc 
isLive(const CFGBlock * B,const VarDecl * D)177f4a2713aSLionel Sambuc bool LiveVariables::isLive(const CFGBlock *B, const VarDecl *D) {
178f4a2713aSLionel Sambuc   return isAlwaysAlive(D) || getImpl(impl).blocksEndToLiveness[B].isLive(D);
179f4a2713aSLionel Sambuc }
180f4a2713aSLionel Sambuc 
isLive(const Stmt * S,const VarDecl * D)181f4a2713aSLionel Sambuc bool LiveVariables::isLive(const Stmt *S, const VarDecl *D) {
182f4a2713aSLionel Sambuc   return isAlwaysAlive(D) || getImpl(impl).stmtsToLiveness[S].isLive(D);
183f4a2713aSLionel Sambuc }
184f4a2713aSLionel Sambuc 
isLive(const Stmt * Loc,const Stmt * S)185f4a2713aSLionel Sambuc bool LiveVariables::isLive(const Stmt *Loc, const Stmt *S) {
186f4a2713aSLionel Sambuc   return getImpl(impl).stmtsToLiveness[Loc].isLive(S);
187f4a2713aSLionel Sambuc }
188f4a2713aSLionel Sambuc 
189f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
190f4a2713aSLionel Sambuc // Dataflow computation.
191f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
192f4a2713aSLionel Sambuc 
193f4a2713aSLionel Sambuc namespace {
194f4a2713aSLionel Sambuc class TransferFunctions : public StmtVisitor<TransferFunctions> {
195f4a2713aSLionel Sambuc   LiveVariablesImpl &LV;
196f4a2713aSLionel Sambuc   LiveVariables::LivenessValues &val;
197f4a2713aSLionel Sambuc   LiveVariables::Observer *observer;
198f4a2713aSLionel Sambuc   const CFGBlock *currentBlock;
199f4a2713aSLionel Sambuc public:
TransferFunctions(LiveVariablesImpl & im,LiveVariables::LivenessValues & Val,LiveVariables::Observer * Observer,const CFGBlock * CurrentBlock)200f4a2713aSLionel Sambuc   TransferFunctions(LiveVariablesImpl &im,
201f4a2713aSLionel Sambuc                     LiveVariables::LivenessValues &Val,
202f4a2713aSLionel Sambuc                     LiveVariables::Observer *Observer,
203f4a2713aSLionel Sambuc                     const CFGBlock *CurrentBlock)
204f4a2713aSLionel Sambuc   : LV(im), val(Val), observer(Observer), currentBlock(CurrentBlock) {}
205f4a2713aSLionel Sambuc 
206f4a2713aSLionel Sambuc   void VisitBinaryOperator(BinaryOperator *BO);
207f4a2713aSLionel Sambuc   void VisitBlockExpr(BlockExpr *BE);
208f4a2713aSLionel Sambuc   void VisitDeclRefExpr(DeclRefExpr *DR);
209f4a2713aSLionel Sambuc   void VisitDeclStmt(DeclStmt *DS);
210f4a2713aSLionel Sambuc   void VisitObjCForCollectionStmt(ObjCForCollectionStmt *OS);
211f4a2713aSLionel Sambuc   void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE);
212f4a2713aSLionel Sambuc   void VisitUnaryOperator(UnaryOperator *UO);
213f4a2713aSLionel Sambuc   void Visit(Stmt *S);
214f4a2713aSLionel Sambuc };
215f4a2713aSLionel Sambuc }
216f4a2713aSLionel Sambuc 
FindVA(QualType Ty)217f4a2713aSLionel Sambuc static const VariableArrayType *FindVA(QualType Ty) {
218f4a2713aSLionel Sambuc   const Type *ty = Ty.getTypePtr();
219f4a2713aSLionel Sambuc   while (const ArrayType *VT = dyn_cast<ArrayType>(ty)) {
220f4a2713aSLionel Sambuc     if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(VT))
221f4a2713aSLionel Sambuc       if (VAT->getSizeExpr())
222f4a2713aSLionel Sambuc         return VAT;
223f4a2713aSLionel Sambuc 
224f4a2713aSLionel Sambuc     ty = VT->getElementType().getTypePtr();
225f4a2713aSLionel Sambuc   }
226f4a2713aSLionel Sambuc 
227*0a6a1f1dSLionel Sambuc   return nullptr;
228f4a2713aSLionel Sambuc }
229f4a2713aSLionel Sambuc 
LookThroughStmt(const Stmt * S)230f4a2713aSLionel Sambuc static const Stmt *LookThroughStmt(const Stmt *S) {
231f4a2713aSLionel Sambuc   while (S) {
232f4a2713aSLionel Sambuc     if (const Expr *Ex = dyn_cast<Expr>(S))
233f4a2713aSLionel Sambuc       S = Ex->IgnoreParens();
234f4a2713aSLionel Sambuc     if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(S)) {
235f4a2713aSLionel Sambuc       S = EWC->getSubExpr();
236f4a2713aSLionel Sambuc       continue;
237f4a2713aSLionel Sambuc     }
238f4a2713aSLionel Sambuc     if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(S)) {
239f4a2713aSLionel Sambuc       S = OVE->getSourceExpr();
240f4a2713aSLionel Sambuc       continue;
241f4a2713aSLionel Sambuc     }
242f4a2713aSLionel Sambuc     break;
243f4a2713aSLionel Sambuc   }
244f4a2713aSLionel Sambuc   return S;
245f4a2713aSLionel Sambuc }
246f4a2713aSLionel Sambuc 
AddLiveStmt(llvm::ImmutableSet<const Stmt * > & Set,llvm::ImmutableSet<const Stmt * >::Factory & F,const Stmt * S)247f4a2713aSLionel Sambuc static void AddLiveStmt(llvm::ImmutableSet<const Stmt *> &Set,
248f4a2713aSLionel Sambuc                         llvm::ImmutableSet<const Stmt *>::Factory &F,
249f4a2713aSLionel Sambuc                         const Stmt *S) {
250f4a2713aSLionel Sambuc   Set = F.add(Set, LookThroughStmt(S));
251f4a2713aSLionel Sambuc }
252f4a2713aSLionel Sambuc 
Visit(Stmt * S)253f4a2713aSLionel Sambuc void TransferFunctions::Visit(Stmt *S) {
254f4a2713aSLionel Sambuc   if (observer)
255f4a2713aSLionel Sambuc     observer->observeStmt(S, currentBlock, val);
256f4a2713aSLionel Sambuc 
257f4a2713aSLionel Sambuc   StmtVisitor<TransferFunctions>::Visit(S);
258f4a2713aSLionel Sambuc 
259f4a2713aSLionel Sambuc   if (isa<Expr>(S)) {
260f4a2713aSLionel Sambuc     val.liveStmts = LV.SSetFact.remove(val.liveStmts, S);
261f4a2713aSLionel Sambuc   }
262f4a2713aSLionel Sambuc 
263f4a2713aSLionel Sambuc   // Mark all children expressions live.
264f4a2713aSLionel Sambuc 
265f4a2713aSLionel Sambuc   switch (S->getStmtClass()) {
266f4a2713aSLionel Sambuc     default:
267f4a2713aSLionel Sambuc       break;
268f4a2713aSLionel Sambuc     case Stmt::StmtExprClass: {
269f4a2713aSLionel Sambuc       // For statement expressions, look through the compound statement.
270f4a2713aSLionel Sambuc       S = cast<StmtExpr>(S)->getSubStmt();
271f4a2713aSLionel Sambuc       break;
272f4a2713aSLionel Sambuc     }
273f4a2713aSLionel Sambuc     case Stmt::CXXMemberCallExprClass: {
274f4a2713aSLionel Sambuc       // Include the implicit "this" pointer as being live.
275f4a2713aSLionel Sambuc       CXXMemberCallExpr *CE = cast<CXXMemberCallExpr>(S);
276f4a2713aSLionel Sambuc       if (Expr *ImplicitObj = CE->getImplicitObjectArgument()) {
277f4a2713aSLionel Sambuc         AddLiveStmt(val.liveStmts, LV.SSetFact, ImplicitObj);
278f4a2713aSLionel Sambuc       }
279f4a2713aSLionel Sambuc       break;
280f4a2713aSLionel Sambuc     }
281f4a2713aSLionel Sambuc     case Stmt::ObjCMessageExprClass: {
282f4a2713aSLionel Sambuc       // In calls to super, include the implicit "self" pointer as being live.
283f4a2713aSLionel Sambuc       ObjCMessageExpr *CE = cast<ObjCMessageExpr>(S);
284f4a2713aSLionel Sambuc       if (CE->getReceiverKind() == ObjCMessageExpr::SuperInstance)
285f4a2713aSLionel Sambuc         val.liveDecls = LV.DSetFact.add(val.liveDecls,
286f4a2713aSLionel Sambuc                                         LV.analysisContext.getSelfDecl());
287f4a2713aSLionel Sambuc       break;
288f4a2713aSLionel Sambuc     }
289f4a2713aSLionel Sambuc     case Stmt::DeclStmtClass: {
290f4a2713aSLionel Sambuc       const DeclStmt *DS = cast<DeclStmt>(S);
291f4a2713aSLionel Sambuc       if (const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl())) {
292f4a2713aSLionel Sambuc         for (const VariableArrayType* VA = FindVA(VD->getType());
293*0a6a1f1dSLionel Sambuc              VA != nullptr; VA = FindVA(VA->getElementType())) {
294f4a2713aSLionel Sambuc           AddLiveStmt(val.liveStmts, LV.SSetFact, VA->getSizeExpr());
295f4a2713aSLionel Sambuc         }
296f4a2713aSLionel Sambuc       }
297f4a2713aSLionel Sambuc       break;
298f4a2713aSLionel Sambuc     }
299f4a2713aSLionel Sambuc     case Stmt::PseudoObjectExprClass: {
300f4a2713aSLionel Sambuc       // A pseudo-object operation only directly consumes its result
301f4a2713aSLionel Sambuc       // expression.
302f4a2713aSLionel Sambuc       Expr *child = cast<PseudoObjectExpr>(S)->getResultExpr();
303f4a2713aSLionel Sambuc       if (!child) return;
304f4a2713aSLionel Sambuc       if (OpaqueValueExpr *OV = dyn_cast<OpaqueValueExpr>(child))
305f4a2713aSLionel Sambuc         child = OV->getSourceExpr();
306f4a2713aSLionel Sambuc       child = child->IgnoreParens();
307f4a2713aSLionel Sambuc       val.liveStmts = LV.SSetFact.add(val.liveStmts, child);
308f4a2713aSLionel Sambuc       return;
309f4a2713aSLionel Sambuc     }
310f4a2713aSLionel Sambuc 
311f4a2713aSLionel Sambuc     // FIXME: These cases eventually shouldn't be needed.
312f4a2713aSLionel Sambuc     case Stmt::ExprWithCleanupsClass: {
313f4a2713aSLionel Sambuc       S = cast<ExprWithCleanups>(S)->getSubExpr();
314f4a2713aSLionel Sambuc       break;
315f4a2713aSLionel Sambuc     }
316f4a2713aSLionel Sambuc     case Stmt::CXXBindTemporaryExprClass: {
317f4a2713aSLionel Sambuc       S = cast<CXXBindTemporaryExpr>(S)->getSubExpr();
318f4a2713aSLionel Sambuc       break;
319f4a2713aSLionel Sambuc     }
320f4a2713aSLionel Sambuc     case Stmt::UnaryExprOrTypeTraitExprClass: {
321f4a2713aSLionel Sambuc       // No need to unconditionally visit subexpressions.
322f4a2713aSLionel Sambuc       return;
323f4a2713aSLionel Sambuc     }
324f4a2713aSLionel Sambuc   }
325f4a2713aSLionel Sambuc 
326f4a2713aSLionel Sambuc   for (Stmt::child_iterator it = S->child_begin(), ei = S->child_end();
327f4a2713aSLionel Sambuc        it != ei; ++it) {
328f4a2713aSLionel Sambuc     if (Stmt *child = *it)
329f4a2713aSLionel Sambuc       AddLiveStmt(val.liveStmts, LV.SSetFact, child);
330f4a2713aSLionel Sambuc   }
331f4a2713aSLionel Sambuc }
332f4a2713aSLionel Sambuc 
VisitBinaryOperator(BinaryOperator * B)333f4a2713aSLionel Sambuc void TransferFunctions::VisitBinaryOperator(BinaryOperator *B) {
334f4a2713aSLionel Sambuc   if (B->isAssignmentOp()) {
335f4a2713aSLionel Sambuc     if (!LV.killAtAssign)
336f4a2713aSLionel Sambuc       return;
337f4a2713aSLionel Sambuc 
338f4a2713aSLionel Sambuc     // Assigning to a variable?
339f4a2713aSLionel Sambuc     Expr *LHS = B->getLHS()->IgnoreParens();
340f4a2713aSLionel Sambuc 
341f4a2713aSLionel Sambuc     if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(LHS))
342f4a2713aSLionel Sambuc       if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
343f4a2713aSLionel Sambuc         // Assignments to references don't kill the ref's address
344f4a2713aSLionel Sambuc         if (VD->getType()->isReferenceType())
345f4a2713aSLionel Sambuc           return;
346f4a2713aSLionel Sambuc 
347f4a2713aSLionel Sambuc         if (!isAlwaysAlive(VD)) {
348f4a2713aSLionel Sambuc           // The variable is now dead.
349f4a2713aSLionel Sambuc           val.liveDecls = LV.DSetFact.remove(val.liveDecls, VD);
350f4a2713aSLionel Sambuc         }
351f4a2713aSLionel Sambuc 
352f4a2713aSLionel Sambuc         if (observer)
353f4a2713aSLionel Sambuc           observer->observerKill(DR);
354f4a2713aSLionel Sambuc       }
355f4a2713aSLionel Sambuc   }
356f4a2713aSLionel Sambuc }
357f4a2713aSLionel Sambuc 
VisitBlockExpr(BlockExpr * BE)358f4a2713aSLionel Sambuc void TransferFunctions::VisitBlockExpr(BlockExpr *BE) {
359f4a2713aSLionel Sambuc   AnalysisDeclContext::referenced_decls_iterator I, E;
360*0a6a1f1dSLionel Sambuc   std::tie(I, E) =
361f4a2713aSLionel Sambuc     LV.analysisContext.getReferencedBlockVars(BE->getBlockDecl());
362f4a2713aSLionel Sambuc   for ( ; I != E ; ++I) {
363f4a2713aSLionel Sambuc     const VarDecl *VD = *I;
364f4a2713aSLionel Sambuc     if (isAlwaysAlive(VD))
365f4a2713aSLionel Sambuc       continue;
366f4a2713aSLionel Sambuc     val.liveDecls = LV.DSetFact.add(val.liveDecls, VD);
367f4a2713aSLionel Sambuc   }
368f4a2713aSLionel Sambuc }
369f4a2713aSLionel Sambuc 
VisitDeclRefExpr(DeclRefExpr * DR)370f4a2713aSLionel Sambuc void TransferFunctions::VisitDeclRefExpr(DeclRefExpr *DR) {
371f4a2713aSLionel Sambuc   if (const VarDecl *D = dyn_cast<VarDecl>(DR->getDecl()))
372f4a2713aSLionel Sambuc     if (!isAlwaysAlive(D) && LV.inAssignment.find(DR) == LV.inAssignment.end())
373f4a2713aSLionel Sambuc       val.liveDecls = LV.DSetFact.add(val.liveDecls, D);
374f4a2713aSLionel Sambuc }
375f4a2713aSLionel Sambuc 
VisitDeclStmt(DeclStmt * DS)376f4a2713aSLionel Sambuc void TransferFunctions::VisitDeclStmt(DeclStmt *DS) {
377*0a6a1f1dSLionel Sambuc   for (const auto *DI : DS->decls())
378*0a6a1f1dSLionel Sambuc     if (const auto *VD = dyn_cast<VarDecl>(DI)) {
379f4a2713aSLionel Sambuc       if (!isAlwaysAlive(VD))
380f4a2713aSLionel Sambuc         val.liveDecls = LV.DSetFact.remove(val.liveDecls, VD);
381f4a2713aSLionel Sambuc     }
382f4a2713aSLionel Sambuc }
383f4a2713aSLionel Sambuc 
VisitObjCForCollectionStmt(ObjCForCollectionStmt * OS)384f4a2713aSLionel Sambuc void TransferFunctions::VisitObjCForCollectionStmt(ObjCForCollectionStmt *OS) {
385f4a2713aSLionel Sambuc   // Kill the iteration variable.
386*0a6a1f1dSLionel Sambuc   DeclRefExpr *DR = nullptr;
387*0a6a1f1dSLionel Sambuc   const VarDecl *VD = nullptr;
388f4a2713aSLionel Sambuc 
389f4a2713aSLionel Sambuc   Stmt *element = OS->getElement();
390f4a2713aSLionel Sambuc   if (DeclStmt *DS = dyn_cast<DeclStmt>(element)) {
391f4a2713aSLionel Sambuc     VD = cast<VarDecl>(DS->getSingleDecl());
392f4a2713aSLionel Sambuc   }
393f4a2713aSLionel Sambuc   else if ((DR = dyn_cast<DeclRefExpr>(cast<Expr>(element)->IgnoreParens()))) {
394f4a2713aSLionel Sambuc     VD = cast<VarDecl>(DR->getDecl());
395f4a2713aSLionel Sambuc   }
396f4a2713aSLionel Sambuc 
397f4a2713aSLionel Sambuc   if (VD) {
398f4a2713aSLionel Sambuc     val.liveDecls = LV.DSetFact.remove(val.liveDecls, VD);
399f4a2713aSLionel Sambuc     if (observer && DR)
400f4a2713aSLionel Sambuc       observer->observerKill(DR);
401f4a2713aSLionel Sambuc   }
402f4a2713aSLionel Sambuc }
403f4a2713aSLionel Sambuc 
404f4a2713aSLionel Sambuc void TransferFunctions::
VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr * UE)405f4a2713aSLionel Sambuc VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE)
406f4a2713aSLionel Sambuc {
407f4a2713aSLionel Sambuc   // While sizeof(var) doesn't technically extend the liveness of 'var', it
408f4a2713aSLionel Sambuc   // does extent the liveness of metadata if 'var' is a VariableArrayType.
409f4a2713aSLionel Sambuc   // We handle that special case here.
410f4a2713aSLionel Sambuc   if (UE->getKind() != UETT_SizeOf || UE->isArgumentType())
411f4a2713aSLionel Sambuc     return;
412f4a2713aSLionel Sambuc 
413f4a2713aSLionel Sambuc   const Expr *subEx = UE->getArgumentExpr();
414f4a2713aSLionel Sambuc   if (subEx->getType()->isVariableArrayType()) {
415f4a2713aSLionel Sambuc     assert(subEx->isLValue());
416f4a2713aSLionel Sambuc     val.liveStmts = LV.SSetFact.add(val.liveStmts, subEx->IgnoreParens());
417f4a2713aSLionel Sambuc   }
418f4a2713aSLionel Sambuc }
419f4a2713aSLionel Sambuc 
VisitUnaryOperator(UnaryOperator * UO)420f4a2713aSLionel Sambuc void TransferFunctions::VisitUnaryOperator(UnaryOperator *UO) {
421f4a2713aSLionel Sambuc   // Treat ++/-- as a kill.
422f4a2713aSLionel Sambuc   // Note we don't actually have to do anything if we don't have an observer,
423f4a2713aSLionel Sambuc   // since a ++/-- acts as both a kill and a "use".
424f4a2713aSLionel Sambuc   if (!observer)
425f4a2713aSLionel Sambuc     return;
426f4a2713aSLionel Sambuc 
427f4a2713aSLionel Sambuc   switch (UO->getOpcode()) {
428f4a2713aSLionel Sambuc   default:
429f4a2713aSLionel Sambuc     return;
430f4a2713aSLionel Sambuc   case UO_PostInc:
431f4a2713aSLionel Sambuc   case UO_PostDec:
432f4a2713aSLionel Sambuc   case UO_PreInc:
433f4a2713aSLionel Sambuc   case UO_PreDec:
434f4a2713aSLionel Sambuc     break;
435f4a2713aSLionel Sambuc   }
436f4a2713aSLionel Sambuc 
437f4a2713aSLionel Sambuc   if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(UO->getSubExpr()->IgnoreParens()))
438f4a2713aSLionel Sambuc     if (isa<VarDecl>(DR->getDecl())) {
439f4a2713aSLionel Sambuc       // Treat ++/-- as a kill.
440f4a2713aSLionel Sambuc       observer->observerKill(DR);
441f4a2713aSLionel Sambuc     }
442f4a2713aSLionel Sambuc }
443f4a2713aSLionel Sambuc 
444f4a2713aSLionel Sambuc LiveVariables::LivenessValues
runOnBlock(const CFGBlock * block,LiveVariables::LivenessValues val,LiveVariables::Observer * obs)445f4a2713aSLionel Sambuc LiveVariablesImpl::runOnBlock(const CFGBlock *block,
446f4a2713aSLionel Sambuc                               LiveVariables::LivenessValues val,
447f4a2713aSLionel Sambuc                               LiveVariables::Observer *obs) {
448f4a2713aSLionel Sambuc 
449f4a2713aSLionel Sambuc   TransferFunctions TF(*this, val, obs, block);
450f4a2713aSLionel Sambuc 
451f4a2713aSLionel Sambuc   // Visit the terminator (if any).
452f4a2713aSLionel Sambuc   if (const Stmt *term = block->getTerminator())
453f4a2713aSLionel Sambuc     TF.Visit(const_cast<Stmt*>(term));
454f4a2713aSLionel Sambuc 
455f4a2713aSLionel Sambuc   // Apply the transfer function for all Stmts in the block.
456f4a2713aSLionel Sambuc   for (CFGBlock::const_reverse_iterator it = block->rbegin(),
457f4a2713aSLionel Sambuc        ei = block->rend(); it != ei; ++it) {
458f4a2713aSLionel Sambuc     const CFGElement &elem = *it;
459f4a2713aSLionel Sambuc 
460f4a2713aSLionel Sambuc     if (Optional<CFGAutomaticObjDtor> Dtor =
461f4a2713aSLionel Sambuc             elem.getAs<CFGAutomaticObjDtor>()) {
462f4a2713aSLionel Sambuc       val.liveDecls = DSetFact.add(val.liveDecls, Dtor->getVarDecl());
463f4a2713aSLionel Sambuc       continue;
464f4a2713aSLionel Sambuc     }
465f4a2713aSLionel Sambuc 
466f4a2713aSLionel Sambuc     if (!elem.getAs<CFGStmt>())
467f4a2713aSLionel Sambuc       continue;
468f4a2713aSLionel Sambuc 
469f4a2713aSLionel Sambuc     const Stmt *S = elem.castAs<CFGStmt>().getStmt();
470f4a2713aSLionel Sambuc     TF.Visit(const_cast<Stmt*>(S));
471f4a2713aSLionel Sambuc     stmtsToLiveness[S] = val;
472f4a2713aSLionel Sambuc   }
473f4a2713aSLionel Sambuc   return val;
474f4a2713aSLionel Sambuc }
475f4a2713aSLionel Sambuc 
runOnAllBlocks(LiveVariables::Observer & obs)476f4a2713aSLionel Sambuc void LiveVariables::runOnAllBlocks(LiveVariables::Observer &obs) {
477f4a2713aSLionel Sambuc   const CFG *cfg = getImpl(impl).analysisContext.getCFG();
478f4a2713aSLionel Sambuc   for (CFG::const_iterator it = cfg->begin(), ei = cfg->end(); it != ei; ++it)
479f4a2713aSLionel Sambuc     getImpl(impl).runOnBlock(*it, getImpl(impl).blocksEndToLiveness[*it], &obs);
480f4a2713aSLionel Sambuc }
481f4a2713aSLionel Sambuc 
LiveVariables(void * im)482f4a2713aSLionel Sambuc LiveVariables::LiveVariables(void *im) : impl(im) {}
483f4a2713aSLionel Sambuc 
~LiveVariables()484f4a2713aSLionel Sambuc LiveVariables::~LiveVariables() {
485f4a2713aSLionel Sambuc   delete (LiveVariablesImpl*) impl;
486f4a2713aSLionel Sambuc }
487f4a2713aSLionel Sambuc 
488f4a2713aSLionel Sambuc LiveVariables *
computeLiveness(AnalysisDeclContext & AC,bool killAtAssign)489f4a2713aSLionel Sambuc LiveVariables::computeLiveness(AnalysisDeclContext &AC,
490f4a2713aSLionel Sambuc                                  bool killAtAssign) {
491f4a2713aSLionel Sambuc 
492f4a2713aSLionel Sambuc   // No CFG?  Bail out.
493f4a2713aSLionel Sambuc   CFG *cfg = AC.getCFG();
494f4a2713aSLionel Sambuc   if (!cfg)
495*0a6a1f1dSLionel Sambuc     return nullptr;
496f4a2713aSLionel Sambuc 
497f4a2713aSLionel Sambuc   // The analysis currently has scalability issues for very large CFGs.
498f4a2713aSLionel Sambuc   // Bail out if it looks too large.
499f4a2713aSLionel Sambuc   if (cfg->getNumBlockIDs() > 300000)
500*0a6a1f1dSLionel Sambuc     return nullptr;
501f4a2713aSLionel Sambuc 
502f4a2713aSLionel Sambuc   LiveVariablesImpl *LV = new LiveVariablesImpl(AC, killAtAssign);
503f4a2713aSLionel Sambuc 
504f4a2713aSLionel Sambuc   // Construct the dataflow worklist.  Enqueue the exit block as the
505f4a2713aSLionel Sambuc   // start of the analysis.
506f4a2713aSLionel Sambuc   DataflowWorklist worklist(*cfg, AC);
507f4a2713aSLionel Sambuc   llvm::BitVector everAnalyzedBlock(cfg->getNumBlockIDs());
508f4a2713aSLionel Sambuc 
509f4a2713aSLionel Sambuc   // FIXME: we should enqueue using post order.
510f4a2713aSLionel Sambuc   for (CFG::const_iterator it = cfg->begin(), ei = cfg->end(); it != ei; ++it) {
511f4a2713aSLionel Sambuc     const CFGBlock *block = *it;
512f4a2713aSLionel Sambuc     worklist.enqueueBlock(block);
513f4a2713aSLionel Sambuc 
514f4a2713aSLionel Sambuc     // FIXME: Scan for DeclRefExprs using in the LHS of an assignment.
515f4a2713aSLionel Sambuc     // We need to do this because we lack context in the reverse analysis
516f4a2713aSLionel Sambuc     // to determine if a DeclRefExpr appears in such a context, and thus
517f4a2713aSLionel Sambuc     // doesn't constitute a "use".
518f4a2713aSLionel Sambuc     if (killAtAssign)
519f4a2713aSLionel Sambuc       for (CFGBlock::const_iterator bi = block->begin(), be = block->end();
520f4a2713aSLionel Sambuc            bi != be; ++bi) {
521f4a2713aSLionel Sambuc         if (Optional<CFGStmt> cs = bi->getAs<CFGStmt>()) {
522f4a2713aSLionel Sambuc           if (const BinaryOperator *BO =
523f4a2713aSLionel Sambuc                   dyn_cast<BinaryOperator>(cs->getStmt())) {
524f4a2713aSLionel Sambuc             if (BO->getOpcode() == BO_Assign) {
525f4a2713aSLionel Sambuc               if (const DeclRefExpr *DR =
526f4a2713aSLionel Sambuc                     dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens())) {
527f4a2713aSLionel Sambuc                 LV->inAssignment[DR] = 1;
528f4a2713aSLionel Sambuc               }
529f4a2713aSLionel Sambuc             }
530f4a2713aSLionel Sambuc           }
531f4a2713aSLionel Sambuc         }
532f4a2713aSLionel Sambuc       }
533f4a2713aSLionel Sambuc   }
534f4a2713aSLionel Sambuc 
535f4a2713aSLionel Sambuc   worklist.sortWorklist();
536f4a2713aSLionel Sambuc 
537f4a2713aSLionel Sambuc   while (const CFGBlock *block = worklist.dequeue()) {
538f4a2713aSLionel Sambuc     // Determine if the block's end value has changed.  If not, we
539f4a2713aSLionel Sambuc     // have nothing left to do for this block.
540f4a2713aSLionel Sambuc     LivenessValues &prevVal = LV->blocksEndToLiveness[block];
541f4a2713aSLionel Sambuc 
542f4a2713aSLionel Sambuc     // Merge the values of all successor blocks.
543f4a2713aSLionel Sambuc     LivenessValues val;
544f4a2713aSLionel Sambuc     for (CFGBlock::const_succ_iterator it = block->succ_begin(),
545f4a2713aSLionel Sambuc                                        ei = block->succ_end(); it != ei; ++it) {
546f4a2713aSLionel Sambuc       if (const CFGBlock *succ = *it) {
547f4a2713aSLionel Sambuc         val = LV->merge(val, LV->blocksBeginToLiveness[succ]);
548f4a2713aSLionel Sambuc       }
549f4a2713aSLionel Sambuc     }
550f4a2713aSLionel Sambuc 
551f4a2713aSLionel Sambuc     if (!everAnalyzedBlock[block->getBlockID()])
552f4a2713aSLionel Sambuc       everAnalyzedBlock[block->getBlockID()] = true;
553f4a2713aSLionel Sambuc     else if (prevVal.equals(val))
554f4a2713aSLionel Sambuc       continue;
555f4a2713aSLionel Sambuc 
556f4a2713aSLionel Sambuc     prevVal = val;
557f4a2713aSLionel Sambuc 
558f4a2713aSLionel Sambuc     // Update the dataflow value for the start of this block.
559f4a2713aSLionel Sambuc     LV->blocksBeginToLiveness[block] = LV->runOnBlock(block, val);
560f4a2713aSLionel Sambuc 
561f4a2713aSLionel Sambuc     // Enqueue the value to the predecessors.
562f4a2713aSLionel Sambuc     worklist.enqueuePredecessors(block);
563f4a2713aSLionel Sambuc   }
564f4a2713aSLionel Sambuc 
565f4a2713aSLionel Sambuc   return new LiveVariables(LV);
566f4a2713aSLionel Sambuc }
567f4a2713aSLionel Sambuc 
dumpBlockLiveness(const SourceManager & M)568f4a2713aSLionel Sambuc void LiveVariables::dumpBlockLiveness(const SourceManager &M) {
569f4a2713aSLionel Sambuc   getImpl(impl).dumpBlockLiveness(M);
570f4a2713aSLionel Sambuc }
571f4a2713aSLionel Sambuc 
dumpBlockLiveness(const SourceManager & M)572f4a2713aSLionel Sambuc void LiveVariablesImpl::dumpBlockLiveness(const SourceManager &M) {
573f4a2713aSLionel Sambuc   std::vector<const CFGBlock *> vec;
574f4a2713aSLionel Sambuc   for (llvm::DenseMap<const CFGBlock *, LiveVariables::LivenessValues>::iterator
575f4a2713aSLionel Sambuc        it = blocksEndToLiveness.begin(), ei = blocksEndToLiveness.end();
576f4a2713aSLionel Sambuc        it != ei; ++it) {
577f4a2713aSLionel Sambuc     vec.push_back(it->first);
578f4a2713aSLionel Sambuc   }
579*0a6a1f1dSLionel Sambuc   std::sort(vec.begin(), vec.end(), [](const CFGBlock *A, const CFGBlock *B) {
580*0a6a1f1dSLionel Sambuc     return A->getBlockID() < B->getBlockID();
581*0a6a1f1dSLionel Sambuc   });
582f4a2713aSLionel Sambuc 
583f4a2713aSLionel Sambuc   std::vector<const VarDecl*> declVec;
584f4a2713aSLionel Sambuc 
585f4a2713aSLionel Sambuc   for (std::vector<const CFGBlock *>::iterator
586f4a2713aSLionel Sambuc         it = vec.begin(), ei = vec.end(); it != ei; ++it) {
587f4a2713aSLionel Sambuc     llvm::errs() << "\n[ B" << (*it)->getBlockID()
588f4a2713aSLionel Sambuc                  << " (live variables at block exit) ]\n";
589f4a2713aSLionel Sambuc 
590f4a2713aSLionel Sambuc     LiveVariables::LivenessValues vals = blocksEndToLiveness[*it];
591f4a2713aSLionel Sambuc     declVec.clear();
592f4a2713aSLionel Sambuc 
593f4a2713aSLionel Sambuc     for (llvm::ImmutableSet<const VarDecl *>::iterator si =
594f4a2713aSLionel Sambuc           vals.liveDecls.begin(),
595f4a2713aSLionel Sambuc           se = vals.liveDecls.end(); si != se; ++si) {
596f4a2713aSLionel Sambuc       declVec.push_back(*si);
597f4a2713aSLionel Sambuc     }
598f4a2713aSLionel Sambuc 
599*0a6a1f1dSLionel Sambuc     std::sort(declVec.begin(), declVec.end(), [](const Decl *A, const Decl *B) {
600*0a6a1f1dSLionel Sambuc       return A->getLocStart() < B->getLocStart();
601*0a6a1f1dSLionel Sambuc     });
602f4a2713aSLionel Sambuc 
603f4a2713aSLionel Sambuc     for (std::vector<const VarDecl*>::iterator di = declVec.begin(),
604f4a2713aSLionel Sambuc          de = declVec.end(); di != de; ++di) {
605f4a2713aSLionel Sambuc       llvm::errs() << " " << (*di)->getDeclName().getAsString()
606f4a2713aSLionel Sambuc                    << " <";
607f4a2713aSLionel Sambuc       (*di)->getLocation().dump(M);
608f4a2713aSLionel Sambuc       llvm::errs() << ">\n";
609f4a2713aSLionel Sambuc     }
610f4a2713aSLionel Sambuc   }
611f4a2713aSLionel Sambuc   llvm::errs() << "\n";
612f4a2713aSLionel Sambuc }
613f4a2713aSLionel Sambuc 
getTag()614f4a2713aSLionel Sambuc const void *LiveVariables::getTag() { static int x; return &x; }
getTag()615f4a2713aSLionel Sambuc const void *RelaxedLiveVariables::getTag() { static int x; return &x; }
616