diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-02-16 20:13:02 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-02-16 20:13:02 +0000 |
commit | b60736ec1405bb0a8dd40989f67ef4c93da068ab (patch) | |
tree | 5c43fbb7c9fc45f0f87e0e6795a86267dbd12f9d /clang/lib/Analysis/LiveVariables.cpp | |
parent | cfca06d7963fa0909f90483b42a6d7d194d01e08 (diff) | |
download | src-b60736ec1405bb0a8dd40989f67ef4c93da068ab.tar.gz src-b60736ec1405bb0a8dd40989f67ef4c93da068ab.zip |
Vendor import of llvm-project main 8e464dd76bef, the last commit beforevendor/llvm-project/llvmorg-12-init-17869-g8e464dd76bef
the upstream release/12.x branch was created.
Diffstat (limited to 'clang/lib/Analysis/LiveVariables.cpp')
-rw-r--r-- | clang/lib/Analysis/LiveVariables.cpp | 102 |
1 files changed, 52 insertions, 50 deletions
diff --git a/clang/lib/Analysis/LiveVariables.cpp b/clang/lib/Analysis/LiveVariables.cpp index d24c40b457b4..8cdc4cc5bd61 100644 --- a/clang/lib/Analysis/LiveVariables.cpp +++ b/clang/lib/Analysis/LiveVariables.cpp @@ -27,7 +27,7 @@ namespace { class LiveVariablesImpl { public: AnalysisDeclContext &analysisContext; - llvm::ImmutableSet<const Stmt *>::Factory SSetFact; + llvm::ImmutableSet<const Expr *>::Factory ESetFact; llvm::ImmutableSet<const VarDecl *>::Factory DSetFact; llvm::ImmutableSet<const BindingDecl *>::Factory BSetFact; llvm::DenseMap<const CFGBlock *, LiveVariables::LivenessValues> blocksEndToLiveness; @@ -45,16 +45,15 @@ public: LiveVariables::Observer *obs = nullptr); void dumpBlockLiveness(const SourceManager& M); - void dumpStmtLiveness(const SourceManager& M); + void dumpExprLiveness(const SourceManager& M); LiveVariablesImpl(AnalysisDeclContext &ac, bool KillAtAssign) - : analysisContext(ac), - SSetFact(false), // Do not canonicalize ImmutableSets by default. - DSetFact(false), // This is a *major* performance win. - BSetFact(false), - killAtAssign(KillAtAssign) {} + : analysisContext(ac), + ESetFact(false), // Do not canonicalize ImmutableSets by default. + DSetFact(false), // This is a *major* performance win. + BSetFact(false), killAtAssign(KillAtAssign) {} }; -} +} // namespace static LiveVariablesImpl &getImpl(void *x) { return *((LiveVariablesImpl *) x); @@ -64,8 +63,8 @@ static LiveVariablesImpl &getImpl(void *x) { // Operations and queries on LivenessValues. //===----------------------------------------------------------------------===// -bool LiveVariables::LivenessValues::isLive(const Stmt *S) const { - return liveStmts.contains(S); +bool LiveVariables::LivenessValues::isLive(const Expr *E) const { + return liveExprs.contains(E); } bool LiveVariables::LivenessValues::isLive(const VarDecl *D) const { @@ -97,10 +96,10 @@ LiveVariables::LivenessValues LiveVariablesImpl::merge(LiveVariables::LivenessValues valsA, LiveVariables::LivenessValues valsB) { - llvm::ImmutableSetRef<const Stmt *> - SSetRefA(valsA.liveStmts.getRootWithoutRetain(), SSetFact.getTreeFactory()), - SSetRefB(valsB.liveStmts.getRootWithoutRetain(), SSetFact.getTreeFactory()); - + llvm::ImmutableSetRef<const Expr *> SSetRefA( + valsA.liveExprs.getRootWithoutRetain(), ESetFact.getTreeFactory()), + SSetRefB(valsB.liveExprs.getRootWithoutRetain(), + ESetFact.getTreeFactory()); llvm::ImmutableSetRef<const VarDecl *> DSetRefA(valsA.liveDecls.getRootWithoutRetain(), DSetFact.getTreeFactory()), @@ -122,7 +121,7 @@ LiveVariablesImpl::merge(LiveVariables::LivenessValues valsA, } bool LiveVariables::LivenessValues::equals(const LivenessValues &V) const { - return liveStmts == V.liveStmts && liveDecls == V.liveDecls; + return liveExprs == V.liveExprs && liveDecls == V.liveDecls; } //===----------------------------------------------------------------------===// @@ -141,8 +140,8 @@ bool LiveVariables::isLive(const Stmt *S, const VarDecl *D) { return isAlwaysAlive(D) || getImpl(impl).stmtsToLiveness[S].isLive(D); } -bool LiveVariables::isLive(const Stmt *Loc, const Stmt *S) { - return getImpl(impl).stmtsToLiveness[Loc].isLive(S); +bool LiveVariables::isLive(const Stmt *Loc, const Expr *Val) { + return getImpl(impl).stmtsToLiveness[Loc].isLive(Val); } //===----------------------------------------------------------------------===// @@ -186,27 +185,27 @@ static const VariableArrayType *FindVA(QualType Ty) { return nullptr; } -static const Stmt *LookThroughStmt(const Stmt *S) { - while (S) { - if (const Expr *Ex = dyn_cast<Expr>(S)) - S = Ex->IgnoreParens(); - if (const FullExpr *FE = dyn_cast<FullExpr>(S)) { - S = FE->getSubExpr(); +static const Expr *LookThroughExpr(const Expr *E) { + while (E) { + if (const Expr *Ex = dyn_cast<Expr>(E)) + E = Ex->IgnoreParens(); + if (const FullExpr *FE = dyn_cast<FullExpr>(E)) { + E = FE->getSubExpr(); continue; } - if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(S)) { - S = OVE->getSourceExpr(); + if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) { + E = OVE->getSourceExpr(); continue; } break; } - return S; + return E; } -static void AddLiveStmt(llvm::ImmutableSet<const Stmt *> &Set, - llvm::ImmutableSet<const Stmt *>::Factory &F, - const Stmt *S) { - Set = F.add(Set, LookThroughStmt(S)); +static void AddLiveExpr(llvm::ImmutableSet<const Expr *> &Set, + llvm::ImmutableSet<const Expr *>::Factory &F, + const Expr *E) { + Set = F.add(Set, LookThroughExpr(E)); } void TransferFunctions::Visit(Stmt *S) { @@ -215,8 +214,8 @@ void TransferFunctions::Visit(Stmt *S) { StmtVisitor<TransferFunctions>::Visit(S); - if (isa<Expr>(S)) { - val.liveStmts = LV.SSetFact.remove(val.liveStmts, S); + if (const auto *E = dyn_cast<Expr>(S)) { + val.liveExprs = LV.ESetFact.remove(val.liveExprs, E); } // Mark all children expressions live. @@ -233,7 +232,7 @@ void TransferFunctions::Visit(Stmt *S) { // Include the implicit "this" pointer as being live. CXXMemberCallExpr *CE = cast<CXXMemberCallExpr>(S); if (Expr *ImplicitObj = CE->getImplicitObjectArgument()) { - AddLiveStmt(val.liveStmts, LV.SSetFact, ImplicitObj); + AddLiveExpr(val.liveExprs, LV.ESetFact, ImplicitObj); } break; } @@ -250,7 +249,7 @@ void TransferFunctions::Visit(Stmt *S) { if (const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl())) { for (const VariableArrayType* VA = FindVA(VD->getType()); VA != nullptr; VA = FindVA(VA->getElementType())) { - AddLiveStmt(val.liveStmts, LV.SSetFact, VA->getSizeExpr()); + AddLiveExpr(val.liveExprs, LV.ESetFact, VA->getSizeExpr()); } } break; @@ -263,7 +262,7 @@ void TransferFunctions::Visit(Stmt *S) { if (OpaqueValueExpr *OV = dyn_cast<OpaqueValueExpr>(child)) child = OV->getSourceExpr(); child = child->IgnoreParens(); - val.liveStmts = LV.SSetFact.add(val.liveStmts, child); + val.liveExprs = LV.ESetFact.add(val.liveExprs, child); return; } @@ -284,36 +283,39 @@ void TransferFunctions::Visit(Stmt *S) { // If one of the branches is an expression rather than a compound // statement, it will be bad if we mark it as live at the terminator // of the if-statement (i.e., immediately after the condition expression). - AddLiveStmt(val.liveStmts, LV.SSetFact, cast<IfStmt>(S)->getCond()); + AddLiveExpr(val.liveExprs, LV.ESetFact, cast<IfStmt>(S)->getCond()); return; } case Stmt::WhileStmtClass: { // If the loop body is an expression rather than a compound statement, // it will be bad if we mark it as live at the terminator of the loop // (i.e., immediately after the condition expression). - AddLiveStmt(val.liveStmts, LV.SSetFact, cast<WhileStmt>(S)->getCond()); + AddLiveExpr(val.liveExprs, LV.ESetFact, cast<WhileStmt>(S)->getCond()); return; } case Stmt::DoStmtClass: { // If the loop body is an expression rather than a compound statement, // it will be bad if we mark it as live at the terminator of the loop // (i.e., immediately after the condition expression). - AddLiveStmt(val.liveStmts, LV.SSetFact, cast<DoStmt>(S)->getCond()); + AddLiveExpr(val.liveExprs, LV.ESetFact, cast<DoStmt>(S)->getCond()); return; } case Stmt::ForStmtClass: { // If the loop body is an expression rather than a compound statement, // it will be bad if we mark it as live at the terminator of the loop // (i.e., immediately after the condition expression). - AddLiveStmt(val.liveStmts, LV.SSetFact, cast<ForStmt>(S)->getCond()); + AddLiveExpr(val.liveExprs, LV.ESetFact, cast<ForStmt>(S)->getCond()); return; } } + // HACK + FIXME: What is this? One could only guess that this is an attempt to + // fish for live values, for example, arguments from a call expression. + // Maybe we could take inspiration from UninitializedVariable analysis? for (Stmt *Child : S->children()) { - if (Child) - AddLiveStmt(val.liveStmts, LV.SSetFact, Child); + if (const auto *E = dyn_cast_or_null<Expr>(Child)) + AddLiveExpr(val.liveExprs, LV.ESetFact, E); } } @@ -416,7 +418,7 @@ VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE) const Expr *subEx = UE->getArgumentExpr(); if (subEx->getType()->isVariableArrayType()) { assert(subEx->isLValue()); - val.liveStmts = LV.SSetFact.add(val.liveStmts, subEx->IgnoreParens()); + val.liveExprs = LV.ESetFact.add(val.liveExprs, subEx->IgnoreParens()); } } @@ -613,19 +615,19 @@ void LiveVariablesImpl::dumpBlockLiveness(const SourceManager &M) { llvm::errs() << "\n"; } -void LiveVariables::dumpStmtLiveness(const SourceManager &M) { - getImpl(impl).dumpStmtLiveness(M); +void LiveVariables::dumpExprLiveness(const SourceManager &M) { + getImpl(impl).dumpExprLiveness(M); } -void LiveVariablesImpl::dumpStmtLiveness(const SourceManager &M) { +void LiveVariablesImpl::dumpExprLiveness(const SourceManager &M) { // Don't iterate over blockEndsToLiveness directly because it's not sorted. - for (auto I : *analysisContext.getCFG()) { + for (const CFGBlock *B : *analysisContext.getCFG()) { - llvm::errs() << "\n[ B" << I->getBlockID() - << " (live statements at block exit) ]\n"; - for (auto S : blocksEndToLiveness[I].liveStmts) { + llvm::errs() << "\n[ B" << B->getBlockID() + << " (live expressions at block exit) ]\n"; + for (const Expr *E : blocksEndToLiveness[B].liveExprs) { llvm::errs() << "\n"; - S->dump(); + E->dump(); } llvm::errs() << "\n"; } |