r214064 - Factoring DataflowWorklist out of LiveVariables and UninitializedValues analyses

Hal Finkel hfinkel at anl.gov
Mon Jul 28 05:11:37 PDT 2014


----- Original Message -----
> From: "Artyom Skrobov" <Artyom.Skrobov at arm.com>
> To: cfe-commits at cs.uiuc.edu
> Sent: Monday, July 28, 2014 3:47:39 AM
> Subject: r214064 - Factoring DataflowWorklist out of LiveVariables and	UninitializedValues analyses
> 
> Author: askrobov
> Date: Mon Jul 28 03:47:38 2014
> New Revision: 214064
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=214064&view=rev
> Log:
> Factoring DataflowWorklist out of LiveVariables and
> UninitializedValues analyses
> 
> Added:
>     cfe/trunk/include/clang/Analysis/Analyses/DataflowWorklist.h
>     cfe/trunk/lib/Analysis/DataflowWorklist.cpp
> Modified:
>     cfe/trunk/lib/Analysis/CMakeLists.txt
>     cfe/trunk/lib/Analysis/LiveVariables.cpp
>     cfe/trunk/lib/Analysis/UninitializedValues.cpp
> 
> Added: cfe/trunk/include/clang/Analysis/Analyses/DataflowWorklist.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/DataflowWorklist.h?rev=214064&view=auto
> ==============================================================================
> --- cfe/trunk/include/clang/Analysis/Analyses/DataflowWorklist.h
> (added)
> +++ cfe/trunk/include/clang/Analysis/Analyses/DataflowWorklist.h Mon
> Jul 28 03:47:38 2014
> @@ -0,0 +1,53 @@
> +//===- DataflowWorklist.h - worklist for dataflow analysis
> --------*- C++ --*-//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open
> Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// DataflowWorklist is used in LiveVariables and UninitializedValues
> analyses

We should have a description here of what this code does, not just where it's used. One can get some idea by reading the comments above DataflowWorklist::enqueueSuccessors in the source file, but it is not clear that gives a complete picture.

 -Hal

