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