/// ScanReachableFromBlock - Mark all blocks reachable from Start. /// Returns the total number of blocks that were marked reachable. unsigned ScanReachableFromBlock(const CFGBlock &Start, llvm::BitVector &Reachable) { unsigned count = 0; llvm::SmallVector<const CFGBlock*, 32> WL; // Prep work queue Reachable.set(Start.getBlockID()); ++count; WL.push_back(&Start); // Find the reachable blocks from 'Start'. CFGBlock::FilterOptions FO; FO.IgnoreDefaultsWithCoveredEnums = 1; while (!WL.empty()) { const CFGBlock *item = WL.back(); WL.pop_back(); // Look at the successors and mark then reachable. for (CFGBlock::filtered_succ_iterator I= item->filtered_succ_start_end(FO); I.hasMore(); ++I) if (const CFGBlock *B = *I) { unsigned blockID = B->getBlockID(); if (!Reachable[blockID]) { Reachable.set(blockID); ++count; WL.push_back(B); } } } return count; }
static SourceLocation MarkLiveTop(const CFGBlock *Start, llvm::BitVector &reachable, SourceManager &SM) { // Prep work worklist. llvm::SmallVector<const CFGBlock*, 32> WL; WL.push_back(Start); SourceRange R1, R2; SourceLocation top = GetUnreachableLoc(*Start, R1, R2); bool FromMainFile = false; bool FromSystemHeader = false; bool TopValid = false; if (top.isValid()) { FromMainFile = SM.isFromMainFile(top); FromSystemHeader = SM.isInSystemHeader(top); TopValid = true; } // Solve CFGBlock::FilterOptions FO; FO.IgnoreDefaultsWithCoveredEnums = 1; while (!WL.empty()) { const CFGBlock *item = WL.back(); WL.pop_back(); SourceLocation c = GetUnreachableLoc(*item, R1, R2); if (c.isValid() && (!TopValid || (SM.isFromMainFile(c) && !FromMainFile) || (FromSystemHeader && !SM.isInSystemHeader(c)) || SM.isBeforeInTranslationUnit(c, top))) { top = c; FromMainFile = SM.isFromMainFile(top); FromSystemHeader = SM.isInSystemHeader(top); } reachable.set(item->getBlockID()); for (CFGBlock::filtered_succ_iterator I = item->filtered_succ_start_end(FO); I.hasMore(); ++I) if (const CFGBlock *B = *I) { unsigned blockID = B->getBlockID(); if (!reachable[blockID]) { reachable.set(blockID); WL.push_back(B); } } } return top; }
unsigned ScanReachableFromBlock(const CFGBlock *Start, llvm::BitVector &Reachable) { unsigned count = 0; // Prep work queue SmallVector<const CFGBlock*, 32> WL; // The entry block may have already been marked reachable // by the caller. if (!Reachable[Start->getBlockID()]) { ++count; Reachable[Start->getBlockID()] = true; } WL.push_back(Start); // Find the reachable blocks from 'Start'. while (!WL.empty()) { const CFGBlock *item = WL.pop_back_val(); // Look at the successors and mark then reachable. for (CFGBlock::const_succ_iterator I = item->succ_begin(), E = item->succ_end(); I != E; ++I) if (const CFGBlock *B = *I) { unsigned blockID = B->getBlockID(); if (!Reachable[blockID]) { Reachable.set(blockID); WL.push_back(B); ++count; } } } return count; }
static unsigned scanFromBlock(const CFGBlock *Start, llvm::BitVector &Reachable, Preprocessor *PP, bool IncludeSometimesUnreachableEdges) { unsigned count = 0; // Prep work queue SmallVector<const CFGBlock*, 32> WL; // The entry block may have already been marked reachable // by the caller. if (!Reachable[Start->getBlockID()]) { ++count; Reachable[Start->getBlockID()] = true; } WL.push_back(Start); // Find the reachable blocks from 'Start'. while (!WL.empty()) { const CFGBlock *item = WL.pop_back_val(); // There are cases where we want to treat all successors as reachable. // The idea is that some "sometimes unreachable" code is not interesting, // and that we should forge ahead and explore those branches anyway. // This allows us to potentially uncover some "always unreachable" code // within the "sometimes unreachable" code. // Look at the successors and mark then reachable. Optional<bool> TreatAllSuccessorsAsReachable; if (!IncludeSometimesUnreachableEdges) TreatAllSuccessorsAsReachable = false; for (CFGBlock::const_succ_iterator I = item->succ_begin(), E = item->succ_end(); I != E; ++I) { const CFGBlock *B = *I; if (!B) do { const CFGBlock *UB = I->getPossiblyUnreachableBlock(); if (!UB) break; if (!TreatAllSuccessorsAsReachable.hasValue()) { assert(PP); TreatAllSuccessorsAsReachable = shouldTreatSuccessorsAsReachable(item, *PP); } if (TreatAllSuccessorsAsReachable.getValue()) { B = UB; break; } } while (false); if (B) { unsigned blockID = B->getBlockID(); if (!Reachable[blockID]) { Reachable.set(blockID); WL.push_back(B); ++count; } } } } return count; }
void BlockState::startTrackingLocation(llvm::BitVector &BV, unsigned i) { BV.set(i); }