diff options
-rw-r--r-- | include/clang/Analysis/Analyses/LiveVariables.h | 5 | ||||
-rw-r--r-- | include/clang/Analysis/AnalysisContext.h | 4 | ||||
-rw-r--r-- | lib/Analysis/AnalysisContext.cpp | 14 | ||||
-rw-r--r-- | lib/Analysis/LiveVariables.cpp | 14 |
4 files changed, 28 insertions, 9 deletions
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h index 44ab080acb..237fe14aed 100644 --- a/include/clang/Analysis/Analyses/LiveVariables.h +++ b/include/clang/Analysis/Analyses/LiveVariables.h @@ -41,8 +41,9 @@ struct LiveVariables_ValueTypes { ObserverTy* Observer; ValTy AlwaysLive; AnalysisContext *AC; + bool killAtAssign; - AnalysisDataTy() : Observer(NULL), AC(NULL) {} + AnalysisDataTy() : Observer(NULL), AC(NULL), killAtAssign(true) {} }; //===-----------------------------------------------------===// @@ -68,7 +69,7 @@ class LiveVariables : public DataflowValues<LiveVariables_ValueTypes, public: typedef LiveVariables_ValueTypes::ObserverTy ObserverTy; - LiveVariables(AnalysisContext &AC); + LiveVariables(AnalysisContext &AC, bool killAtAssign = true); /// IsLive - Return true if a variable is live at the end of a /// specified block. diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h index 6091db4be9..7d4d25f8b0 100644 --- a/include/clang/Analysis/AnalysisContext.h +++ b/include/clang/Analysis/AnalysisContext.h @@ -49,6 +49,7 @@ class AnalysisContext { CFG *cfg, *completeCFG; bool builtCFG, builtCompleteCFG; LiveVariables *liveness; + LiveVariables *relaxedLiveness; ParentMap *PM; PseudoConstantAnalysis *PCA; llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars; @@ -61,7 +62,7 @@ public: bool addehedges = false) : D(d), TU(tu), cfg(0), completeCFG(0), builtCFG(false), builtCompleteCFG(false), - liveness(0), PM(0), PCA(0), + liveness(0), relaxedLiveness(0), PM(0), PCA(0), ReferencedBlockVars(0), UseUnoptimizedCFG(useUnoptimizedCFG), AddEHEdges(addehedges) {} @@ -89,6 +90,7 @@ public: ParentMap &getParentMap(); PseudoConstantAnalysis *getPseudoConstantAnalysis(); LiveVariables *getLiveVariables(); + LiveVariables *getRelaxedLiveVariables(); typedef const VarDecl * const * referenced_decls_iterator; diff --git a/lib/Analysis/AnalysisContext.cpp b/lib/Analysis/AnalysisContext.cpp index 2c337f07c3..884cbc65f4 100644 --- a/lib/Analysis/AnalysisContext.cpp +++ b/lib/Analysis/AnalysisContext.cpp @@ -104,6 +104,20 @@ LiveVariables *AnalysisContext::getLiveVariables() { return liveness; } +LiveVariables *AnalysisContext::getRelaxedLiveVariables() { + if (!relaxedLiveness) { + CFG *c = getCFG(); + if (!c) + return 0; + + relaxedLiveness = new LiveVariables(*this, false); + relaxedLiveness->runOnCFG(*c); + relaxedLiveness->runOnAllBlocks(*c, 0, true); + } + + return relaxedLiveness; +} + AnalysisContext *AnalysisContextManager::getContext(const Decl *D, idx::TranslationUnit *TU) { AnalysisContext *&AC = Contexts[D]; diff --git a/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp index 3011fd0dee..47b2e3d604 100644 --- a/lib/Analysis/LiveVariables.cpp +++ b/lib/Analysis/LiveVariables.cpp @@ -77,12 +77,13 @@ public: }; } // end anonymous namespace -LiveVariables::LiveVariables(AnalysisContext &AC) { +LiveVariables::LiveVariables(AnalysisContext &AC, bool killAtAssign) { // Register all referenced VarDecls. CFG &cfg = *AC.getCFG(); getAnalysisData().setCFG(cfg); getAnalysisData().setContext(AC.getASTContext()); getAnalysisData().AC = &AC; + getAnalysisData().killAtAssign = killAtAssign; RegisterDecls R(getAnalysisData()); cfg.VisitBlockStmts(R); @@ -260,12 +261,13 @@ void TransferFuncs::VisitAssign(BinaryOperator* B) { if (DR->getDecl()->getType()->isReferenceType()) { VisitDeclRefExpr(DR); } else { - // Update liveness inforamtion. - unsigned bit = AD.getIdx(DR->getDecl()); - LiveState.getDeclBit(bit) = Dead | AD.AlwaysLive.getDeclBit(bit); - - if (AD.Observer) { AD.Observer->ObserverKill(DR); } + if (AD.killAtAssign) { + // Update liveness inforamtion. + unsigned bit = AD.getIdx(DR->getDecl()); + LiveState.getDeclBit(bit) = Dead | AD.AlwaysLive.getDeclBit(bit); + if (AD.Observer) { AD.Observer->ObserverKill(DR); } + } // Handle things like +=, etc., which also generate "uses" // of a variable. Do this just by visiting the subexpression. if (B->getOpcode() != BO_Assign) |