//===- DeadCodeAnalysis.h - Dead code analysis ----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file implements dead code analysis using the data-flow analysis // framework. This analysis uses the results of constant propagation to // determine live blocks, control-flow edges, and control-flow predecessors. // //===----------------------------------------------------------------------===// #ifndef MLIR_ANALYSIS_DATAFLOW_DEADCODEANALYSIS_H #define MLIR_ANALYSIS_DATAFLOW_DEADCODEANALYSIS_H #include "mlir/Analysis/DataFlowFramework.h" #include "mlir/IR/SymbolTable.h" #include "llvm/ADT/SmallPtrSet.h" #include <optional> namespace mlir { class CallOpInterface; class CallableOpInterface; class BranchOpInterface; class RegionBranchOpInterface; class RegionBranchTerminatorOpInterface; namespace dataflow { //===----------------------------------------------------------------------===// // Executable //===----------------------------------------------------------------------===// /// This is a simple analysis state that represents whether the associated /// lattice anchor (either a block or a control-flow edge) is live. class Executable : public AnalysisState { … }; //===----------------------------------------------------------------------===// // PredecessorState //===----------------------------------------------------------------------===// /// This analysis state represents a set of live control-flow "predecessors" of /// a program point (either an operation or a block), which are the last /// operations along all execution paths that pass through this point. /// /// For example, in dead-code analysis, an operation with region control-flow /// can be the predecessor of a region's entry block or itself, the exiting /// terminator of a region can be the predecessor of the parent operation or /// another region's entry block, the callsite of a callable operation can be /// the predecessor to its entry block, and the exiting terminator or a callable /// operation can be the predecessor of the call operation. /// /// The state can optionally contain information about which values are /// propagated from each predecessor to the successor point. /// /// The state can indicate that it is underdefined, meaning that not all live /// control-flow predecessors can be known. class PredecessorState : public AnalysisState { … }; //===----------------------------------------------------------------------===// // CFGEdge //===----------------------------------------------------------------------===// /// This lattice anchor represents a control-flow edge between a block and one /// of its successors. class CFGEdge : public GenericLatticeAnchorBase<CFGEdge, std::pair<Block *, Block *>> { … }; //===----------------------------------------------------------------------===// // DeadCodeAnalysis //===----------------------------------------------------------------------===// /// Dead code analysis analyzes control-flow, as understood by /// `RegionBranchOpInterface` and `BranchOpInterface`, and the callgraph, as /// understood by `CallableOpInterface` and `CallOpInterface`. /// /// This analysis uses known constant values of operands to determine the /// liveness of each block and each edge between a block and its predecessors. /// For region control-flow, this analysis determines the predecessor operations /// for region entry blocks and region control-flow operations. For the /// callgraph, this analysis determines the callsites and live returns of every /// function. class DeadCodeAnalysis : public DataFlowAnalysis { … }; } // end namespace dataflow } // end namespace mlir #endif // MLIR_ANALYSIS_DATAFLOW_DEADCODEANALYSIS_H