Skip to content

Commit

Permalink
[clang][dataflow] Add (initial) debug printing for Value and `Envir…
Browse files Browse the repository at this point in the history
…onment`.

Also adds uses of the new printing in analysis inner loop.

Differential Revision: https://reviews.llvm.org/D141716
  • Loading branch information
ymand committed Jan 19, 2023
1 parent 2bcedd4 commit c441f65
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Analysis/FlowSensitive/Value.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <cassert>
#include <utility>

Expand Down Expand Up @@ -310,6 +311,8 @@ class StructValue final : public Value {
llvm::DenseMap<const ValueDecl *, Value *> Children;
};

raw_ostream &operator<<(raw_ostream &OS, const Value &Val);

} // namespace dataflow
} // namespace clang

Expand Down
22 changes: 21 additions & 1 deletion clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
14 changes: 13 additions & 1 deletion clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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");
Expand All @@ -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);
Expand Down
17 changes: 17 additions & 0 deletions clang/lib/Analysis/FlowSensitive/Value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//

#include "clang/Analysis/FlowSensitive/Value.h"
#include "clang/Analysis/FlowSensitive/DebugSupport.h"
#include "llvm/Support/Casting.h"

namespace clang {
Expand All @@ -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<ReferenceValue>(&Val);
return OS << "Reference(" << &RV->getReferentLoc() << ")";
}
case Value::Kind::Pointer: {
const auto *PV = dyn_cast<PointerValue>(&Val);
return OS << "Pointer(" << &PV->getPointeeLoc() << ")";
}
// FIXME: support remaining cases.
default:
return OS << debugString(Val.getKind());
}
}

} // namespace dataflow
} // namespace clang

0 comments on commit c441f65

Please sign in to comment.