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