From eee18c38b6dd29c0e6982f5565fcbc3f76d1bf4d Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 19 Jul 2012 04:59:05 +0000 Subject: [PATCH] Simplify UninitializedValues.cpp by removing logic to handle the previous (imprecise) representation of '&&' and '||' in the CFG. This is no longer needed, and greatly simplifies the code. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160494 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/UninitializedValues.cpp | 167 ++++----------------------- 1 file changed, 25 insertions(+), 142 deletions(-) diff --git a/lib/Analysis/UninitializedValues.cpp b/lib/Analysis/UninitializedValues.cpp index acf695a1e9..858be4561c 100644 --- a/lib/Analysis/UninitializedValues.cpp +++ b/lib/Analysis/UninitializedValues.cpp @@ -98,38 +98,32 @@ static bool isAlwaysUninit(const Value v) { namespace { typedef llvm::PackedVector ValueVector; -typedef std::pair BVPair; class CFGBlockValues { const CFG &cfg; - BVPair *vals; + std::vector vals; ValueVector scratch; DeclToIndex declToIndex; - - ValueVector &lazyCreate(ValueVector *&bv); public: CFGBlockValues(const CFG &cfg); ~CFGBlockValues(); - + unsigned getNumEntries() const { return declToIndex.size(); } void computeSetOfDeclarations(const DeclContext &dc); - ValueVector &getValueVector(const CFGBlock *block, - const CFGBlock *dstBlock); - - BVPair &getValueVectors(const CFGBlock *block, bool shouldLazyCreate); + ValueVector &getValueVector(const CFGBlock *block) { + return *vals[block->getBlockID()]; + } void setAllScratchValues(Value V); void mergeIntoScratch(ValueVector const &source, bool isFirst); bool updateValueVectorWithScratch(const CFGBlock *block); - bool updateValueVectors(const CFGBlock *block, const BVPair &newVals); bool hasNoDeclarations() const { return declToIndex.size() == 0; } void resetScratch(); - ValueVector &getScratch() { return scratch; } ValueVector::reference operator[](const VarDecl *vd); @@ -137,91 +131,29 @@ public: const VarDecl *vd) { const llvm::Optional &idx = declToIndex.getValueIndex(vd); assert(idx.hasValue()); - return getValueVector(block, dstBlock)[idx.getValue()]; + return getValueVector(block)[idx.getValue()]; } }; } // end anonymous namespace -CFGBlockValues::CFGBlockValues(const CFG &c) : cfg(c), vals(0) { - unsigned n = cfg.getNumBlockIDs(); - if (!n) - return; - vals = new std::pair[n]; - memset((void*)vals, 0, sizeof(*vals) * n); -} +CFGBlockValues::CFGBlockValues(const CFG &c) : cfg(c), vals(0) {} CFGBlockValues::~CFGBlockValues() { - unsigned n = cfg.getNumBlockIDs(); - if (n == 0) - return; - for (unsigned i = 0; i < n; ++i) { - delete vals[i].first; - delete vals[i].second; - } - delete [] vals; + for (std::vector::iterator I = vals.begin(), E = vals.end(); + I != E; ++I) + delete *I; } void CFGBlockValues::computeSetOfDeclarations(const DeclContext &dc) { declToIndex.computeMap(dc); - scratch.resize(declToIndex.size()); -} - -ValueVector &CFGBlockValues::lazyCreate(ValueVector *&bv) { - if (!bv) - bv = new ValueVector(declToIndex.size()); - return *bv; -} - -/// This function pattern matches for a '&&' or '||' that appears at -/// the beginning of a CFGBlock that also (1) has a terminator and -/// (2) has no other elements. If such an expression is found, it is returned. -static const BinaryOperator *getLogicalOperatorInChain(const CFGBlock *block) { - if (block->empty()) - return 0; - - CFGElement front = block->front(); - const CFGStmt *cstmt = front.getAs(); - if (!cstmt) - return 0; - - const BinaryOperator *b = dyn_cast_or_null(cstmt->getStmt()); - - if (!b || !b->isLogicalOp()) - return 0; - - if (block->pred_size() == 2) { - if (block->getTerminatorCondition() == b) { - if (block->succ_size() == 2) - return b; - } - else if (block->size() == 1) - return b; - } - - return 0; -} - -ValueVector &CFGBlockValues::getValueVector(const CFGBlock *block, - const CFGBlock *dstBlock) { - unsigned idx = block->getBlockID(); - if (dstBlock && getLogicalOperatorInChain(block)) { - if (*block->succ_begin() == dstBlock) - return lazyCreate(vals[idx].first); - assert(*(block->succ_begin()+1) == dstBlock); - return lazyCreate(vals[idx].second); - } - - assert(vals[idx].second == 0); - return lazyCreate(vals[idx].first); -} - -BVPair &CFGBlockValues::getValueVectors(const clang::CFGBlock *block, - bool shouldLazyCreate) { - unsigned idx = block->getBlockID(); - lazyCreate(vals[idx].first); - if (shouldLazyCreate) - lazyCreate(vals[idx].second); - return vals[idx]; + unsigned decls = declToIndex.size(); + scratch.resize(decls); + unsigned n = cfg.getNumBlockIDs(); + if (!n) + return; + vals.resize(n); + for (unsigned i = 0; i < n; ++i) + vals[i] = new ValueVector(decls); } #if DEBUG_LOGGING @@ -249,7 +181,7 @@ void CFGBlockValues::mergeIntoScratch(ValueVector const &source, } bool CFGBlockValues::updateValueVectorWithScratch(const CFGBlock *block) { - ValueVector &dst = getValueVector(block, 0); + ValueVector &dst = getValueVector(block); bool changed = (dst != scratch); if (changed) dst = scratch; @@ -259,20 +191,6 @@ bool CFGBlockValues::updateValueVectorWithScratch(const CFGBlock *block) { return changed; } -bool CFGBlockValues::updateValueVectors(const CFGBlock *block, - const BVPair &newVals) { - BVPair &vals = getValueVectors(block, true); - bool changed = *newVals.first != *vals.first || - *newVals.second != *vals.second; - *vals.first = *newVals.first; - *vals.second = *newVals.second; -#if DEBUG_LOGGING - printVector(block, *vals.first, 1); - printVector(block, *vals.second, 2); -#endif - return changed; -} - void CFGBlockValues::resetScratch() { scratch.reset(); } @@ -768,42 +686,15 @@ static bool runOnBlock(const CFGBlock *block, const CFG &cfg, const ClassifyRefs &classification, llvm::BitVector &wasAnalyzed, UninitVariablesHandler *handler = 0) { - wasAnalyzed[block->getBlockID()] = true; - - if (const BinaryOperator *b = getLogicalOperatorInChain(block)) { - CFGBlock::const_pred_iterator itr = block->pred_begin(); - BVPair vA = vals.getValueVectors(*itr, false); - ++itr; - BVPair vB = vals.getValueVectors(*itr, false); - - BVPair valsAB; - - if (b->getOpcode() == BO_LAnd) { - // Merge the 'F' bits from the first and second. - vals.mergeIntoScratch(*(vA.second ? vA.second : vA.first), true); - vals.mergeIntoScratch(*(vB.second ? vB.second : vB.first), false); - valsAB.first = vA.first; - valsAB.second = &vals.getScratch(); - } else { - // Merge the 'T' bits from the first and second. - assert(b->getOpcode() == BO_LOr); - vals.mergeIntoScratch(*vA.first, true); - vals.mergeIntoScratch(*vB.first, false); - valsAB.first = &vals.getScratch(); - valsAB.second = vA.second ? vA.second : vA.first; - } - return vals.updateValueVectors(block, valsAB); - } - - // Default behavior: merge in values of predecessor blocks. vals.resetScratch(); + // Merge in values of predecessor blocks. bool isFirst = true; for (CFGBlock::const_pred_iterator I = block->pred_begin(), E = block->pred_end(); I != E; ++I) { const CFGBlock *pred = *I; if (wasAnalyzed[pred->getBlockID()]) { - vals.mergeIntoScratch(vals.getValueVector(pred, block), isFirst); + vals.mergeIntoScratch(vals.getValueVector(pred), isFirst); isFirst = false; } } @@ -828,9 +719,6 @@ void clang::runUninitializedVariablesAnalysis( vals.computeSetOfDeclarations(dc); if (vals.hasNoDeclarations()) return; -#if DEBUG_LOGGING - cfg.dump(dc.getParentASTContext().getLangOpts(), true); -#endif stats.NumVariablesAnalyzed = vals.getNumEntries(); @@ -840,15 +728,10 @@ void clang::runUninitializedVariablesAnalysis( // Mark all variables uninitialized at the entry. const CFGBlock &entry = cfg.getEntry(); - for (CFGBlock::const_succ_iterator i = entry.succ_begin(), - e = entry.succ_end(); i != e; ++i) { - if (const CFGBlock *succ = *i) { - ValueVector &vec = vals.getValueVector(&entry, succ); - const unsigned n = vals.getNumEntries(); - for (unsigned j = 0; j < n ; ++j) { - vec[j] = Uninitialized; - } - } + ValueVector &vec = vals.getValueVector(&entry); + const unsigned n = vals.getNumEntries(); + for (unsigned j = 0; j < n ; ++j) { + vec[j] = Uninitialized; } // Proceed with the workist. -- 2.40.0