From c441f65f9183a4d1d7f5ecc63b4e32a42e09367e Mon Sep 17 00:00:00 2001 From: Yitzhak Mandelbaum Date: Fri, 13 Jan 2023 19:26:57 +0000 Subject: [PATCH] [clang][dataflow] Add (initial) debug printing for `Value` and `Environment`. Also adds uses of the new printing in analysis inner loop. Differential Revision: https://reviews.llvm.org/D141716 --- .../FlowSensitive/DataflowEnvironment.h | 1 + .../clang/Analysis/FlowSensitive/Value.h | 3 +++ .../FlowSensitive/DataflowEnvironment.cpp | 22 ++++++++++++++++++- .../TypeErasedDataflowAnalysis.cpp | 14 +++++++++++- clang/lib/Analysis/FlowSensitive/Value.cpp | 17 ++++++++++++++ 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h index 694dd0ea67d794..e457430a5e6467 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h @@ -430,6 +430,7 @@ class Environment { } LLVM_DUMP_METHOD void dump() const; + LLVM_DUMP_METHOD void dump(raw_ostream &OS) const; private: /// Creates a value appropriate for `Type`, if `Type` is supported, otherwise diff --git a/clang/include/clang/Analysis/FlowSensitive/Value.h b/clang/include/clang/Analysis/FlowSensitive/Value.h index 9012d3b00060cd..32d10a3489483c 100644 --- a/clang/include/clang/Analysis/FlowSensitive/Value.h +++ b/clang/include/clang/Analysis/FlowSensitive/Value.h @@ -19,6 +19,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/raw_ostream.h" #include #include @@ -310,6 +311,8 @@ class StructValue final : public Value { llvm::DenseMap Children; }; +raw_ostream &operator<<(raw_ostream &OS, const Value &Val); + } // namespace dataflow } // namespace clang diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index 37d200509e8d23..064d0f92e71a4b 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -786,9 +786,29 @@ bool Environment::flowConditionImplies(BoolValue &Val) const { return DACtx->flowConditionImplies(*FlowConditionToken, Val); } -void Environment::dump() const { +void Environment::dump(raw_ostream &OS) const { + // FIXME: add printing for remaining fields and allow caller to decide what + // fields are printed. + OS << "DeclToLoc:\n"; + for (auto [D, L] : DeclToLoc) + OS << " [" << D->getName() << ", " << L << "]\n"; + + OS << "ExprToLoc:\n"; + for (auto [E, L] : ExprToLoc) + OS << " [" << E << ", " << L << "]\n"; + + OS << "LocToVal:\n"; + for (auto [L, V] : LocToVal) { + OS << " [" << L << ", " << V << ": " << *V << "]\n"; + } + + OS << "FlowConditionToken:\n"; DACtx->dumpFlowCondition(*FlowConditionToken); } +void Environment::dump() const { + dump(llvm::dbgs()); +} + } // namespace dataflow } // namespace clang diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp index dc923fe2419751..b125701212c966 100644 --- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp +++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp @@ -32,8 +32,10 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/Error.h" -#include "llvm/Support/ErrorHandling.h" + +#define DEBUG_TYPE "clang-dataflow" namespace clang { namespace dataflow { @@ -431,6 +433,8 @@ runTypeErasedDataflowAnalysis( std::min(RelativeMaxIterations, AbsoluteMaxIterations); uint32_t Iterations = 0; while (const CFGBlock *Block = Worklist.dequeue()) { + LLVM_DEBUG(llvm::dbgs() + << "Processing Block " << Block->getBlockID() << "\n"); if (++Iterations > MaxIterations) { return llvm::createStringError(std::errc::timed_out, "maximum number of iterations reached"); @@ -440,8 +444,16 @@ runTypeErasedDataflowAnalysis( BlockStates[Block->getBlockID()]; TypeErasedDataflowAnalysisState NewBlockState = transferCFGBlock(*Block, AC); + LLVM_DEBUG({ + llvm::errs() << "New Env:\n"; + NewBlockState.Env.dump(); + }); if (OldBlockState) { + LLVM_DEBUG({ + llvm::errs() << "Old Env:\n"; + OldBlockState->Env.dump(); + }); if (isLoopHead(*Block)) { LatticeJoinEffect Effect1 = Analysis.widenTypeErased( NewBlockState.Lattice, OldBlockState->Lattice); diff --git a/clang/lib/Analysis/FlowSensitive/Value.cpp b/clang/lib/Analysis/FlowSensitive/Value.cpp index 84c1ea8ca4e97c..59affa80bdce99 100644 --- a/clang/lib/Analysis/FlowSensitive/Value.cpp +++ b/clang/lib/Analysis/FlowSensitive/Value.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "clang/Analysis/FlowSensitive/Value.h" +#include "clang/Analysis/FlowSensitive/DebugSupport.h" #include "llvm/Support/Casting.h" namespace clang { @@ -35,5 +36,21 @@ bool areEquivalentValues(const Value &Val1, const Value &Val2) { areEquivalentIndirectionValues(Val1, Val2))); } +raw_ostream &operator<<(raw_ostream &OS, const Value &Val) { + switch (Val.getKind()) { + case Value::Kind::Reference: { + const auto *RV = cast(&Val); + return OS << "Reference(" << &RV->getReferentLoc() << ")"; + } + case Value::Kind::Pointer: { + const auto *PV = dyn_cast(&Val); + return OS << "Pointer(" << &PV->getPointeeLoc() << ")"; + } + // FIXME: support remaining cases. + default: + return OS << debugString(Val.getKind()); + } +} + } // namespace dataflow } // namespace clang