Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions changelogs/unreleased/iangneal__analysis-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
added:
- PredecessorAnalysis (-llzk-predecessor-analysis) for testing
changed:
- Implement `CallOpInterface` methods for `CallOp`
removed:
- LLZK port of MLIR DenseAnalysis
2 changes: 2 additions & 0 deletions include/llzk/Analysis/AnalysisPasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ std::unique_ptr<mlir::Pass> createSymbolDefTreePrinterPass();

std::unique_ptr<mlir::Pass> createSymbolUseGraphPrinterPass();

std::unique_ptr<mlir::Pass> createPredecessorPrinterPass();

#define GEN_PASS_REGISTRATION
#include "llzk/Analysis/AnalysisPasses.h.inc"

Expand Down
10 changes: 10 additions & 0 deletions include/llzk/Analysis/AnalysisPasses.td
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,14 @@ def SymbolUseGraphPrinterPass : LLZKPass<"llzk-print-symbol-use-graph"> {
let options = [OutputStreamOption, SaveDotGraphOption];
}

def PredecessorPrinterPass : LLZKPass<"llzk-print-predecessors"> {
let summary = "Print the predecessors of all operations.";
let constructor = "llzk::createPredecessorPrinterPass()";
let options = [OutputStreamOption,
Option<"preRunRequiredAnalyses", "prerun", "bool",
/* default */ "false",
"Whether to pre-run the required dataflow analyses "
"(e.g., liveness analysis).">];
}

#endif // LLZK_ANALYSIS_TD
26 changes: 19 additions & 7 deletions include/llzk/Analysis/AnalysisUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,25 @@

namespace llzk::dataflow {

/// LLZK: Added this utility to ensure analysis is performed for all structs
/// in a given module.
///
/// @brief Mark all operations from the top and included in the top operation
/// as live so the solver will perform dataflow analyses.
/// @brief Loads analyses required to initialize the Executable and PredecessorState
/// analysis states, which are required for the MLIR Dataflow analyses to properly
/// traverse the LLZK IR.
/// @param solver The solver.
/// @param top The top-level operation.
void markAllOpsAsLive(mlir::DataFlowSolver &solver, mlir::Operation *top);
void loadRequiredAnalyses(mlir::DataFlowSolver &solver);

/// @brief Loads and runs analyses required to initialize the Executable and PredecessorState
/// analysis states, which are required for the MLIR Dataflow analyses to properly
/// traverse the LLZK IR.
/// This function pre-runs the analyses, which is helpful in cases where early
/// region-op-body traversal is desired.
/// - the bodies of scf.for, scf.while, scf.if are usually not marked as live
/// initially, so the dataflow analysis will traverse all ops in a function
/// before traversing the insides of region ops.
/// - by pre-running the analysis, the region bodies will be explored as encountered
/// if they are marked as "live" by the dead code analysis.
/// @param solver The solver.
/// @param op The operation to pre-run the analyses on.
/// @return Whether the pre-run analysis was successful.
mlir::LogicalResult loadAndRunRequiredAnalyses(mlir::DataFlowSolver &solver, mlir::Operation *op);

} // namespace llzk::dataflow
3 changes: 2 additions & 1 deletion include/llzk/Analysis/AnalysisWrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ class ModuleAnalysis {
/// in the `ModuleOp` that is being subjected to this analysis.
/// @param am The module's analysis manager.
void constructChildAnalyses(mlir::AnalysisManager &am) {
dataflow::markAllOpsAsLive(solver, modOp);
auto init = dataflow::loadAndRunRequiredAnalyses(solver, modOp);
ensure(init.succeeded(), "solver failed to run on module!");

// The analysis is run at the module level so that lattices are computed
// for global functions as well.
Expand Down
7 changes: 4 additions & 3 deletions include/llzk/Analysis/ConstraintDependencyGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ using SourceRefRemappings = std::vector<std::pair<SourceRef, SourceRefLatticeVal
/// LLZK operations use and produce. The analysis is simple: any operation will
/// simply output a union of its input references, regardless of what type of
/// operation it performs, as the analysis is operator-insensitive.
class SourceRefAnalysis : public dataflow::DenseForwardDataFlowAnalysis<SourceRefLattice> {
class SourceRefAnalysis : public mlir::dataflow::DenseForwardDataFlowAnalysis<SourceRefLattice> {
public:
using dataflow::DenseForwardDataFlowAnalysis<SourceRefLattice>::DenseForwardDataFlowAnalysis;
using mlir::dataflow::DenseForwardDataFlowAnalysis<
SourceRefLattice>::DenseForwardDataFlowAnalysis;

void visitCallControlFlowTransfer(
mlir::CallOpInterface call, dataflow::CallControlFlowAction action,
mlir::CallOpInterface call, mlir::dataflow::CallControlFlowAction action,
const SourceRefLattice &before, SourceRefLattice *after
) override;

Expand Down
289 changes: 0 additions & 289 deletions include/llzk/Analysis/DenseAnalysis.h

This file was deleted.

2 changes: 1 addition & 1 deletion include/llzk/Analysis/IntervalAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include "llzk/Analysis/AbstractLatticeValue.h"
#include "llzk/Analysis/AnalysisWrappers.h"
#include "llzk/Analysis/ConstraintDependencyGraph.h"
#include "llzk/Analysis/DenseAnalysis.h"
#include "llzk/Analysis/Intervals.h"
#include "llzk/Analysis/SparseAnalysis.h"
#include "llzk/Dialect/Array/IR/Ops.h"
Expand All @@ -26,6 +25,7 @@
#include "llzk/Util/Compare.h"
#include "llzk/Util/Field.h"

#include <mlir/Analysis/DataFlow/DenseAnalysis.h>
#include <mlir/IR/BuiltinOps.h>
#include <mlir/Pass/AnalysisManager.h>
#include <mlir/Support/LLVM.h>
Expand Down
Loading