[clang] [clang][dataflow] Add support for serialization and deserialization. (PR #152487)
Yitzhak Mandelbaum via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 8 07:05:59 PDT 2025
================
@@ -140,6 +140,15 @@ class DataflowAnalysisContext {
/// Adds `Constraint` to the flow condition identified by `Token`.
void addFlowConditionConstraint(Atom Token, const Formula &Constraint);
+ /// Adds `Deps` to the dependencies of the flow condition identified by
+ /// `Token`. Intended for use in deserializing contexts. The formula alone
+ /// doesn't have enough information to indicate its deps.
+ void addFlowConditionDeps(Atom Token, const llvm::DenseSet<Atom> &Deps) {
----------------
ymand wrote:
Here's the basic idea for serialization -- it assumes a set of protobuf messages designed for this purposes. I don't include their definitions here but it should self explanatory.
Some of this might belong in the patch itself (vs just demo code in a comment), like `getAtomData` and `getReferencedAtoms`. I could also imagine we define a struct used for exporting the data. And then we could make more of the current functions private.
WDYT?
```
static unsigned getAtomData(dataflow::Atom A) {
return static_cast<unsigned>(A);
}
static void getReferencedAtoms(const Formula &F,
llvm::DenseSet<dataflow::Atom> &Refs) {
switch (F.kind()) {
case Formula::AtomRef:
Refs.insert(F.getAtom());
break;
case Formula::Literal:
break;
case Formula::Not:
getReferencedAtoms(*F.operands()[0], Refs);
break;
case Formula::And:
case Formula::Or:
case Formula::Implies:
case Formula::Equal:
ArrayRef<const Formula *> Operands = F.operands();
getReferencedAtoms(*Operands[0], Refs);
getReferencedAtoms(*Operands[1], Refs);
break;
}
}
static void saveFormula(const dataflow::Formula &F, FormulaProto &Proto) {
llvm::raw_string_ostream OS(*Proto.mutable_serialized());
F.serialize(OS);
}
static void saveTokenDefinitions(
const llvm::DenseSet<dataflow::Atom> &UsedTokens,
const DataflowAnalysisContext &AC,
proto2::Map<uint32_t, FormulaProto> *AtomDefs) {
for (const dataflow::Atom A : UsedTokens) {
const Formula *FC = AC.getFlowCondition(A);
// Only record the atom if it is constrained.
if (FC != nullptr) saveFormula(*FC, (*AtomDefs)[getAtomData(A)]);
}
}
// Exports the subset of `AC`'s logical elements needed to define `TargetTokens`.
static void saveLogicalContext(llvm::DenseSet<dataflow::Atom> TargetTokens,
const DataflowAnalysisContext &AC,
LogicalContext &LC) {
if (const Formula *I = AC.getInvariant()) {
saveFormula(*I, *LC.mutable_ground_truth());
getReferencedAtoms(*I, TargetTokens);
}
llvm::DenseSet<dataflow::Atom> ReachableTokens = AC.getTransitiveClosure(TargetTokens);
saveTokenDefinitions(ReachableTokens, AC, LC.mutable_atom_defs());
}
```
https://github.com/llvm/llvm-project/pull/152487
More information about the cfe-commits
mailing list