19#include "mlir/Analysis/DataFlow/ConstantPropagationAnalysis.h"
20#include "mlir/Analysis/DataFlow/DeadCodeAnalysis.h"
21#include "mlir/Interfaces/FunctionInterfaces.h"
28#define GEN_PASS_DEF_PRINTALIASANALYSISPASS
29#include "Passes/Passes.h.inc"
35struct PrintAliasAnalysisPass
36 :
public enzyme::impl::PrintAliasAnalysisPassBase<PrintAliasAnalysisPass> {
38 void runOnOperation()
override {
39 DataFlowSolver solver;
43 solver.load<dataflow::DeadCodeAnalysis>();
44 solver.load<dataflow::SparseConstantPropagation>();
46 if (failed(solver.initializeAndRun(getOperation()))) {
47 return signalPassFailure();
49 raw_ostream &os = llvm::outs();
51 SmallVector<std::pair<Attribute, Value>> taggedPointers;
52 getOperation()->walk([&](FunctionOpInterface funcOp) {
53 for (
auto arg : funcOp.getArguments()) {
54 if (funcOp.getArgAttr(arg.getArgNumber(),
"enzyme.tag")) {
55 taggedPointers.push_back(
56 {funcOp.getArgAttr(arg.getArgNumber(),
"enzyme.tag"), arg});
60 funcOp.walk([&](Operation *op) {
61 if (op->hasAttr(
"tag")) {
62 for (OpResult result : op->getResults()) {
63 taggedPointers.push_back({op->getAttr(
"tag"), result});
69 for (
const auto &[tag, value] : taggedPointers) {
72 os <<
"tag " << tag <<
" " << *state <<
"\n";
76 if (taggedPointers.empty())
80 for (
unsigned i = 0; i < taggedPointers.size() - 1; i++) {
81 for (
unsigned j = i + 1; j < taggedPointers.size(); j++) {
82 const auto &[tagA, a] = taggedPointers[i];
83 const auto &[tagB, b] = taggedPointers[j];
90 os << tagA <<
" and " << tagB <<
": " << lhs->
alias(*rhs) <<
"\n";
94 getOperation()->walk([&solver, &os](Operation *op) {
95 if (
auto funcOp = dyn_cast<FunctionOpInterface>(op)) {
96 for (
auto arg : funcOp.getArguments()) {
104 if (state == enzyme::AliasClassSet::State::Undefined)
106 arg.getArgNumber(),
"enzyme.ac",
107 StringAttr::get(arg.getContext(),
"undefined"));
108 else if (state == enzyme::AliasClassSet::State::Unknown)
110 arg.getArgNumber(),
"enzyme.ac",
111 StringAttr::get(arg.getContext(),
"unknown"));
113 funcOp.setArgAttr(arg.getArgNumber(),
"enzyme.ac",
115 return ChangeResult::NoChange;
118 }
else if (op->hasTrait<OpTrait::ReturnLike>() &&
119 isa<FunctionOpInterface>(op->getParentOp())) {
120 os <<
"points-to-pointer sets for op @" << op->getLoc() <<
":\n";
122 solver.getProgramPointBefore(op)))
123 os << *state <<
"\n";
125 os <<
"NOT computed\n";
127 if (op->hasAttr(
"tag")) {
128 for (OpResult result : op->getResults()) {
131 if (state->isUnknown()) {
133 StringAttr::get(result.getContext(),
"<unknown>"));
134 }
else if (state->isUndefined()) {
136 StringAttr::get(result.getContext(),
"<undefined>"));
138 for (
auto aliasClass : state->getAliasClasses()) {
139 op->setAttr(
"ac", aliasClass);
This analysis implements interprocedural alias analysis.
const AliasClassSet & getAliasClassesObject() const
::mlir::AliasResult alias(const AbstractSparseLattice &other) const
ChangeResult foreachElement(function_ref< ChangeResult(ValueT, State)> callback) const