1 //===- ConstantPropagationAnalysis.h - Constant propagation 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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements constant propagation analysis. In this file are defined
10 // the lattice value class that represents constant values in the program and
11 // a sparse constant propagation analysis that uses operation folders to
12 // speculate about constant values in the program.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef MLIR_ANALYSIS_DATAFLOW_CONSTANTPROPAGATIONANALYSIS_H
17 #define MLIR_ANALYSIS_DATAFLOW_CONSTANTPROPAGATIONANALYSIS_H
18 
19 #include "mlir/Analysis/DataFlow/SparseAnalysis.h"
20 
21 namespace mlir {
22 namespace dataflow {
23 
24 //===----------------------------------------------------------------------===//
25 // ConstantValue
26 //===----------------------------------------------------------------------===//
27 
28 /// This lattice value represents a known constant value of a lattice.
29 class ConstantValue {
30 public:
31   /// Construct a constant value with a known constant.
32   ConstantValue(Attribute knownValue = {}, Dialect *dialect = nullptr)
constant(knownValue)33       : constant(knownValue), dialect(dialect) {}
34 
35   /// Get the constant value. Returns null if no value was determined.
getConstantValue()36   Attribute getConstantValue() const { return constant; }
37 
38   /// Get the dialect instance that can be used to materialize the constant.
getConstantDialect()39   Dialect *getConstantDialect() const { return dialect; }
40 
41   /// Compare the constant values.
42   bool operator==(const ConstantValue &rhs) const {
43     return constant == rhs.constant;
44   }
45 
46   /// Print the constant value.
47   void print(raw_ostream &os) const;
48 
49   /// The pessimistic value state of the constant value is unknown.
getPessimisticValueState(Value value)50   static ConstantValue getPessimisticValueState(Value value) { return {}; }
51 
52   /// The union with another constant value is null if they are different, and
53   /// the same if they are the same.
join(const ConstantValue & lhs,const ConstantValue & rhs)54   static ConstantValue join(const ConstantValue &lhs,
55                             const ConstantValue &rhs) {
56     return lhs == rhs ? lhs : ConstantValue();
57   }
58 
59 private:
60   /// The constant value.
61   Attribute constant;
62   /// An dialect instance that can be used to materialize the constant.
63   Dialect *dialect;
64 };
65 
66 //===----------------------------------------------------------------------===//
67 // SparseConstantPropagation
68 //===----------------------------------------------------------------------===//
69 
70 /// This analysis implements sparse constant propagation, which attempts to
71 /// determine constant-valued results for operations using constant-valued
72 /// operands, by speculatively folding operations. When combined with dead-code
73 /// analysis, this becomes sparse conditional constant propagation (SCCP).
74 class SparseConstantPropagation
75     : public SparseDataFlowAnalysis<Lattice<ConstantValue>> {
76 public:
77   using SparseDataFlowAnalysis::SparseDataFlowAnalysis;
78 
79   void visitOperation(Operation *op,
80                       ArrayRef<const Lattice<ConstantValue> *> operands,
81                       ArrayRef<Lattice<ConstantValue> *> results) override;
82 };
83 
84 } // end namespace dataflow
85 } // end namespace mlir
86 
87 #endif // MLIR_ANALYSIS_DATAFLOW_CONSTANTPROPAGATIONANALYSIS_H
88