> +//
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_CLANG_DATAFLOW_WORKLIST
> +#define LLVM_CLANG_DATAFLOW_WORKLIST
> +
> +#include "clang/Analysis/Analyses/PostOrderCFGView.h"
> +
> +namespace clang {
> +
> +class DataflowWorklist {
> +  PostOrderCFGView::iterator PO_I, PO_E;
> +  PostOrderCFGView::BlockOrderCompare comparator;
> +  SmallVector<const CFGBlock *, 20> worklist;
> +  llvm::BitVector enqueuedBlocks;
> +
> +  DataflowWorklist(const CFG &cfg, PostOrderCFGView &view)
> +    : PO_I(view.begin()), PO_E(view.end()),
> +      comparator(view.getComparator()),
> +      enqueuedBlocks(cfg.getNumBlockIDs(), true) {
> +        // Treat the first block as already analyzed.
> +        if (PO_I != PO_E) {
> +          assert(*PO_I == &cfg.getEntry());
> +          enqueuedBlocks[(*PO_I)->getBlockID()] = false;
> +          ++PO_I;
> +        }
> +      }
> +
> +public:
> +  DataflowWorklist(const CFG &cfg, AnalysisDeclContext &Ctx)
> +    : DataflowWorklist(cfg, *Ctx.getAnalysis<PostOrderCFGView>()) {}
> +
> +  void enqueueBlock(const CFGBlock *block);
> +  void enqueuePredecessors(const CFGBlock *block);
> +  void enqueueSuccessors(const CFGBlock *block);
> +  const CFGBlock *dequeue();
> +
> +  void sortWorklist();
> +};
> +
> +} // end clang namespace
> +
> +#endif
> 
> Modified: cfe/trunk/lib/Analysis/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CMakeLists.txt?rev=214064&r1=214063&r2=214064&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Analysis/CMakeLists.txt (original)
> +++ cfe/trunk/lib/Analysis/CMakeLists.txt Mon Jul 28 03:47:38 2014
> @@ -12,6 +12,7 @@ add_clang_library(clangAnalysis
>    CocoaConventions.cpp
>    Consumed.cpp
>    Dominators.cpp
> +  DataflowWorklist.cpp
>    FormatString.cpp
>    LiveVariables.cpp
>    ObjCNoReturn.cpp
> 
> Added: cfe/trunk/lib/Analysis/DataflowWorklist.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/DataflowWorklist.cpp?rev=214064&view=auto
> ==============================================================================
> --- cfe/trunk/lib/Analysis/DataflowWorklist.cpp (added)
> +++ cfe/trunk/lib/Analysis/DataflowWorklist.cpp Mon Jul 28 03:47:38
> 2014
> @@ -0,0 +1,92 @@
> +//===- DataflowWorklist.cpp - worklist for dataflow analysis
> ------*- C++ --*-//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open
> Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// DataflowWorklist is used in LiveVariables and UninitializedValues
> analyses
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include "clang/Analysis/Analyses/DataflowWorklist.h"
> +
> +using namespace clang;
> +
> +// Marking a block as enqueued means that it cannot be re-added to
> the worklist,
> +// but it doesn't control when the algorithm terminates.
> +// Initially, enqueuedBlocks is set to true for all blocks;
> +// that's not because everything is added initially to the worklist,
> +// but instead, to cause the forward analysis to follow the reverse
> post order
> +// until we enqueue something on the worklist.
> +void DataflowWorklist::enqueueBlock(const clang::CFGBlock *block) {
> +  if (block && !enqueuedBlocks[block->getBlockID()]) {
> +    enqueuedBlocks[block->getBlockID()] = true;
> +    worklist.push_back(block);
> +  }
> +}
> +
> +// The forward analysis alternates between essentially two
> worklists.
> +// A prioritization worklist (SmallVector<const CFGBlock *>
> worklist)
> +// is consulted first, and if it's empty, we consult the reverse
> +// post-order traversal (PostOrderCFGView::iterator PO_I).
> +// The prioritization worklist is used to prioritize analyzing from
> +// the beginning, or to prioritize updates fed by back edges.
> +// Typically, what gets enqueued on the worklist are back edges,
> which
> +// we want to prioritize analyzing first, because that causes
> dataflow facts
> +// to flow up the graph, which we then want to propagate forward.
> +// In practice this can cause the analysis to converge much faster.
> +void DataflowWorklist::enqueueSuccessors(const clang::CFGBlock
> *block) {
> +  for (CFGBlock::const_succ_iterator I = block->succ_begin(),
> +       E = block->succ_end(); I != E; ++I) {
> +    enqueueBlock(*I);
> +  }
> +}
> +
> +// The reverse analysis uses a simple re-sorting of the worklist to
> +// reprioritize it.  It's not as efficient as the two-worklists
> approach,
> +// but it isn't performance sensitive since it's used by the static
> analyzer,
> +// and the static analyzer does far more work that dwarfs the work
> done here.
> +// TODO: It would still be nice to use the same approach for both
> analyses.
> +void DataflowWorklist::enqueuePredecessors(const clang::CFGBlock
> *block) {
> +  const unsigned OldWorklistSize = worklist.size();
> +  for (CFGBlock::const_pred_iterator I = block->pred_begin(),
> +       E = block->pred_end(); I != E; ++I) {
> +    enqueueBlock(*I);
> +  }
> +
> +  if (OldWorklistSize == 0 || OldWorklistSize == worklist.size())
> +    return;
> +
> +  sortWorklist();
> +}
> +
> +const CFGBlock *DataflowWorklist::dequeue() {
> +  const CFGBlock *B = nullptr;
> +
> +  // First dequeue from the worklist.  This can represent
> +  // updates along backedges that we want propagated as quickly as
> possible.
> +  if (!worklist.empty())
> +    B = worklist.pop_back_val();
> +
> +  // Next dequeue from the initial reverse post order.  This is the
> +  // theoretical ideal in the presence of no back edges.
> +  else if (PO_I != PO_E) {
> +    B = *PO_I;
> +    ++PO_I;
> +  }
> +  else {
> +    return nullptr;
> +  }
> +
> +  assert(enqueuedBlocks[B->getBlockID()] == true);
> +  enqueuedBlocks[B->getBlockID()] = false;
> +  return B;
> +}
> +
> +void DataflowWorklist::sortWorklist() {
> +  std::sort(worklist.begin(), worklist.end(), comparator);
> +}
> +
> 
> Modified: cfe/trunk/lib/Analysis/LiveVariables.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/LiveVariables.cpp?rev=214064&r1=214063&r2=214064&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Analysis/LiveVariables.cpp (original)
> +++ cfe/trunk/lib/Analysis/LiveVariables.cpp Mon Jul 28 03:47:38 2014
> @@ -14,11 +14,10 @@
>  #include "clang/Analysis/Analyses/LiveVariables.h"
>  #include "clang/AST/Stmt.h"
>  #include "clang/AST/StmtVisitor.h"
> -#include "clang/Analysis/Analyses/PostOrderCFGView.h"
> +#include "clang/Analysis/Analyses/DataflowWorklist.h"
>  #include "clang/Analysis/AnalysisContext.h"
>  #include "clang/Analysis/CFG.h"
>  #include "llvm/ADT/DenseMap.h"
> -#include "llvm/ADT/PostOrderIterator.h"
>  #include "llvm/Support/raw_ostream.h"
>  #include <algorithm>
>  #include <vector>
> @@ -26,59 +25,6 @@
>  using namespace clang;
>  
>  namespace {
> -
> -class DataflowWorklist {
> -  SmallVector<const CFGBlock *, 20> worklist;
> -  llvm::BitVector enqueuedBlocks;
> -  PostOrderCFGView *POV;
> -public:
> -  DataflowWorklist(const CFG &cfg, AnalysisDeclContext &Ctx)
> -    : enqueuedBlocks(cfg.getNumBlockIDs()),
> -      POV(Ctx.getAnalysis<PostOrderCFGView>()) {}
> -
> -  void enqueueBlock(const CFGBlock *block);
> -  void enqueuePredecessors(const CFGBlock *block);
> -
> -  const CFGBlock *dequeue();
> -
> -  void sortWorklist();
> -};
> -
> -}
> -
> -void DataflowWorklist::enqueueBlock(const clang::CFGBlock *block) {
> -  if (block && !enqueuedBlocks[block->getBlockID()]) {
> -    enqueuedBlocks[block->getBlockID()] = true;
> -    worklist.push_back(block);
> -  }
> -}
> -
> -void DataflowWorklist::enqueuePredecessors(const clang::CFGBlock
> *block) {
> -  const unsigned OldWorklistSize = worklist.size();
> -  for (CFGBlock::const_pred_iterator I = block->pred_begin(),
> -       E = block->pred_end(); I != E; ++I) {
> -    enqueueBlock(*I);
> -  }
> -
> -  if (OldWorklistSize == 0 || OldWorklistSize == worklist.size())
> -    return;
> -
> -  sortWorklist();
> -}
> -
> -void DataflowWorklist::sortWorklist() {
> -  std::sort(worklist.begin(), worklist.end(), POV->getComparator());
> -}
> -
> -const CFGBlock *DataflowWorklist::dequeue() {
> -  if (worklist.empty())
> -    return nullptr;
> -  const CFGBlock *b = worklist.pop_back_val();
> -  enqueuedBlocks[b->getBlockID()] = false;
> -  return b;
> -}
> -
> -namespace {
>  class LiveVariablesImpl {
>  public:
>    AnalysisDeclContext &analysisContext;
> 
> Modified: cfe/trunk/lib/Analysis/UninitializedValues.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/UninitializedValues.cpp?rev=214064&r1=214063&r2=214064&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Analysis/UninitializedValues.cpp (original)
> +++ cfe/trunk/lib/Analysis/UninitializedValues.cpp Mon Jul 28
> 03:47:38 2014
> @@ -15,7 +15,7 @@
>  #include "clang/AST/Attr.h"
>  #include "clang/AST/Decl.h"
>  #include "clang/AST/StmtVisitor.h"
> -#include "clang/Analysis/Analyses/PostOrderCFGView.h"
> +#include "clang/Analysis/Analyses/DataflowWorklist.h"
>  #include "clang/Analysis/Analyses/UninitializedValues.h"
>  #include "clang/Analysis/AnalysisContext.h"
>  #include "clang/Analysis/CFG.h"
> @@ -199,66 +199,6 @@ ValueVector::reference CFGBlockValues::o
>  }
>  
>  //------------------------------------------------------------------------====//
> -// Worklist: worklist for dataflow analysis.
> -//====------------------------------------------------------------------------//
> -
> -namespace {
> -class DataflowWorklist {
> -  PostOrderCFGView::iterator PO_I, PO_E;
> -  SmallVector<const CFGBlock *, 20> worklist;
> -  llvm::BitVector enqueuedBlocks;
> -public:
> -  DataflowWorklist(const CFG &cfg, PostOrderCFGView &view)
> -    : PO_I(view.begin()), PO_E(view.end()),
> -      enqueuedBlocks(cfg.getNumBlockIDs(), true) {
> -        // Treat the first block as already analyzed.
> -        if (PO_I != PO_E) {
> -          assert(*PO_I == &cfg.getEntry());
> -          enqueuedBlocks[(*PO_I)->getBlockID()] = false;
> -          ++PO_I;
> -        }
> -      }
> -
> -  void enqueueSuccessors(const CFGBlock *block);
> -  const CFGBlock *dequeue();
> -};
> -}
> -
> -void DataflowWorklist::enqueueSuccessors(const clang::CFGBlock
> *block) {
> -  for (CFGBlock::const_succ_iterator I = block->succ_begin(),
> -       E = block->succ_end(); I != E; ++I) {
> -    const CFGBlock *Successor = *I;
> -    if (!Successor || enqueuedBlocks[Successor->getBlockID()])
> -      continue;
> -    worklist.push_back(Successor);
> -    enqueuedBlocks[Successor->getBlockID()] = true;
> -  }
> -}
> -
> -const CFGBlock *DataflowWorklist::dequeue() {
> -  const CFGBlock *B = nullptr;
> -
> -  // First dequeue from the worklist.  This can represent
> -  // updates along backedges that we want propagated as quickly as
> possible.
> -  if (!worklist.empty())
> -    B = worklist.pop_back_val();
> -
> -  // Next dequeue from the initial reverse post order.  This is the
> -  // theoretical ideal in the presence of no back edges.
> -  else if (PO_I != PO_E) {
> -    B = *PO_I;
> -    ++PO_I;
> -  }
> -  else {
> -    return nullptr;
> -  }
> -
> -  assert(enqueuedBlocks[B->getBlockID()] == true);
> -  enqueuedBlocks[B->getBlockID()] = false;
> -  return B;
> -}
> -
> -//------------------------------------------------------------------------====//
>  // Classification of DeclRefExprs as use or initialization.
>  //====------------------------------------------------------------------------//
>  
> @@ -831,7 +771,7 @@ void clang::runUninitializedVariablesAna
>    }
>  
>    // Proceed with the workist.
> -  DataflowWorklist worklist(cfg,
> *ac.getAnalysis<PostOrderCFGView>());
> +  DataflowWorklist worklist(cfg, ac);
>    llvm::BitVector previouslyVisited(cfg.getNumBlockIDs());
>    worklist.enqueueSuccessors(&cfg.getEntry());
>    llvm::BitVector wasAnalyzed(cfg.getNumBlockIDs(), false);
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
> 

-- 
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory



More information about the cfe-commits mailing list