This repository has been archived by the owner on May 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
/
Utils.h
155 lines (117 loc) · 5.96 KB
/
Utils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//===----------------------------------------------------------------------===//
//
// Adapated from ScaleHLS https://github.com/hanchenye/scalehls
//
//===----------------------------------------------------------------------===//
#ifndef OPENHLS_SUPPORT_UTILS_H
#define OPENHLS_SUPPORT_UTILS_H
#include "mlir/Dialect/Affine/IR/AffineOps.h"
#include "mlir/Dialect/Affine/IR/AffineValueMap.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
//#include "HLS.h"
namespace mlir {
class ModuleOp;
namespace openhls {
using namespace mlir::func;
//===----------------------------------------------------------------------===//
// Memory and loop analysis utils
//===----------------------------------------------------------------------===//
/// Parse array attributes.
SmallVector<int64_t, 8> getIntArrayAttrValue(Operation *op, StringRef name);
using AffineLoopBand = SmallVector<AffineForOp, 6>;
using AffineLoopBands = std::vector<AffineLoopBand>;
/// For storing all affine memory access operations (including AffineLoadOp, and
/// AffineStoreOp) indexed by the corresponding memref.
using MemAccessesMap = DenseMap<Value, SmallVector<Operation *, 16>>;
/// Collect all load and store operations in the block and return them in "map".
void getMemAccessesMap(Block &block, MemAccessesMap &map,
bool includeVectorTransfer = false);
/// Check if the lhsOp and rhsOp are in the same block. If so, return their
/// ancestors that are located at the same block. Note that in this check,
/// AffineIfOp is transparent.
Optional<std::pair<Operation *, Operation *>> checkSameLevel(Operation *lhsOp,
Operation *rhsOp);
unsigned getCommonSurroundingLoops(Operation *A, Operation *B,
AffineLoopBand *band);
/// Calculate the upper and lower bound of the affine map if possible.
Optional<std::pair<int64_t, int64_t>> getBoundOfAffineMap(AffineMap map,
ValueRange operands);
/// Calculate partition factors through analyzing the "memrefType" and return
/// them in "factors". Meanwhile, the overall partition number is calculated and
/// returned as well.
int64_t getPartitionFactors(MemRefType memrefType,
SmallVector<int64_t, 8> *factors = nullptr);
bool isFullyPartitioned(MemRefType memrefType);
/// This is method for finding the number of child loops which immediatedly
/// contained by the input operation.
unsigned getChildLoopNum(Operation *op);
/// Given a tiled loop band, return true and get the tile (tile-space) loop
/// band and the point (intra-tile) loop band. If failed, return false.
bool getTileAndPointLoopBand(const AffineLoopBand &band,
AffineLoopBand &tileBand,
AffineLoopBand &pointBand);
/// Get the whole loop band given the outermost loop and return it in "band".
/// Meanwhile, the return value is the innermost loop of this loop band.
AffineForOp getLoopBandFromOutermost(AffineForOp forOp, AffineLoopBand &band);
/// Collect all loop bands in the "block" and return them in "bands". If
/// "allowHavingChilds" is true, loop bands containing more than 1 other loop
/// bands are also collected. Otherwise, only loop bands that contains no child
/// loops are collected.
void getLoopBands(Block &block, AffineLoopBands &bands,
bool allowHavingChilds = false);
void getArrays(Block &block, SmallVectorImpl<Value> &arrays,
bool allowArguments = true);
Optional<unsigned> getAverageTripCount(AffineForOp forOp);
bool checkDependence(Operation *A, Operation *B);
/// Localize each tosa/arith constant to right before its each use. Only
/// localize the constants whose size is below the bitsThreshold.
void localizeConstants(Block &block, int64_t bitsThreshold = INT64_MAX);
FuncOp getTopFunc(ModuleOp module, std::string topFuncName = "");
FuncOp getRuntimeFunc(ModuleOp module, std::string runtimeFuncName = "");
//===----------------------------------------------------------------------===//
// PtrLikeMemRefAccess Struct Declaration
//===----------------------------------------------------------------------===//
/// Encapsulates a memref load or store access information.
struct PtrLikeMemRefAccess {
Value memref = nullptr;
AffineValueMap accessMap;
void *impl = nullptr;
/// Constructs a MemRefAccess from a load or store operation.
explicit PtrLikeMemRefAccess(Operation *opInst);
PtrLikeMemRefAccess(const void *impl) : impl(const_cast<void *>(impl)) {}
bool operator==(const PtrLikeMemRefAccess &rhs) const;
llvm::hash_code getHashValue() {
return llvm::hash_combine(memref, accessMap.getAffineMap(),
accessMap.getOperands(), impl);
}
};
using ReverseOpIteratorsMap =
DenseMap<PtrLikeMemRefAccess,
SmallVector<std::reverse_iterator<Operation **>, 16>>;
using OpIteratorsMap =
DenseMap<PtrLikeMemRefAccess, SmallVector<Operation **, 16>>;
} // namespace openhls
} // namespace mlir
//===----------------------------------------------------------------------===//
// Make PtrLikeMemRefAccess eligible as key of DenseMap
//===----------------------------------------------------------------------===//
namespace llvm {
template <> struct DenseMapInfo<mlir::openhls::PtrLikeMemRefAccess> {
static mlir::openhls::PtrLikeMemRefAccess getEmptyKey() {
auto pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
return mlir::openhls::PtrLikeMemRefAccess(pointer);
}
static mlir::openhls::PtrLikeMemRefAccess getTombstoneKey() {
auto pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
return mlir::openhls::PtrLikeMemRefAccess(pointer);
}
static unsigned getHashValue(mlir::openhls::PtrLikeMemRefAccess access) {
return access.getHashValue();
}
static bool isEqual(mlir::openhls::PtrLikeMemRefAccess lhs,
mlir::openhls::PtrLikeMemRefAccess rhs) {
return lhs == rhs;
}
};
} // namespace llvm
#endif // OPENHLS_SUPPORT_UTILS_H