xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/Analysis/LiveVariables.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //=- LiveVariables.cpp - Live Variable Analysis for Source CFGs ----------*-==//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file implements Live Variables analysis for source-level CFGs.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg 
137330f729Sjoerg #include "clang/Analysis/Analyses/LiveVariables.h"
147330f729Sjoerg #include "clang/AST/Stmt.h"
157330f729Sjoerg #include "clang/AST/StmtVisitor.h"
167330f729Sjoerg #include "clang/Analysis/AnalysisDeclContext.h"
177330f729Sjoerg #include "clang/Analysis/CFG.h"
18*e038c9c4Sjoerg #include "clang/Analysis/FlowSensitive/DataflowWorklist.h"
197330f729Sjoerg #include "llvm/ADT/DenseMap.h"
207330f729Sjoerg #include "llvm/Support/raw_ostream.h"
217330f729Sjoerg #include <algorithm>
227330f729Sjoerg #include <vector>
237330f729Sjoerg 
247330f729Sjoerg using namespace clang;
257330f729Sjoerg 
267330f729Sjoerg namespace {
277330f729Sjoerg class LiveVariablesImpl {
287330f729Sjoerg public:
297330f729Sjoerg   AnalysisDeclContext &analysisContext;
30*e038c9c4Sjoerg   llvm::ImmutableSet<const Expr *>::Factory ESetFact;
317330f729Sjoerg   llvm::ImmutableSet<const VarDecl *>::Factory DSetFact;
327330f729Sjoerg   llvm::ImmutableSet<const BindingDecl *>::Factory BSetFact;
337330f729Sjoerg   llvm::DenseMap<const CFGBlock *, LiveVariables::LivenessValues> blocksEndToLiveness;
347330f729Sjoerg   llvm::DenseMap<const CFGBlock *, LiveVariables::LivenessValues> blocksBeginToLiveness;
357330f729Sjoerg   llvm::DenseMap<const Stmt *, LiveVariables::LivenessValues> stmtsToLiveness;
367330f729Sjoerg   llvm::DenseMap<const DeclRefExpr *, unsigned> inAssignment;
377330f729Sjoerg   const bool killAtAssign;
387330f729Sjoerg 
397330f729Sjoerg   LiveVariables::LivenessValues
407330f729Sjoerg   merge(LiveVariables::LivenessValues valsA,
417330f729Sjoerg         LiveVariables::LivenessValues valsB);
427330f729Sjoerg 
437330f729Sjoerg   LiveVariables::LivenessValues
447330f729Sjoerg   runOnBlock(const CFGBlock *block, LiveVariables::LivenessValues val,
457330f729Sjoerg              LiveVariables::Observer *obs = nullptr);
467330f729Sjoerg 
477330f729Sjoerg   void dumpBlockLiveness(const SourceManager& M);
48*e038c9c4Sjoerg   void dumpExprLiveness(const SourceManager& M);
497330f729Sjoerg 
LiveVariablesImpl(AnalysisDeclContext & ac,bool KillAtAssign)507330f729Sjoerg   LiveVariablesImpl(AnalysisDeclContext &ac, bool KillAtAssign)
517330f729Sjoerg       : analysisContext(ac),
52*e038c9c4Sjoerg         ESetFact(false), // Do not canonicalize ImmutableSets by default.
537330f729Sjoerg         DSetFact(false), // This is a *major* performance win.
54*e038c9c4Sjoerg         BSetFact(false), killAtAssign(KillAtAssign) {}
557330f729Sjoerg };
56*e038c9c4Sjoerg } // namespace
577330f729Sjoerg 
getImpl(void * x)587330f729Sjoerg static LiveVariablesImpl &getImpl(void *x) {
597330f729Sjoerg   return *((LiveVariablesImpl *) x);
607330f729Sjoerg }
617330f729Sjoerg 
627330f729Sjoerg //===----------------------------------------------------------------------===//
637330f729Sjoerg // Operations and queries on LivenessValues.
647330f729Sjoerg //===----------------------------------------------------------------------===//
657330f729Sjoerg 
isLive(const Expr * E) const66*e038c9c4Sjoerg bool LiveVariables::LivenessValues::isLive(const Expr *E) const {
67*e038c9c4Sjoerg   return liveExprs.contains(E);
687330f729Sjoerg }
697330f729Sjoerg 
isLive(const VarDecl * D) const707330f729Sjoerg bool LiveVariables::LivenessValues::isLive(const VarDecl *D) const {
717330f729Sjoerg   if (const auto *DD = dyn_cast<DecompositionDecl>(D)) {
727330f729Sjoerg     bool alive = false;
737330f729Sjoerg     for (const BindingDecl *BD : DD->bindings())
747330f729Sjoerg       alive |= liveBindings.contains(BD);
757330f729Sjoerg     return alive;
767330f729Sjoerg   }
777330f729Sjoerg   return liveDecls.contains(D);
787330f729Sjoerg }
797330f729Sjoerg 
807330f729Sjoerg namespace {
817330f729Sjoerg   template <typename SET>
mergeSets(SET A,SET B)827330f729Sjoerg   SET mergeSets(SET A, SET B) {
837330f729Sjoerg     if (A.isEmpty())
847330f729Sjoerg       return B;
857330f729Sjoerg 
867330f729Sjoerg     for (typename SET::iterator it = B.begin(), ei = B.end(); it != ei; ++it) {
877330f729Sjoerg       A = A.add(*it);
887330f729Sjoerg     }
897330f729Sjoerg     return A;
907330f729Sjoerg   }
91*e038c9c4Sjoerg } // namespace
927330f729Sjoerg 
anchor()937330f729Sjoerg void LiveVariables::Observer::anchor() { }
947330f729Sjoerg 
957330f729Sjoerg LiveVariables::LivenessValues
merge(LiveVariables::LivenessValues valsA,LiveVariables::LivenessValues valsB)967330f729Sjoerg LiveVariablesImpl::merge(LiveVariables::LivenessValues valsA,
977330f729Sjoerg                          LiveVariables::LivenessValues valsB) {
987330f729Sjoerg 
99*e038c9c4Sjoerg   llvm::ImmutableSetRef<const Expr *> SSetRefA(
100*e038c9c4Sjoerg       valsA.liveExprs.getRootWithoutRetain(), ESetFact.getTreeFactory()),
101*e038c9c4Sjoerg       SSetRefB(valsB.liveExprs.getRootWithoutRetain(),
102*e038c9c4Sjoerg                ESetFact.getTreeFactory());
1037330f729Sjoerg 
1047330f729Sjoerg   llvm::ImmutableSetRef<const VarDecl *>
1057330f729Sjoerg     DSetRefA(valsA.liveDecls.getRootWithoutRetain(), DSetFact.getTreeFactory()),
1067330f729Sjoerg     DSetRefB(valsB.liveDecls.getRootWithoutRetain(), DSetFact.getTreeFactory());
1077330f729Sjoerg 
1087330f729Sjoerg   llvm::ImmutableSetRef<const BindingDecl *>
1097330f729Sjoerg     BSetRefA(valsA.liveBindings.getRootWithoutRetain(), BSetFact.getTreeFactory()),
1107330f729Sjoerg     BSetRefB(valsB.liveBindings.getRootWithoutRetain(), BSetFact.getTreeFactory());
1117330f729Sjoerg 
1127330f729Sjoerg   SSetRefA = mergeSets(SSetRefA, SSetRefB);
1137330f729Sjoerg   DSetRefA = mergeSets(DSetRefA, DSetRefB);
1147330f729Sjoerg   BSetRefA = mergeSets(BSetRefA, BSetRefB);
1157330f729Sjoerg 
1167330f729Sjoerg   // asImmutableSet() canonicalizes the tree, allowing us to do an easy
1177330f729Sjoerg   // comparison afterwards.
1187330f729Sjoerg   return LiveVariables::LivenessValues(SSetRefA.asImmutableSet(),
1197330f729Sjoerg                                        DSetRefA.asImmutableSet(),
1207330f729Sjoerg                                        BSetRefA.asImmutableSet());
1217330f729Sjoerg }
1227330f729Sjoerg 
equals(const LivenessValues & V) const1237330f729Sjoerg bool LiveVariables::LivenessValues::equals(const LivenessValues &V) const {
124*e038c9c4Sjoerg   return liveExprs == V.liveExprs && liveDecls == V.liveDecls;
1257330f729Sjoerg }
1267330f729Sjoerg 
1277330f729Sjoerg //===----------------------------------------------------------------------===//
1287330f729Sjoerg // Query methods.
1297330f729Sjoerg //===----------------------------------------------------------------------===//
1307330f729Sjoerg 
isAlwaysAlive(const VarDecl * D)1317330f729Sjoerg static bool isAlwaysAlive(const VarDecl *D) {
1327330f729Sjoerg   return D->hasGlobalStorage();
1337330f729Sjoerg }
1347330f729Sjoerg 
isLive(const CFGBlock * B,const VarDecl * D)1357330f729Sjoerg bool LiveVariables::isLive(const CFGBlock *B, const VarDecl *D) {
1367330f729Sjoerg   return isAlwaysAlive(D) || getImpl(impl).blocksEndToLiveness[B].isLive(D);
1377330f729Sjoerg }
1387330f729Sjoerg 
isLive(const Stmt * S,const VarDecl * D)1397330f729Sjoerg bool LiveVariables::isLive(const Stmt *S, const VarDecl *D) {
1407330f729Sjoerg   return isAlwaysAlive(D) || getImpl(impl).stmtsToLiveness[S].isLive(D);
1417330f729Sjoerg }
1427330f729Sjoerg 
isLive(const Stmt * Loc,const Expr * Val)143*e038c9c4Sjoerg bool LiveVariables::isLive(const Stmt *Loc, const Expr *Val) {
144*e038c9c4Sjoerg   return getImpl(impl).stmtsToLiveness[Loc].isLive(Val);
1457330f729Sjoerg }
1467330f729Sjoerg 
1477330f729Sjoerg //===----------------------------------------------------------------------===//
1487330f729Sjoerg // Dataflow computation.
1497330f729Sjoerg //===----------------------------------------------------------------------===//
1507330f729Sjoerg 
1517330f729Sjoerg namespace {
1527330f729Sjoerg class TransferFunctions : public StmtVisitor<TransferFunctions> {
1537330f729Sjoerg   LiveVariablesImpl &LV;
1547330f729Sjoerg   LiveVariables::LivenessValues &val;
1557330f729Sjoerg   LiveVariables::Observer *observer;
1567330f729Sjoerg   const CFGBlock *currentBlock;
1577330f729Sjoerg public:
TransferFunctions(LiveVariablesImpl & im,LiveVariables::LivenessValues & Val,LiveVariables::Observer * Observer,const CFGBlock * CurrentBlock)1587330f729Sjoerg   TransferFunctions(LiveVariablesImpl &im,
1597330f729Sjoerg                     LiveVariables::LivenessValues &Val,
1607330f729Sjoerg                     LiveVariables::Observer *Observer,
1617330f729Sjoerg                     const CFGBlock *CurrentBlock)
1627330f729Sjoerg   : LV(im), val(Val), observer(Observer), currentBlock(CurrentBlock) {}
1637330f729Sjoerg 
1647330f729Sjoerg   void VisitBinaryOperator(BinaryOperator *BO);
1657330f729Sjoerg   void VisitBlockExpr(BlockExpr *BE);
1667330f729Sjoerg   void VisitDeclRefExpr(DeclRefExpr *DR);
1677330f729Sjoerg   void VisitDeclStmt(DeclStmt *DS);
1687330f729Sjoerg   void VisitObjCForCollectionStmt(ObjCForCollectionStmt *OS);
1697330f729Sjoerg   void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE);
1707330f729Sjoerg   void VisitUnaryOperator(UnaryOperator *UO);
1717330f729Sjoerg   void Visit(Stmt *S);
1727330f729Sjoerg };
173*e038c9c4Sjoerg } // namespace
1747330f729Sjoerg 
FindVA(QualType Ty)1757330f729Sjoerg static const VariableArrayType *FindVA(QualType Ty) {
1767330f729Sjoerg   const Type *ty = Ty.getTypePtr();
1777330f729Sjoerg   while (const ArrayType *VT = dyn_cast<ArrayType>(ty)) {
1787330f729Sjoerg     if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(VT))
1797330f729Sjoerg       if (VAT->getSizeExpr())
1807330f729Sjoerg         return VAT;
1817330f729Sjoerg 
1827330f729Sjoerg     ty = VT->getElementType().getTypePtr();
1837330f729Sjoerg   }
1847330f729Sjoerg 
1857330f729Sjoerg   return nullptr;
1867330f729Sjoerg }
1877330f729Sjoerg 
LookThroughExpr(const Expr * E)188*e038c9c4Sjoerg static const Expr *LookThroughExpr(const Expr *E) {
189*e038c9c4Sjoerg   while (E) {
190*e038c9c4Sjoerg     if (const Expr *Ex = dyn_cast<Expr>(E))
191*e038c9c4Sjoerg       E = Ex->IgnoreParens();
192*e038c9c4Sjoerg     if (const FullExpr *FE = dyn_cast<FullExpr>(E)) {
193*e038c9c4Sjoerg       E = FE->getSubExpr();
1947330f729Sjoerg       continue;
1957330f729Sjoerg     }
196*e038c9c4Sjoerg     if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) {
197*e038c9c4Sjoerg       E = OVE->getSourceExpr();
1987330f729Sjoerg       continue;
1997330f729Sjoerg     }
2007330f729Sjoerg     break;
2017330f729Sjoerg   }
202*e038c9c4Sjoerg   return E;
2037330f729Sjoerg }
2047330f729Sjoerg 
AddLiveExpr(llvm::ImmutableSet<const Expr * > & Set,llvm::ImmutableSet<const Expr * >::Factory & F,const Expr * E)205*e038c9c4Sjoerg static void AddLiveExpr(llvm::ImmutableSet<const Expr *> &Set,
206*e038c9c4Sjoerg                         llvm::ImmutableSet<const Expr *>::Factory &F,
207*e038c9c4Sjoerg                         const Expr *E) {
208*e038c9c4Sjoerg   Set = F.add(Set, LookThroughExpr(E));
2097330f729Sjoerg }
2107330f729Sjoerg 
Visit(Stmt * S)2117330f729Sjoerg void TransferFunctions::Visit(Stmt *S) {
2127330f729Sjoerg   if (observer)
2137330f729Sjoerg     observer->observeStmt(S, currentBlock, val);
2147330f729Sjoerg 
2157330f729Sjoerg   StmtVisitor<TransferFunctions>::Visit(S);
2167330f729Sjoerg 
217*e038c9c4Sjoerg   if (const auto *E = dyn_cast<Expr>(S)) {
218*e038c9c4Sjoerg     val.liveExprs = LV.ESetFact.remove(val.liveExprs, E);
2197330f729Sjoerg   }
2207330f729Sjoerg 
2217330f729Sjoerg   // Mark all children expressions live.
2227330f729Sjoerg 
2237330f729Sjoerg   switch (S->getStmtClass()) {
2247330f729Sjoerg     default:
2257330f729Sjoerg       break;
2267330f729Sjoerg     case Stmt::StmtExprClass: {
2277330f729Sjoerg       // For statement expressions, look through the compound statement.
2287330f729Sjoerg       S = cast<StmtExpr>(S)->getSubStmt();
2297330f729Sjoerg       break;
2307330f729Sjoerg     }
2317330f729Sjoerg     case Stmt::CXXMemberCallExprClass: {
2327330f729Sjoerg       // Include the implicit "this" pointer as being live.
2337330f729Sjoerg       CXXMemberCallExpr *CE = cast<CXXMemberCallExpr>(S);
2347330f729Sjoerg       if (Expr *ImplicitObj = CE->getImplicitObjectArgument()) {
235*e038c9c4Sjoerg         AddLiveExpr(val.liveExprs, LV.ESetFact, ImplicitObj);
2367330f729Sjoerg       }
2377330f729Sjoerg       break;
2387330f729Sjoerg     }
2397330f729Sjoerg     case Stmt::ObjCMessageExprClass: {
2407330f729Sjoerg       // In calls to super, include the implicit "self" pointer as being live.
2417330f729Sjoerg       ObjCMessageExpr *CE = cast<ObjCMessageExpr>(S);
2427330f729Sjoerg       if (CE->getReceiverKind() == ObjCMessageExpr::SuperInstance)
2437330f729Sjoerg         val.liveDecls = LV.DSetFact.add(val.liveDecls,
2447330f729Sjoerg                                         LV.analysisContext.getSelfDecl());
2457330f729Sjoerg       break;
2467330f729Sjoerg     }
2477330f729Sjoerg     case Stmt::DeclStmtClass: {
2487330f729Sjoerg       const DeclStmt *DS = cast<DeclStmt>(S);
2497330f729Sjoerg       if (const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl())) {
2507330f729Sjoerg         for (const VariableArrayType* VA = FindVA(VD->getType());
2517330f729Sjoerg              VA != nullptr; VA = FindVA(VA->getElementType())) {
252*e038c9c4Sjoerg           AddLiveExpr(val.liveExprs, LV.ESetFact, VA->getSizeExpr());
2537330f729Sjoerg         }
2547330f729Sjoerg       }
2557330f729Sjoerg       break;
2567330f729Sjoerg     }
2577330f729Sjoerg     case Stmt::PseudoObjectExprClass: {
2587330f729Sjoerg       // A pseudo-object operation only directly consumes its result
2597330f729Sjoerg       // expression.
2607330f729Sjoerg       Expr *child = cast<PseudoObjectExpr>(S)->getResultExpr();
2617330f729Sjoerg       if (!child) return;
2627330f729Sjoerg       if (OpaqueValueExpr *OV = dyn_cast<OpaqueValueExpr>(child))
2637330f729Sjoerg         child = OV->getSourceExpr();
2647330f729Sjoerg       child = child->IgnoreParens();
265*e038c9c4Sjoerg       val.liveExprs = LV.ESetFact.add(val.liveExprs, child);
2667330f729Sjoerg       return;
2677330f729Sjoerg     }
2687330f729Sjoerg 
2697330f729Sjoerg     // FIXME: These cases eventually shouldn't be needed.
2707330f729Sjoerg     case Stmt::ExprWithCleanupsClass: {
2717330f729Sjoerg       S = cast<ExprWithCleanups>(S)->getSubExpr();
2727330f729Sjoerg       break;
2737330f729Sjoerg     }
2747330f729Sjoerg     case Stmt::CXXBindTemporaryExprClass: {
2757330f729Sjoerg       S = cast<CXXBindTemporaryExpr>(S)->getSubExpr();
2767330f729Sjoerg       break;
2777330f729Sjoerg     }
2787330f729Sjoerg     case Stmt::UnaryExprOrTypeTraitExprClass: {
2797330f729Sjoerg       // No need to unconditionally visit subexpressions.
2807330f729Sjoerg       return;
2817330f729Sjoerg     }
2827330f729Sjoerg     case Stmt::IfStmtClass: {
2837330f729Sjoerg       // If one of the branches is an expression rather than a compound
2847330f729Sjoerg       // statement, it will be bad if we mark it as live at the terminator
2857330f729Sjoerg       // of the if-statement (i.e., immediately after the condition expression).
286*e038c9c4Sjoerg       AddLiveExpr(val.liveExprs, LV.ESetFact, cast<IfStmt>(S)->getCond());
2877330f729Sjoerg       return;
2887330f729Sjoerg     }
2897330f729Sjoerg     case Stmt::WhileStmtClass: {
2907330f729Sjoerg       // If the loop body is an expression rather than a compound statement,
2917330f729Sjoerg       // it will be bad if we mark it as live at the terminator of the loop
2927330f729Sjoerg       // (i.e., immediately after the condition expression).
293*e038c9c4Sjoerg       AddLiveExpr(val.liveExprs, LV.ESetFact, cast<WhileStmt>(S)->getCond());
2947330f729Sjoerg       return;
2957330f729Sjoerg     }
2967330f729Sjoerg     case Stmt::DoStmtClass: {
2977330f729Sjoerg       // If the loop body is an expression rather than a compound statement,
2987330f729Sjoerg       // it will be bad if we mark it as live at the terminator of the loop
2997330f729Sjoerg       // (i.e., immediately after the condition expression).
300*e038c9c4Sjoerg       AddLiveExpr(val.liveExprs, LV.ESetFact, cast<DoStmt>(S)->getCond());
3017330f729Sjoerg       return;
3027330f729Sjoerg     }
3037330f729Sjoerg     case Stmt::ForStmtClass: {
3047330f729Sjoerg       // If the loop body is an expression rather than a compound statement,
3057330f729Sjoerg       // it will be bad if we mark it as live at the terminator of the loop
3067330f729Sjoerg       // (i.e., immediately after the condition expression).
307*e038c9c4Sjoerg       AddLiveExpr(val.liveExprs, LV.ESetFact, cast<ForStmt>(S)->getCond());
3087330f729Sjoerg       return;
3097330f729Sjoerg     }
3107330f729Sjoerg 
3117330f729Sjoerg   }
3127330f729Sjoerg 
313*e038c9c4Sjoerg   // HACK + FIXME: What is this? One could only guess that this is an attempt to
314*e038c9c4Sjoerg   // fish for live values, for example, arguments from a call expression.
315*e038c9c4Sjoerg   // Maybe we could take inspiration from UninitializedVariable analysis?
3167330f729Sjoerg   for (Stmt *Child : S->children()) {
317*e038c9c4Sjoerg     if (const auto *E = dyn_cast_or_null<Expr>(Child))
318*e038c9c4Sjoerg       AddLiveExpr(val.liveExprs, LV.ESetFact, E);
3197330f729Sjoerg   }
3207330f729Sjoerg }
3217330f729Sjoerg 
writeShouldKill(const VarDecl * VD)3227330f729Sjoerg static bool writeShouldKill(const VarDecl *VD) {
3237330f729Sjoerg   return VD && !VD->getType()->isReferenceType() &&
3247330f729Sjoerg     !isAlwaysAlive(VD);
3257330f729Sjoerg }
3267330f729Sjoerg 
VisitBinaryOperator(BinaryOperator * B)3277330f729Sjoerg void TransferFunctions::VisitBinaryOperator(BinaryOperator *B) {
328*e038c9c4Sjoerg   if (LV.killAtAssign && B->getOpcode() == BO_Assign) {
329*e038c9c4Sjoerg     if (const auto *DR = dyn_cast<DeclRefExpr>(B->getLHS()->IgnoreParens())) {
330*e038c9c4Sjoerg       LV.inAssignment[DR] = 1;
331*e038c9c4Sjoerg     }
332*e038c9c4Sjoerg   }
3337330f729Sjoerg   if (B->isAssignmentOp()) {
3347330f729Sjoerg     if (!LV.killAtAssign)
3357330f729Sjoerg       return;
3367330f729Sjoerg 
3377330f729Sjoerg     // Assigning to a variable?
3387330f729Sjoerg     Expr *LHS = B->getLHS()->IgnoreParens();
3397330f729Sjoerg 
3407330f729Sjoerg     if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(LHS)) {
3417330f729Sjoerg       const Decl* D = DR->getDecl();
3427330f729Sjoerg       bool Killed = false;
3437330f729Sjoerg 
3447330f729Sjoerg       if (const BindingDecl* BD = dyn_cast<BindingDecl>(D)) {
3457330f729Sjoerg         Killed = !BD->getType()->isReferenceType();
3467330f729Sjoerg         if (Killed)
3477330f729Sjoerg           val.liveBindings = LV.BSetFact.remove(val.liveBindings, BD);
3487330f729Sjoerg       } else if (const auto *VD = dyn_cast<VarDecl>(D)) {
3497330f729Sjoerg         Killed = writeShouldKill(VD);
3507330f729Sjoerg         if (Killed)
3517330f729Sjoerg           val.liveDecls = LV.DSetFact.remove(val.liveDecls, VD);
3527330f729Sjoerg 
3537330f729Sjoerg       }
3547330f729Sjoerg 
3557330f729Sjoerg       if (Killed && observer)
3567330f729Sjoerg         observer->observerKill(DR);
3577330f729Sjoerg     }
3587330f729Sjoerg   }
3597330f729Sjoerg }
3607330f729Sjoerg 
VisitBlockExpr(BlockExpr * BE)3617330f729Sjoerg void TransferFunctions::VisitBlockExpr(BlockExpr *BE) {
3627330f729Sjoerg   for (const VarDecl *VD :
3637330f729Sjoerg        LV.analysisContext.getReferencedBlockVars(BE->getBlockDecl())) {
3647330f729Sjoerg     if (isAlwaysAlive(VD))
3657330f729Sjoerg       continue;
3667330f729Sjoerg     val.liveDecls = LV.DSetFact.add(val.liveDecls, VD);
3677330f729Sjoerg   }
3687330f729Sjoerg }
3697330f729Sjoerg 
VisitDeclRefExpr(DeclRefExpr * DR)3707330f729Sjoerg void TransferFunctions::VisitDeclRefExpr(DeclRefExpr *DR) {
3717330f729Sjoerg   const Decl* D = DR->getDecl();
3727330f729Sjoerg   bool InAssignment = LV.inAssignment[DR];
3737330f729Sjoerg   if (const auto *BD = dyn_cast<BindingDecl>(D)) {
3747330f729Sjoerg     if (!InAssignment)
3757330f729Sjoerg       val.liveBindings = LV.BSetFact.add(val.liveBindings, BD);
3767330f729Sjoerg   } else if (const auto *VD = dyn_cast<VarDecl>(D)) {
3777330f729Sjoerg     if (!InAssignment && !isAlwaysAlive(VD))
3787330f729Sjoerg       val.liveDecls = LV.DSetFact.add(val.liveDecls, VD);
3797330f729Sjoerg   }
3807330f729Sjoerg }
3817330f729Sjoerg 
VisitDeclStmt(DeclStmt * DS)3827330f729Sjoerg void TransferFunctions::VisitDeclStmt(DeclStmt *DS) {
3837330f729Sjoerg   for (const auto *DI : DS->decls()) {
3847330f729Sjoerg     if (const auto *DD = dyn_cast<DecompositionDecl>(DI)) {
3857330f729Sjoerg       for (const auto *BD : DD->bindings())
3867330f729Sjoerg         val.liveBindings = LV.BSetFact.remove(val.liveBindings, BD);
3877330f729Sjoerg     } else if (const auto *VD = dyn_cast<VarDecl>(DI)) {
3887330f729Sjoerg       if (!isAlwaysAlive(VD))
3897330f729Sjoerg         val.liveDecls = LV.DSetFact.remove(val.liveDecls, VD);
3907330f729Sjoerg     }
3917330f729Sjoerg   }
3927330f729Sjoerg }
3937330f729Sjoerg 
VisitObjCForCollectionStmt(ObjCForCollectionStmt * OS)3947330f729Sjoerg void TransferFunctions::VisitObjCForCollectionStmt(ObjCForCollectionStmt *OS) {
3957330f729Sjoerg   // Kill the iteration variable.
3967330f729Sjoerg   DeclRefExpr *DR = nullptr;
3977330f729Sjoerg   const VarDecl *VD = nullptr;
3987330f729Sjoerg 
3997330f729Sjoerg   Stmt *element = OS->getElement();
4007330f729Sjoerg   if (DeclStmt *DS = dyn_cast<DeclStmt>(element)) {
4017330f729Sjoerg     VD = cast<VarDecl>(DS->getSingleDecl());
4027330f729Sjoerg   }
4037330f729Sjoerg   else if ((DR = dyn_cast<DeclRefExpr>(cast<Expr>(element)->IgnoreParens()))) {
4047330f729Sjoerg     VD = cast<VarDecl>(DR->getDecl());
4057330f729Sjoerg   }
4067330f729Sjoerg 
4077330f729Sjoerg   if (VD) {
4087330f729Sjoerg     val.liveDecls = LV.DSetFact.remove(val.liveDecls, VD);
4097330f729Sjoerg     if (observer && DR)
4107330f729Sjoerg       observer->observerKill(DR);
4117330f729Sjoerg   }
4127330f729Sjoerg }
4137330f729Sjoerg 
4147330f729Sjoerg void TransferFunctions::
VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr * UE)4157330f729Sjoerg VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE)
4167330f729Sjoerg {
4177330f729Sjoerg   // While sizeof(var) doesn't technically extend the liveness of 'var', it
4187330f729Sjoerg   // does extent the liveness of metadata if 'var' is a VariableArrayType.
4197330f729Sjoerg   // We handle that special case here.
4207330f729Sjoerg   if (UE->getKind() != UETT_SizeOf || UE->isArgumentType())
4217330f729Sjoerg     return;
4227330f729Sjoerg 
4237330f729Sjoerg   const Expr *subEx = UE->getArgumentExpr();
4247330f729Sjoerg   if (subEx->getType()->isVariableArrayType()) {
4257330f729Sjoerg     assert(subEx->isLValue());
426*e038c9c4Sjoerg     val.liveExprs = LV.ESetFact.add(val.liveExprs, subEx->IgnoreParens());
4277330f729Sjoerg   }
4287330f729Sjoerg }
4297330f729Sjoerg 
VisitUnaryOperator(UnaryOperator * UO)4307330f729Sjoerg void TransferFunctions::VisitUnaryOperator(UnaryOperator *UO) {
4317330f729Sjoerg   // Treat ++/-- as a kill.
4327330f729Sjoerg   // Note we don't actually have to do anything if we don't have an observer,
4337330f729Sjoerg   // since a ++/-- acts as both a kill and a "use".
4347330f729Sjoerg   if (!observer)
4357330f729Sjoerg     return;
4367330f729Sjoerg 
4377330f729Sjoerg   switch (UO->getOpcode()) {
4387330f729Sjoerg   default:
4397330f729Sjoerg     return;
4407330f729Sjoerg   case UO_PostInc:
4417330f729Sjoerg   case UO_PostDec:
4427330f729Sjoerg   case UO_PreInc:
4437330f729Sjoerg   case UO_PreDec:
4447330f729Sjoerg     break;
4457330f729Sjoerg   }
4467330f729Sjoerg 
4477330f729Sjoerg   if (auto *DR = dyn_cast<DeclRefExpr>(UO->getSubExpr()->IgnoreParens())) {
4487330f729Sjoerg     const Decl *D = DR->getDecl();
4497330f729Sjoerg     if (isa<VarDecl>(D) || isa<BindingDecl>(D)) {
4507330f729Sjoerg       // Treat ++/-- as a kill.
4517330f729Sjoerg       observer->observerKill(DR);
4527330f729Sjoerg     }
4537330f729Sjoerg   }
4547330f729Sjoerg }
4557330f729Sjoerg 
4567330f729Sjoerg LiveVariables::LivenessValues
runOnBlock(const CFGBlock * block,LiveVariables::LivenessValues val,LiveVariables::Observer * obs)4577330f729Sjoerg LiveVariablesImpl::runOnBlock(const CFGBlock *block,
4587330f729Sjoerg                               LiveVariables::LivenessValues val,
4597330f729Sjoerg                               LiveVariables::Observer *obs) {
4607330f729Sjoerg 
4617330f729Sjoerg   TransferFunctions TF(*this, val, obs, block);
4627330f729Sjoerg 
4637330f729Sjoerg   // Visit the terminator (if any).
4647330f729Sjoerg   if (const Stmt *term = block->getTerminatorStmt())
4657330f729Sjoerg     TF.Visit(const_cast<Stmt*>(term));
4667330f729Sjoerg 
4677330f729Sjoerg   // Apply the transfer function for all Stmts in the block.
4687330f729Sjoerg   for (CFGBlock::const_reverse_iterator it = block->rbegin(),
4697330f729Sjoerg        ei = block->rend(); it != ei; ++it) {
4707330f729Sjoerg     const CFGElement &elem = *it;
4717330f729Sjoerg 
4727330f729Sjoerg     if (Optional<CFGAutomaticObjDtor> Dtor =
4737330f729Sjoerg             elem.getAs<CFGAutomaticObjDtor>()) {
4747330f729Sjoerg       val.liveDecls = DSetFact.add(val.liveDecls, Dtor->getVarDecl());
4757330f729Sjoerg       continue;
4767330f729Sjoerg     }
4777330f729Sjoerg 
4787330f729Sjoerg     if (!elem.getAs<CFGStmt>())
4797330f729Sjoerg       continue;
4807330f729Sjoerg 
4817330f729Sjoerg     const Stmt *S = elem.castAs<CFGStmt>().getStmt();
4827330f729Sjoerg     TF.Visit(const_cast<Stmt*>(S));
4837330f729Sjoerg     stmtsToLiveness[S] = val;
4847330f729Sjoerg   }
4857330f729Sjoerg   return val;
4867330f729Sjoerg }
4877330f729Sjoerg 
runOnAllBlocks(LiveVariables::Observer & obs)4887330f729Sjoerg void LiveVariables::runOnAllBlocks(LiveVariables::Observer &obs) {
4897330f729Sjoerg   const CFG *cfg = getImpl(impl).analysisContext.getCFG();
4907330f729Sjoerg   for (CFG::const_iterator it = cfg->begin(), ei = cfg->end(); it != ei; ++it)
4917330f729Sjoerg     getImpl(impl).runOnBlock(*it, getImpl(impl).blocksEndToLiveness[*it], &obs);
4927330f729Sjoerg }
4937330f729Sjoerg 
LiveVariables(void * im)4947330f729Sjoerg LiveVariables::LiveVariables(void *im) : impl(im) {}
4957330f729Sjoerg 
~LiveVariables()4967330f729Sjoerg LiveVariables::~LiveVariables() {
4977330f729Sjoerg   delete (LiveVariablesImpl*) impl;
4987330f729Sjoerg }
4997330f729Sjoerg 
500*e038c9c4Sjoerg std::unique_ptr<LiveVariables>
computeLiveness(AnalysisDeclContext & AC,bool killAtAssign)501*e038c9c4Sjoerg LiveVariables::computeLiveness(AnalysisDeclContext &AC, bool killAtAssign) {
5027330f729Sjoerg 
5037330f729Sjoerg   // No CFG?  Bail out.
5047330f729Sjoerg   CFG *cfg = AC.getCFG();
5057330f729Sjoerg   if (!cfg)
5067330f729Sjoerg     return nullptr;
5077330f729Sjoerg 
5087330f729Sjoerg   // The analysis currently has scalability issues for very large CFGs.
5097330f729Sjoerg   // Bail out if it looks too large.
5107330f729Sjoerg   if (cfg->getNumBlockIDs() > 300000)
5117330f729Sjoerg     return nullptr;
5127330f729Sjoerg 
5137330f729Sjoerg   LiveVariablesImpl *LV = new LiveVariablesImpl(AC, killAtAssign);
5147330f729Sjoerg 
5157330f729Sjoerg   // Construct the dataflow worklist.  Enqueue the exit block as the
5167330f729Sjoerg   // start of the analysis.
517*e038c9c4Sjoerg   BackwardDataflowWorklist worklist(*cfg, AC);
5187330f729Sjoerg   llvm::BitVector everAnalyzedBlock(cfg->getNumBlockIDs());
5197330f729Sjoerg 
5207330f729Sjoerg   // FIXME: we should enqueue using post order.
521*e038c9c4Sjoerg   for (const CFGBlock *B : cfg->nodes()) {
522*e038c9c4Sjoerg     worklist.enqueueBlock(B);
5237330f729Sjoerg   }
5247330f729Sjoerg 
5257330f729Sjoerg   while (const CFGBlock *block = worklist.dequeue()) {
5267330f729Sjoerg     // Determine if the block's end value has changed.  If not, we
5277330f729Sjoerg     // have nothing left to do for this block.
5287330f729Sjoerg     LivenessValues &prevVal = LV->blocksEndToLiveness[block];
5297330f729Sjoerg 
5307330f729Sjoerg     // Merge the values of all successor blocks.
5317330f729Sjoerg     LivenessValues val;
5327330f729Sjoerg     for (CFGBlock::const_succ_iterator it = block->succ_begin(),
5337330f729Sjoerg                                        ei = block->succ_end(); it != ei; ++it) {
5347330f729Sjoerg       if (const CFGBlock *succ = *it) {
5357330f729Sjoerg         val = LV->merge(val, LV->blocksBeginToLiveness[succ]);
5367330f729Sjoerg       }
5377330f729Sjoerg     }
5387330f729Sjoerg 
5397330f729Sjoerg     if (!everAnalyzedBlock[block->getBlockID()])
5407330f729Sjoerg       everAnalyzedBlock[block->getBlockID()] = true;
5417330f729Sjoerg     else if (prevVal.equals(val))
5427330f729Sjoerg       continue;
5437330f729Sjoerg 
5447330f729Sjoerg     prevVal = val;
5457330f729Sjoerg 
5467330f729Sjoerg     // Update the dataflow value for the start of this block.
5477330f729Sjoerg     LV->blocksBeginToLiveness[block] = LV->runOnBlock(block, val);
5487330f729Sjoerg 
5497330f729Sjoerg     // Enqueue the value to the predecessors.
5507330f729Sjoerg     worklist.enqueuePredecessors(block);
5517330f729Sjoerg   }
5527330f729Sjoerg 
553*e038c9c4Sjoerg   return std::unique_ptr<LiveVariables>(new LiveVariables(LV));
5547330f729Sjoerg }
5557330f729Sjoerg 
dumpBlockLiveness(const SourceManager & M)5567330f729Sjoerg void LiveVariables::dumpBlockLiveness(const SourceManager &M) {
5577330f729Sjoerg   getImpl(impl).dumpBlockLiveness(M);
5587330f729Sjoerg }
5597330f729Sjoerg 
dumpBlockLiveness(const SourceManager & M)5607330f729Sjoerg void LiveVariablesImpl::dumpBlockLiveness(const SourceManager &M) {
5617330f729Sjoerg   std::vector<const CFGBlock *> vec;
5627330f729Sjoerg   for (llvm::DenseMap<const CFGBlock *, LiveVariables::LivenessValues>::iterator
5637330f729Sjoerg        it = blocksEndToLiveness.begin(), ei = blocksEndToLiveness.end();
5647330f729Sjoerg        it != ei; ++it) {
5657330f729Sjoerg     vec.push_back(it->first);
5667330f729Sjoerg   }
5677330f729Sjoerg   llvm::sort(vec, [](const CFGBlock *A, const CFGBlock *B) {
5687330f729Sjoerg     return A->getBlockID() < B->getBlockID();
5697330f729Sjoerg   });
5707330f729Sjoerg 
5717330f729Sjoerg   std::vector<const VarDecl*> declVec;
5727330f729Sjoerg 
5737330f729Sjoerg   for (std::vector<const CFGBlock *>::iterator
5747330f729Sjoerg         it = vec.begin(), ei = vec.end(); it != ei; ++it) {
5757330f729Sjoerg     llvm::errs() << "\n[ B" << (*it)->getBlockID()
5767330f729Sjoerg                  << " (live variables at block exit) ]\n";
5777330f729Sjoerg 
5787330f729Sjoerg     LiveVariables::LivenessValues vals = blocksEndToLiveness[*it];
5797330f729Sjoerg     declVec.clear();
5807330f729Sjoerg 
5817330f729Sjoerg     for (llvm::ImmutableSet<const VarDecl *>::iterator si =
5827330f729Sjoerg           vals.liveDecls.begin(),
5837330f729Sjoerg           se = vals.liveDecls.end(); si != se; ++si) {
5847330f729Sjoerg       declVec.push_back(*si);
5857330f729Sjoerg     }
5867330f729Sjoerg 
5877330f729Sjoerg     llvm::sort(declVec, [](const Decl *A, const Decl *B) {
5887330f729Sjoerg       return A->getBeginLoc() < B->getBeginLoc();
5897330f729Sjoerg     });
5907330f729Sjoerg 
5917330f729Sjoerg     for (std::vector<const VarDecl*>::iterator di = declVec.begin(),
5927330f729Sjoerg          de = declVec.end(); di != de; ++di) {
5937330f729Sjoerg       llvm::errs() << " " << (*di)->getDeclName().getAsString()
5947330f729Sjoerg                    << " <";
5957330f729Sjoerg       (*di)->getLocation().print(llvm::errs(), M);
5967330f729Sjoerg       llvm::errs() << ">\n";
5977330f729Sjoerg     }
5987330f729Sjoerg   }
5997330f729Sjoerg   llvm::errs() << "\n";
6007330f729Sjoerg }
6017330f729Sjoerg 
dumpExprLiveness(const SourceManager & M)602*e038c9c4Sjoerg void LiveVariables::dumpExprLiveness(const SourceManager &M) {
603*e038c9c4Sjoerg   getImpl(impl).dumpExprLiveness(M);
6047330f729Sjoerg }
6057330f729Sjoerg 
dumpExprLiveness(const SourceManager & M)606*e038c9c4Sjoerg void LiveVariablesImpl::dumpExprLiveness(const SourceManager &M) {
6077330f729Sjoerg   // Don't iterate over blockEndsToLiveness directly because it's not sorted.
608*e038c9c4Sjoerg   for (const CFGBlock *B : *analysisContext.getCFG()) {
6097330f729Sjoerg 
610*e038c9c4Sjoerg     llvm::errs() << "\n[ B" << B->getBlockID()
611*e038c9c4Sjoerg                  << " (live expressions at block exit) ]\n";
612*e038c9c4Sjoerg     for (const Expr *E : blocksEndToLiveness[B].liveExprs) {
6137330f729Sjoerg       llvm::errs() << "\n";
614*e038c9c4Sjoerg       E->dump();
6157330f729Sjoerg     }
6167330f729Sjoerg     llvm::errs() << "\n";
6177330f729Sjoerg   }
6187330f729Sjoerg }
6197330f729Sjoerg 
getTag()6207330f729Sjoerg const void *LiveVariables::getTag() { static int x; return &x; }
getTag()6217330f729Sjoerg const void *RelaxedLiveVariables::getTag() { static int x; return &x; }
622