diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/Analysis/DeadStores.cpp | 23 | ||||
| -rw-r--r-- | clang/Analysis/LiveVariables.cpp | 74 | ||||
| -rw-r--r-- | clang/Driver/ASTStreamers.cpp | 3 | ||||
| -rw-r--r-- | clang/include/clang/Analysis/LiveVariables.h | 24 |
4 files changed, 87 insertions, 37 deletions
diff --git a/clang/Analysis/DeadStores.cpp b/clang/Analysis/DeadStores.cpp index 4073eccf60b..e0922eede94 100644 --- a/clang/Analysis/DeadStores.cpp +++ b/clang/Analysis/DeadStores.cpp @@ -36,29 +36,28 @@ public: return; // Is this an assignment to a variable? - if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(B->getLHS())) { + if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(B->getLHS())) // Is the variable live? - if (!L.isLive(Live,DR->getDecl())) { + if (!L.isLive(Live,cast<VarDecl>(DR->getDecl()))) { SourceRange R = B->getRHS()->getSourceRange(); PP.getDiagnostics().Report(DR->getSourceRange().Begin(), diag::warn_dead_store, 0, 0, &R,1); } - } } else if(DeclStmt* DS = dyn_cast<DeclStmt>(S)) { // Iterate through the decls. Warn if any of them (which have // initializers) are not live. - for (Decl* D = DS->getDecl() ; D != NULL ; D = D->getNextDeclarator()) - if (VarDecl* V = dyn_cast<VarDecl>(D)) - if (Expr* E = V->getInit()) - if (!L.isLive(Live,D)) { - SourceRange R = E->getSourceRange(); - PP.getDiagnostics().Report(D->getLocation(), - diag::warn_dead_store, 0, 0, - &R,1); - } + for (VarDecl* V = cast<VarDecl>(DS->getDecl()); V != NULL ; + V = cast<VarDecl>(V->getNextDeclarator())) + if (Expr* E = V->getInit()) + if (!L.isLive(Live,V)) { + SourceRange R = E->getSourceRange(); + PP.getDiagnostics().Report(V->getLocation(), + diag::warn_dead_store, 0, 0, + &R,1); + } } } }; diff --git a/clang/Analysis/LiveVariables.cpp b/clang/Analysis/LiveVariables.cpp index 1d06c26af84..4324b3ec567 100644 --- a/clang/Analysis/LiveVariables.cpp +++ b/clang/Analysis/LiveVariables.cpp @@ -65,10 +65,12 @@ void RegisterDecls::RegisterDeclChain(Decl* D) { } void RegisterDecls::Register(Decl* D) { - LiveVariables::VPair& VP = L.getVarInfoMap()[const_cast<const Decl*>(D)]; + if (VarDecl* V = dyn_cast<VarDecl>(D)) { + LiveVariables::VPair& VP = L.getVarInfoMap()[V]; - VP.V.AliveBlocks.reserve(cfg.getNumBlockIDs()); - VP.Idx = L.getNumDecls()++; + VP.V.AliveBlocks.resize(cfg.getNumBlockIDs()); + VP.Idx = L.getNumDecls()++; + } } void RegisterDecls::RegisterUsedDecls() { @@ -135,7 +137,7 @@ public: void VisitDeclStmt(DeclStmt* DS); void VisitUnaryOperator(UnaryOperator* U); - unsigned getIdx(const Decl* D) { + unsigned getIdx(const VarDecl* D) { LiveVariables::VarInfoMap& V = L.getVarInfoMap(); LiveVariables::VarInfoMap::iterator I = V.find(D); assert (I != V.end()); @@ -144,7 +146,7 @@ public: bool ProcessBlock(const CFGBlock* B); llvm::BitVector* getBlockEntryLiveness(const CFGBlock* B); - LiveVariables::VarInfo& KillVar(Decl* D); + LiveVariables::VarInfo& KillVar(VarDecl* D); }; void LivenessTFuncs::VisitStmt(Stmt* S) { @@ -163,7 +165,8 @@ void LivenessTFuncs::VisitDeclRefExpr(DeclRefExpr* DR) { Observer->ObserveStmt(DR,L,Live); // Register a use of the variable. - Live.set(getIdx(DR->getDecl())); + if (VarDecl* V = dyn_cast<VarDecl>(DR->getDecl())) + Live.set(getIdx(V)); } void LivenessTFuncs::VisitStmtExpr(StmtExpr* S) { @@ -205,7 +208,8 @@ void LivenessTFuncs::VisitUnaryOperator(UnaryOperator* U) { } else if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S)) { // Treat the --/++/& operator as a kill. - LiveVariables::VarInfo& V = KillVar(DR->getDecl()); + LiveVariables::VarInfo& V = + KillVar(cast<VarDecl>(DR->getDecl())); if (!blockPreviouslyProcessed) V.AddKill(CurrentStmt,DR); @@ -225,7 +229,7 @@ void LivenessTFuncs::VisitUnaryOperator(UnaryOperator* U) { } } -LiveVariables::VarInfo& LivenessTFuncs::KillVar(Decl* D) { +LiveVariables::VarInfo& LivenessTFuncs::KillVar(VarDecl* D) { LiveVariables::VarInfoMap::iterator I = L.getVarInfoMap().find(D); assert (I != L.getVarInfoMap().end() && @@ -247,7 +251,7 @@ void LivenessTFuncs::VisitAssign(BinaryOperator* B) { Stmt* LHS = B->getLHS(); if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS)) { - LiveVariables::VarInfo& V = KillVar(DR->getDecl()); + LiveVariables::VarInfo& V = KillVar(cast<VarDecl>(DR->getDecl())); // We only need to register kills once, so we check if this block // has been previously processed. @@ -272,7 +276,7 @@ void LivenessTFuncs::VisitDeclStmt(DeclStmt* DS) { // in the sense that the value is obliterated, so we do not register // DeclStmts as a "kill site" for a variable. for (Decl* D = DS->getDecl(); D != NULL ; D = D->getNextDeclarator()) - KillVar(D); + KillVar(cast<VarDecl>(D)); } llvm::BitVector* LivenessTFuncs::getBlockEntryLiveness(const CFGBlock* B) { @@ -385,7 +389,7 @@ void LiveVariables::runOnBlock(const CFGBlock* B, // liveness queries // -bool LiveVariables::isLive(const CFGBlock* B, const Decl* D) const { +bool LiveVariables::isLive(const CFGBlock* B, const VarDecl* D) const { BlockLivenessMap::const_iterator I = LiveAtBlockEntryMap.find(B); assert (I != LiveAtBlockEntryMap.end()); @@ -395,13 +399,13 @@ bool LiveVariables::isLive(const CFGBlock* B, const Decl* D) const { return I->second[VI->second.Idx]; } -bool LiveVariables::isLive(llvm::BitVector& Live, const Decl* D) const { +bool LiveVariables::isLive(llvm::BitVector& Live, const VarDecl* D) const { VarInfoMap::const_iterator VI = VarInfos.find(D); assert (VI != VarInfos.end()); return Live[VI->second.Idx]; } -bool LiveVariables::KillsVar(const Stmt* S, const Decl* D) const { +bool LiveVariables::KillsVar(const Stmt* S, const VarDecl* D) const { VarInfoMap::const_iterator VI = VarInfos.find(D); assert (VI != VarInfos.end()); @@ -413,13 +417,13 @@ bool LiveVariables::KillsVar(const Stmt* S, const Decl* D) const { return false; } -LiveVariables::VarInfo& LiveVariables::getVarInfo(const Decl* D) { +LiveVariables::VarInfo& LiveVariables::getVarInfo(const VarDecl* D) { VarInfoMap::iterator VI = VarInfos.find(D); assert (VI != VarInfos.end()); return VI->second.V; } -const LiveVariables::VarInfo& LiveVariables::getVarInfo(const Decl* D) const { +const LiveVariables::VarInfo& LiveVariables::getVarInfo(const VarDecl* D) const{ return const_cast<LiveVariables*>(this)->getVarInfo(D); } @@ -465,4 +469,44 @@ void LiveVariables::dumpBlockLiveness(SourceManager& M) const { dumpLiveness(I->second,M); } + + fprintf(stderr,"\n"); +} + +void LiveVariables::dumpVarLiveness(SourceManager& SM) const { + + for (VarInfoMap::iterator I = VarInfos.begin(), E=VarInfos.end(); I!=E; ++I) { + SourceLocation PhysLoc = SM.getPhysicalLoc(I->first->getLocation()); + + fprintf(stderr, "[ %s <%s:%u:%u> ]\n", + I->first->getIdentifier()->getName(), + SM.getSourceName(PhysLoc), + SM.getLineNumber(PhysLoc), + SM.getColumnNumber(PhysLoc)); + + I->second.V.Dump(SM); + } +} + +void LiveVariables::VarInfo::Dump(SourceManager& SM) const { + fprintf(stderr," Blocks Alive:"); + for (unsigned i = 0; i < AliveBlocks.size(); ++i) { + if (i % 5 == 0) + fprintf(stderr,"\n "); + + fprintf(stderr," B%d", i); + } + + fprintf(stderr,"\n Kill Sites:\n"); + for (KillsSet::const_iterator I = Kills.begin(), E = Kills.end(); I!=E; ++I) { + SourceLocation PhysLoc = + SM.getPhysicalLoc(I->second->getSourceRange().Begin()); + + fprintf(stderr, " <%s:%u:%u>\n", + SM.getSourceName(PhysLoc), + SM.getLineNumber(PhysLoc), + SM.getColumnNumber(PhysLoc)); + } + + fprintf(stderr,"\n"); }
\ No newline at end of file diff --git a/clang/Driver/ASTStreamers.cpp b/clang/Driver/ASTStreamers.cpp index 59be1b36e7a..d4c55ad681a 100644 --- a/clang/Driver/ASTStreamers.cpp +++ b/clang/Driver/ASTStreamers.cpp @@ -240,7 +240,8 @@ namespace { virtual void VisitCFG(CFG& C) { LiveVariables L; L.runOnCFG(C); - L.dumpBlockLiveness(PP.getSourceManager()); + L.dumpBlockLiveness(PP.getSourceManager()); + L.dumpVarLiveness(PP.getSourceManager()); } }; } // end anonymous namespace diff --git a/clang/include/clang/Analysis/LiveVariables.h b/clang/include/clang/Analysis/LiveVariables.h index 18b6b18683a..7d1d0210a06 100644 --- a/clang/include/clang/Analysis/LiveVariables.h +++ b/clang/include/clang/Analysis/LiveVariables.h @@ -22,7 +22,7 @@ namespace clang { class Stmt; class DeclRefExpr; - class Decl; + class VarDecl; class CFG; class CFGBlock; class SourceManager; @@ -45,7 +45,7 @@ public: /// then V contains the liveness information after the execution of /// the given block. virtual void ObserveBlockExit(const CFGBlock* B, LiveVariables& L, - llvm::BitVector& V); + llvm::BitVector& V); }; class LiveVariables { @@ -70,7 +70,10 @@ public: void AddKill(Stmt* S, DeclRefExpr* DR) { Kills.push_back(std::make_pair(const_cast<const Stmt*>(S), const_cast<const DeclRefExpr*>(DR))); - } + } + + // Dump - prints VarInfo data to stderr. + void Dump(SourceManager& M) const; }; struct VPair { @@ -78,7 +81,7 @@ public: unsigned Idx; }; - typedef llvm::DenseMap<const Decl*, VPair > VarInfoMap; + typedef llvm::DenseMap<const VarDecl*, VPair > VarInfoMap; typedef llvm::DenseMap<const CFGBlock*, llvm::BitVector > BlockLivenessMap; public: @@ -96,22 +99,22 @@ public: /// KillsVar - Return true if the specified statement kills the /// specified variable. - bool KillsVar(const Stmt* S, const Decl* D) const; + bool KillsVar(const Stmt* S, const VarDecl* D) const; /// IsLive - Return true if a variable is live at beginning of a specified // block. - bool isLive(const CFGBlock* B, const Decl* D) const; + bool isLive(const CFGBlock* B, const VarDecl* D) const; /// IsLive - Return true if a variable is live according to the provided /// livness bitvector. This is typically used by classes that subclass /// LiveVariablesObserver. - bool isLive(llvm::BitVector& V, const Decl* D) const; + bool isLive(llvm::BitVector& V, const VarDecl* D) const; /// getVarInfo - Return the liveness information associated with a given /// variable. - VarInfo& getVarInfo(const Decl* D); + VarInfo& getVarInfo(const VarDecl* D); - const VarInfo& getVarInfo(const Decl* D) const; + const VarInfo& getVarInfo(const VarDecl* D) const; /// getVarInfoMap VarInfoMap& getVarInfoMap() { return VarInfos; } @@ -124,6 +127,9 @@ public: // dumpBlockLiveness void dumpBlockLiveness(SourceManager& M) const; + // dumpVarLiveness + void dumpVarLiveness(SourceManager& M) const; + // getLiveAtBlockEntryMap BlockLivenessMap& getLiveAtBlockEntryMap() { return LiveAtBlockEntryMap; } |

