134 lines · cpp
1//===- TestDeadCodeAnalysis.cpp - Test dead code analysis -----------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "mlir/Analysis/DataFlow/ConstantPropagationAnalysis.h"10#include "mlir/Analysis/DataFlow/DeadCodeAnalysis.h"11#include "mlir/IR/Matchers.h"12#include "mlir/Pass/Pass.h"13 14using namespace mlir;15using namespace mlir::dataflow;16 17/// Print the liveness of every block, control-flow edge, and the predecessors18/// of all regions, callables, and calls.19static void printAnalysisResults(DataFlowSolver &solver, Operation *op,20 raw_ostream &os) {21 op->walk([&](Operation *op) {22 auto tag = op->getAttrOfType<StringAttr>("tag");23 if (!tag)24 return;25 os << tag.getValue() << ":\n";26 for (Region ®ion : op->getRegions()) {27 os << " region #" << region.getRegionNumber() << "\n";28 for (Block &block : region) {29 os << " ";30 block.printAsOperand(os);31 os << " = ";32 auto *live = solver.lookupState<Executable>(33 solver.getProgramPointBefore(&block));34 if (live)35 os << *live;36 else37 os << "dead";38 os << "\n";39 for (Block *pred : block.getPredecessors()) {40 os << " from ";41 pred->printAsOperand(os);42 os << " = ";43 auto *live = solver.lookupState<Executable>(44 solver.getLatticeAnchor<CFGEdge>(pred, &block));45 if (live)46 os << *live;47 else48 os << "dead";49 os << "\n";50 }51 }52 if (!region.empty()) {53 auto *preds = solver.lookupState<PredecessorState>(54 solver.getProgramPointBefore(®ion.front()));55 if (preds)56 os << "region_preds: " << *preds << "\n";57 }58 }59 auto *preds =60 solver.lookupState<PredecessorState>(solver.getProgramPointAfter(op));61 if (preds)62 os << "op_preds: " << *preds << "\n";63 });64}65 66namespace {67/// This is a simple analysis that implements a transfer function for constant68/// operations.69struct ConstantAnalysis : public DataFlowAnalysis {70 using DataFlowAnalysis::DataFlowAnalysis;71 72 LogicalResult initialize(Operation *top) override {73 WalkResult result = top->walk([&](Operation *op) {74 if (failed(visit(getProgramPointAfter(op))))75 return WalkResult::interrupt();76 return WalkResult::advance();77 });78 return success(!result.wasInterrupted());79 }80 81 LogicalResult visit(ProgramPoint *point) override {82 Operation *op = point->getPrevOp();83 Attribute value;84 if (matchPattern(op, m_Constant(&value))) {85 auto *constant = getOrCreate<Lattice<ConstantValue>>(op->getResult(0));86 propagateIfChanged(87 constant, constant->join(ConstantValue(value, op->getDialect())));88 return success();89 }90 setAllToUnknownConstants(op->getResults());91 for (Region ®ion : op->getRegions())92 setAllToUnknownConstants(region.getArguments());93 return success();94 }95 96 /// Set all given values as not constants.97 void setAllToUnknownConstants(ValueRange values) {98 for (Value value : values) {99 auto *constant = getOrCreate<Lattice<ConstantValue>>(value);100 propagateIfChanged(constant,101 constant->join(ConstantValue::getUnknownConstant()));102 }103 }104};105 106/// This is a simple pass that runs dead code analysis with a constant value107/// provider that only understands constant operations.108struct TestDeadCodeAnalysisPass109 : public PassWrapper<TestDeadCodeAnalysisPass, OperationPass<>> {110 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestDeadCodeAnalysisPass)111 112 StringRef getArgument() const override { return "test-dead-code-analysis"; }113 114 void runOnOperation() override {115 Operation *op = getOperation();116 117 DataFlowSolver solver;118 solver.load<DeadCodeAnalysis>();119 solver.load<ConstantAnalysis>();120 if (failed(solver.initializeAndRun(op)))121 return signalPassFailure();122 printAnalysisResults(solver, op, llvm::errs());123 }124};125} // end anonymous namespace126 127namespace mlir {128namespace test {129void registerTestDeadCodeAnalysisPass() {130 PassRegistration<TestDeadCodeAnalysisPass>();131}132} // end namespace test133} // end namespace mlir134