void lfort::runUninitializedVariablesAnalysis( const DeclContext &dc, const CFG &cfg, AnalysisDeclContext &ac, UninitVariablesHandler &handler, UninitVariablesAnalysisStats &stats) { CFGBlockValues vals(cfg); vals.computeSetOfDeclarations(dc); if (vals.hasNoDeclarations()) return; stats.NumVariablesAnalyzed = vals.getNumEntries(); // Precompute which expressions are uses and which are initializations. ClassifyRefs classification(ac); cfg.VisitBlockStmts(classification); // Mark all variables uninitialized at the entry. const CFGBlock &entry = cfg.getEntry(); ValueVector &vec = vals.getValueVector(&entry); const unsigned n = vals.getNumEntries(); for (unsigned j = 0; j < n ; ++j) { vec[j] = Uninitialized; } // Proceed with the workist. DataflowWorklist worklist(cfg, *ac.getAnalysis<PostOrderCFGView>()); llvm::BitVector previouslyVisited(cfg.getNumBlockIDs()); worklist.enqueueSuccessors(&cfg.getEntry()); llvm::BitVector wasAnalyzed(cfg.getNumBlockIDs(), false); wasAnalyzed[cfg.getEntry().getBlockID()] = true; PruneBlocksHandler PBH(cfg.getNumBlockIDs()); while (const CFGBlock *block = worklist.dequeue()) { PBH.currentBlock = block->getBlockID(); // Did the block change? bool changed = runOnBlock(block, cfg, ac, vals, classification, wasAnalyzed, PBH); ++stats.NumBlockVisits; if (changed || !previouslyVisited[block->getBlockID()]) worklist.enqueueSuccessors(block); previouslyVisited[block->getBlockID()] = true; } if (!PBH.hadAnyUse) return; // Run through the blocks one more time, and report uninitialized variabes. for (CFG::const_iterator BI = cfg.begin(), BE = cfg.end(); BI != BE; ++BI) { const CFGBlock *block = *BI; if (PBH.hadUse[block->getBlockID()]) { runOnBlock(block, cfg, ac, vals, classification, wasAnalyzed, handler); ++stats.NumBlockVisits; } } }
void UninitializedValues::InitializeValues(const CFG& cfg) { RegisterDecls R(getAnalysisData()); cfg.VisitBlockStmts(R); }