PDG — Program Dependence Graph
Overview
The Program Dependence Graph (PDG) is a fine-grained representation of data and control dependences. It is built on top of the ICFG and is used for slicing, security analyses, and other dependence-aware queries.
Location:
lib/IR/PDG/,include/IR/PDG/
Core Passes
The PDG infrastructure provides several LLVM passes:
DataDependencyGraph– builds def-use, read-after-write (RAW), and alias-based data dependence edges.ControlDependencyGraph– computes control dependences between basic blocks and instructions.ProgramDependencyGraph– combines data and control dependences and exposes a unified query interface.
Unified Query API
The public query layer lives in include/IR/PDG/Analysis/PDGQuery.h and is
organized around five service objects:
SliceQuery– forward/backward slices, chops, and thin slicesDependenceQuery– reachability and shortest-path style queriesDataFlowQuery– reaching definitions, liveness, and control-region viewsTransformQuery– motion legality and scheduling helpersDiffQuery– structural differencing and impact summaries
All services share the same option/result model:
PDGQueryOptions– edge preset, scope, context mode, traversal limits, cache policy, and explanation modePDGQueryScope– whole graph, explicit node set, function, or prior query resultPDGQueryResult– nodes, induced edges, predecessor map, witness paths, distances, and diagnosticsPDGCriteriaResolver– seeds queries from nodes, LLVM values, function names, callee names, source locations, property specs, and Cypher results
High-Level Usage
PDG is exposed as an LLVM ModulePass. A typical usage pattern:
#include "IR/PDG/Core/ProgramDependencyGraph.h"
using namespace llvm;
using namespace pdg;
legacy::PassManager PM;
PM.add(new DataDependencyGraph());
PM.add(new ControlDependencyGraph());
auto *pdgPass = new ProgramDependencyGraph();
PM.add(pdgPass);
PM.run(module);
ProgramGraph *G = pdgPass->getPDG();
SliceQuery slicer(*G);
PDGCriteria criteria;
criteria.values.push_back(src);
PDGQueryOptions options;
options.edge_preset = PDGEdgePreset::Data;
options.context_mode = PDGContextMode::ContextSensitive;
auto result = slicer.forward(criteria, options, &module);
For interactive querying and slicing, see the ../pdg_query_language
and the pdg-query tool described in ../tools/ir.
pdg-query Analysis Mode
pdg-query still accepts raw Cypher queries, but it can now also run the
PDG analysis services directly:
--analysis slice-forward/slice-backward/chop--analysis shortest-path/reaching-defs/control-region--analysis live/dead/diff
Analysis mode uses Cypher as a selector front end:
--criteria-queryselects analysis seeds--target-queryselects targets for binary analyses--scope-functionor--scope-queryrestrict analysis scope--edge-presetchooses one ofall,data,control,parameter,interprocedural,value-flow, ortransform-legality--context-sensitiveenables call/return matching--thinenables thin slicing semantics--format text|json|dotcontrols rendering