1 //===- NumberOfExecutions.h - Number of executions analysis -----*- C++ -*-===//
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 contains an analysis for computing how many times a block within a
10 // region is executed *each time* that region is entered. The analysis
11 // iterates over all associated regions that are attached to the given top-level
12 // operation.
13 //
14 // It is possible to query number of executions information on block level.
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef MLIR_ANALYSIS_NUMBER_OF_EXECUTIONS_H
19 #define MLIR_ANALYSIS_NUMBER_OF_EXECUTIONS_H
20 
21 #include "mlir/Support/LLVM.h"
22 #include "llvm/ADT/DenseMap.h"
23 #include "llvm/ADT/Optional.h"
24 
25 namespace mlir {
26 
27 class Block;
28 class BlockNumberOfExecutionsInfo;
29 class Operation;
30 class Region;
31 
32 /// Represents an analysis for computing how many times a block or an operation
33 /// within a region is executed *each time* that region is entered. The analysis
34 /// iterates over all associated regions that are attached to the given
35 /// top-level operation.
36 ///
37 /// This analysis assumes that all operations complete in a finite amount of
38 /// time (do not abort and do not go into the infinite loop).
39 class NumberOfExecutions {
40 public:
41   /// Creates a new NumberOfExecutions analysis that computes how many times a
42   /// block within a region is executed for all associated regions.
43   explicit NumberOfExecutions(Operation *op);
44 
45   /// Returns the number of times operations `op` is executed *each time* the
46   /// control flow enters the region `perEntryOfThisRegion`. Returns empty
47   /// optional if this is not known statically.
48   Optional<int64_t> getNumberOfExecutions(Operation *op,
49                                           Region *perEntryOfThisRegion) const;
50 
51   /// Returns the number of times block `block` is executed *each time* the
52   /// control flow enters the region `perEntryOfThisRegion`. Returns empty
53   /// optional if this is not known statically.
54   Optional<int64_t> getNumberOfExecutions(Block *block,
55                                           Region *perEntryOfThisRegion) const;
56 
57   /// Dumps the number of block executions *each time* the control flow enters
58   /// the region `perEntryOfThisRegion` to the given stream.
59   void printBlockExecutions(raw_ostream &os,
60                             Region *perEntryOfThisRegion) const;
61 
62   /// Dumps the number of operation executions *each time* the control flow
63   /// enters the region `perEntryOfThisRegion` to the given stream.
64   void printOperationExecutions(raw_ostream &os,
65                                 Region *perEntryOfThisRegion) const;
66 
67 private:
68   /// The operation this analysis was constructed from.
69   Operation *operation;
70 
71   /// A mapping from blocks to number of executions information.
72   DenseMap<Block *, BlockNumberOfExecutionsInfo> blockNumbersOfExecution;
73 };
74 
75 /// Represents number of block executions information.
76 class BlockNumberOfExecutionsInfo {
77 public:
78   BlockNumberOfExecutionsInfo(Block *block,
79                               Optional<int64_t> numberOfRegionInvocations,
80                               Optional<int64_t> numberOfBlockExecutions);
81 
82   /// Returns the number of times this block will be executed *each time* the
83   /// parent operation is executed.
84   Optional<int64_t> getNumberOfExecutions() const;
85 
86   /// Returns the number of times this block will be executed if the parent
87   /// region is invoked `numberOfRegionInvocations` times. This can be different
88   /// from the number of region invocations by the parent operation.
89   Optional<int64_t>
90   getNumberOfExecutions(int64_t numberOfRegionInvocations) const;
91 
getBlock()92   Block *getBlock() const { return block; }
93 
94 private:
95   Block *block;
96 
97   /// Number of `block` parent region invocations *each time* parent operation
98   /// is executed.
99   Optional<int64_t> numberOfRegionInvocations;
100 
101   /// Number of `block` executions *each time* parent region is invoked.
102   Optional<int64_t> numberOfBlockExecutions;
103 };
104 
105 } // end namespace mlir
106 
107 #endif // MLIR_ANALYSIS_NUMBER_OF_EXECUTIONS_H
108