diff options
| -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; } | 

