Path: blob/main/contrib/llvm-project/clang/lib/Analysis/CFGReachabilityAnalysis.cpp
35233 views
//===- CFGReachabilityAnalysis.cpp - Basic reachability analysis ----------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file defines a flow-sensitive, (mostly) path-insensitive reachability9// analysis based on Clang's CFGs. Clients can query if a given basic block10// is reachable within the CFG.11//12//===----------------------------------------------------------------------===//1314#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"15#include "clang/Analysis/CFG.h"16#include "llvm/ADT/BitVector.h"17#include "llvm/ADT/SmallVector.h"1819using namespace clang;2021CFGReverseBlockReachabilityAnalysis::CFGReverseBlockReachabilityAnalysis(22const CFG &cfg)23: analyzed(cfg.getNumBlockIDs(), false) {}2425bool CFGReverseBlockReachabilityAnalysis::isReachable(const CFGBlock *Src,26const CFGBlock *Dst) {27const unsigned DstBlockID = Dst->getBlockID();2829// If we haven't analyzed the destination node, run the analysis now30if (!analyzed[DstBlockID]) {31mapReachability(Dst);32analyzed[DstBlockID] = true;33}3435// Return the cached result36return reachable[DstBlockID][Src->getBlockID()];37}3839// Maps reachability to a common node by walking the predecessors of the40// destination node.41void CFGReverseBlockReachabilityAnalysis::mapReachability(const CFGBlock *Dst) {42SmallVector<const CFGBlock *, 11> worklist;43llvm::BitVector visited(analyzed.size());4445ReachableSet &DstReachability = reachable[Dst->getBlockID()];46DstReachability.resize(analyzed.size(), false);4748// Start searching from the destination node, since we commonly will perform49// multiple queries relating to a destination node.50worklist.push_back(Dst);51bool firstRun = true;5253while (!worklist.empty()) {54const CFGBlock *block = worklist.pop_back_val();5556if (visited[block->getBlockID()])57continue;58visited[block->getBlockID()] = true;5960// Update reachability information for this node -> Dst61if (!firstRun) {62// Don't insert Dst -> Dst unless it was a predecessor of itself63DstReachability[block->getBlockID()] = true;64}65else66firstRun = false;6768// Add the predecessors to the worklist.69for (CFGBlock::const_pred_iterator i = block->pred_begin(),70e = block->pred_end(); i != e; ++i) {71if (*i)72worklist.push_back(*i);73}74}75}767778