CIRCT 22.0.0git
Loading...
Searching...
No Matches
Synth.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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
10
18#include "mlir-c/BuiltinAttributes.h"
19#include "mlir-c/IR.h"
20#include "mlir-c/Support.h"
21#include "mlir/CAPI/IR.h"
22#include "mlir/CAPI/Registration.h"
23#include "mlir/CAPI/Support.h"
24#include "mlir/Pass/AnalysisManager.h"
25#include "llvm/ADT/ImmutableList.h"
26#include "llvm/ADT/PointerUnion.h"
27#include "llvm/Support/JSON.h"
28#include <memory>
29#include <tuple>
30
31using namespace circt;
32using namespace circt::synth;
33
35
36MLIR_DEFINE_CAPI_DIALECT_REGISTRATION(Synth, synth, circt::synth::SynthDialect)
37
38void registerSynthPasses() { circt::synth::registerPasses(); }
39
40// Wrapper struct to hold both the analysis and the analysis manager
42 std::unique_ptr<mlir::ModuleAnalysisManager> analysisManager;
43 std::unique_ptr<LongestPathAnalysis> analysis;
44};
45
47DEFINE_C_API_PTR_METHODS(SynthLongestPathCollection, LongestPathCollection)
48DEFINE_C_API_PTR_METHODS(SynthLongestPathDataflowPath, DataflowPath)
49DEFINE_C_API_PTR_METHODS(SynthLongestPathHistory,
50 llvm::ImmutableListImpl<DebugPoint>)
51
52// SynthLongestPathObject is a pointer to either an Object or an OutputPort so
53// we can not use DEFINE_C_API_PTR_METHODS.
54llvm::PointerUnion<Object *, DataflowPath::OutputPort *>
55unwrap(SynthLongestPathObject object) {
56 return llvm::PointerUnion<
57 Object *, DataflowPath::OutputPort *>::getFromOpaqueValue(object.ptr);
58}
59
60SynthLongestPathObject
61wrap(llvm::PointerUnion<Object *, DataflowPath::OutputPort *> object) {
62 return SynthLongestPathObject{object.getOpaqueValue()};
63}
64
65SynthLongestPathObject wrap(const Object *object) {
66 auto ptr = llvm::PointerUnion<Object *, DataflowPath::OutputPort *>(
67 const_cast<Object *>(object));
68 return wrap(ptr);
69}
70
71SynthLongestPathObject wrap(const DataflowPath::OutputPort *object) {
72 auto ptr = llvm::PointerUnion<Object *, DataflowPath::OutputPort *>(
73 const_cast<DataflowPath::OutputPort *>(object));
74 return wrap(ptr);
75}
76
77//===----------------------------------------------------------------------===//
78// LongestPathAnalysis C API
79//===----------------------------------------------------------------------===//
80
81SynthLongestPathAnalysis
82synthLongestPathAnalysisCreate(MlirOperation module, bool collectDebugInfo,
83 bool keepOnlyMaxDelayPaths, bool lazyComputation,
84 MlirStringRef topModuleName) {
85 auto *op = unwrap(module);
86 auto *wrapper = new LongestPathAnalysisWrapper();
87 wrapper->analysisManager =
88 std::make_unique<mlir::ModuleAnalysisManager>(op, nullptr);
89 mlir::AnalysisManager am = *wrapper->analysisManager;
90 auto topModuleNameAttr =
91 StringAttr::get(op->getContext(), unwrap(topModuleName));
92 wrapper->analysis = std::make_unique<LongestPathAnalysis>(
93 op, am,
94 LongestPathAnalysisOptions(collectDebugInfo, lazyComputation,
95 keepOnlyMaxDelayPaths, topModuleNameAttr));
96 return wrap(wrapper);
97}
98
99void synthLongestPathAnalysisDestroy(SynthLongestPathAnalysis analysis) {
100 delete unwrap(analysis);
101}
102
103SynthLongestPathCollection
104synthLongestPathAnalysisGetPaths(SynthLongestPathAnalysis analysis,
105 MlirValue value, int64_t bitPos,
106 bool elaboratePaths) {
107 auto *wrapper = unwrap(analysis);
108 auto *lpa = wrapper->analysis.get();
109 auto *collection = new LongestPathCollection(lpa->getContext());
110 auto result =
111 lpa->computeGlobalPaths(unwrap(value), bitPos, collection->paths);
112 if (failed(result))
113 return {nullptr};
114 collection->sortInDescendingOrder();
115 return wrap(collection);
116}
117
118SynthLongestPathCollection
119synthLongestPathAnalysisGetInternalPaths(SynthLongestPathAnalysis analysis,
120 MlirStringRef moduleName,
121 bool elaboratePaths) {
122 auto *wrapper = unwrap(analysis);
123 auto *lpa = wrapper->analysis.get();
124 auto moduleNameAttr = StringAttr::get(lpa->getContext(), unwrap(moduleName));
125
126 auto *collection = new LongestPathCollection(lpa->getContext());
127 if (!lpa->isAnalysisAvailable(moduleNameAttr) ||
128 failed(lpa->getInternalPaths(moduleNameAttr, collection->paths,
129 elaboratePaths)))
130 return {nullptr};
131
132 collection->sortInDescendingOrder();
133 return wrap(collection);
134}
135
136// Get external paths from module input ports to internal sequential elements.
137SynthLongestPathCollection
139 SynthLongestPathAnalysis analysis, MlirStringRef moduleName) {
140 auto *wrapper = unwrap(analysis);
141 auto *lpa = wrapper->analysis.get();
142 auto moduleNameAttr = StringAttr::get(lpa->getContext(), unwrap(moduleName));
143
144 auto *collection = new LongestPathCollection(lpa->getContext());
145 if (!lpa->isAnalysisAvailable(moduleNameAttr) ||
146 failed(lpa->getOpenPathsFromInputPortsToInternal(moduleNameAttr,
147 collection->paths)))
148 return {nullptr};
149
150 collection->sortInDescendingOrder();
151 return wrap(collection);
152}
153
154// Get external paths from internal sequential elements to module output ports.
155SynthLongestPathCollection
157 SynthLongestPathAnalysis analysis, MlirStringRef moduleName) {
158 auto *wrapper = unwrap(analysis);
159 auto *lpa = wrapper->analysis.get();
160 auto moduleNameAttr = StringAttr::get(lpa->getContext(), unwrap(moduleName));
161
162 auto *collection = new LongestPathCollection(lpa->getContext());
163 if (!lpa->isAnalysisAvailable(moduleNameAttr) ||
164 failed(lpa->getOpenPathsFromInternalToOutputPorts(moduleNameAttr,
165 collection->paths)))
166 return {nullptr};
167
168 collection->sortInDescendingOrder();
169 return wrap(collection);
170}
171
172// ===----------------------------------------------------------------------===//
173// LongestPathCollection
174// ===----------------------------------------------------------------------===//
175
176bool synthLongestPathCollectionIsNull(SynthLongestPathCollection collection) {
177 return !collection.ptr;
178}
179
180void synthLongestPathCollectionDestroy(SynthLongestPathCollection collection) {
181 delete unwrap(collection);
182}
183
184size_t
185synthLongestPathCollectionGetSize(SynthLongestPathCollection collection) {
186 auto *wrapper = unwrap(collection);
187 return wrapper->paths.size();
188}
189
190// Get a specific path from the collection as DataflowPath object
191SynthLongestPathDataflowPath
192synthLongestPathCollectionGetDataflowPath(SynthLongestPathCollection collection,
193 size_t index) {
194 auto *wrapper = unwrap(collection);
195 auto &path = wrapper->paths[index];
196 return wrap(&path);
197}
198
199void synthLongestPathCollectionMerge(SynthLongestPathCollection dest,
200 SynthLongestPathCollection src) {
201 auto *destWrapper = unwrap(dest);
202 auto *srcWrapper = unwrap(src);
203 destWrapper->merge(*srcWrapper);
204}
205
207 SynthLongestPathCollection collection, bool perEndPoint) {
208 auto *wrapper = unwrap(collection);
209 wrapper->dropNonCriticalPaths(perEndPoint);
210}
211
212//===----------------------------------------------------------------------===//
213// DataflowPath
214//===----------------------------------------------------------------------===//
215
216int64_t
217synthLongestPathDataflowPathGetDelay(SynthLongestPathDataflowPath path) {
218 auto *wrapper = unwrap(path);
219 return wrapper->getDelay();
220}
221
222SynthLongestPathObject
223synthLongestPathDataflowPathGetStartPoint(SynthLongestPathDataflowPath path) {
224 auto *wrapper = unwrap(path);
225 auto &startPoint = wrapper->getStartPoint();
226 return wrap(const_cast<Object *>(&startPoint));
227}
228
229SynthLongestPathObject
230synthLongestPathDataflowPathGetEndPoint(SynthLongestPathDataflowPath path) {
231 auto *wrapper = unwrap(path);
232 if (auto *object = std::get_if<Object>(&wrapper->getEndPoint())) {
233 return wrap(object);
234 }
235 auto *ptr = std::get_if<DataflowPath::OutputPort>(&wrapper->getEndPoint());
236 return wrap(ptr);
237}
238
239SynthLongestPathHistory
240synthLongestPathDataflowPathGetHistory(SynthLongestPathDataflowPath path) {
241 auto *wrapper = unwrap(path);
242 return wrap(const_cast<llvm::ImmutableListImpl<DebugPoint> *>(
243 wrapper->getHistory().getInternalPointer()));
244}
245
246MlirOperation
247synthLongestPathDataflowPathGetRoot(SynthLongestPathDataflowPath path) {
248 auto *wrapper = unwrap(path);
249 return wrap(wrapper->getRoot());
250}
251
252//===----------------------------------------------------------------------===//
253// History
254//===----------------------------------------------------------------------===//
255
256bool synthLongestPathHistoryIsEmpty(SynthLongestPathHistory history) {
257 auto *wrapper = unwrap(history);
258 return llvm::ImmutableList<DebugPoint>(wrapper).isEmpty();
259}
260
261void synthLongestPathHistoryGetHead(SynthLongestPathHistory history,
262 SynthLongestPathObject *object,
263 int64_t *delay, MlirStringRef *comment) {
264 auto *wrapper = unwrap(history);
265 auto list = llvm::ImmutableList<DebugPoint>(wrapper);
266
267 auto &head = list.getHead();
268 *object = wrap(&head.object);
269 *delay = head.delay;
270 *comment = mlirStringRefCreate(head.comment.data(), head.comment.size());
271}
272
273SynthLongestPathHistory
274synthLongestPathHistoryGetTail(SynthLongestPathHistory history) {
275 auto *wrapper = unwrap(history);
276 auto list = llvm::ImmutableList<DebugPoint>(wrapper);
277 auto *tail = list.getTail().getInternalPointer();
278 return wrap(const_cast<llvm::ImmutableListImpl<DebugPoint> *>(tail));
279}
280
281//===----------------------------------------------------------------------===//
282// Object
283//===----------------------------------------------------------------------===//
284
286synthLongestPathObjectGetInstancePath(SynthLongestPathObject object) {
287 auto *ptr = dyn_cast<Object *>(unwrap(object));
288 if (ptr) {
289 IgraphInstancePath result;
290 result.ptr = const_cast<igraph::InstanceOpInterface *>(
291 ptr->instancePath.getPath().data());
292 result.size = ptr->instancePath.getPath().size();
293 return result;
294 }
295
296 // This is output port so the instance path is empty.
297 return {nullptr, 0};
298}
299
300MlirStringRef synthLongestPathObjectName(SynthLongestPathObject rawObject) {
301 auto ptr = unwrap(rawObject);
302 if (auto *object = dyn_cast<Object *>(ptr)) {
303 auto name = object->getName();
304 return mlirStringRefCreate(name.data(), name.size());
305 }
306 auto [module, resultNumber, _] = *dyn_cast<DataflowPath::OutputPort *>(ptr);
307 auto name = module.getOutputName(resultNumber);
308 return mlirStringRefCreate(name.data(), name.size());
309}
310
311size_t synthLongestPathObjectBitPos(SynthLongestPathObject rawObject) {
312 auto ptr = unwrap(rawObject);
313 if (auto *object = dyn_cast<Object *>(ptr))
314 return object->bitPos;
315 return std::get<2>(*dyn_cast<DataflowPath::OutputPort *>(ptr));
316}
MLIR_DEFINE_CAPI_DIALECT_REGISTRATION(CHIRRTL, chirrtl, circt::chirrtl::CHIRRTLDialect) MlirType chirrtlTypeGetCMemory(MlirContext ctx
static EvaluatorValuePtr unwrap(OMEvaluatorValue c)
Definition OM.cpp:111
size_t synthLongestPathCollectionGetSize(SynthLongestPathCollection collection)
Definition Synth.cpp:185
MlirStringRef synthLongestPathObjectName(SynthLongestPathObject rawObject)
Definition Synth.cpp:300
void synthLongestPathHistoryGetHead(SynthLongestPathHistory history, SynthLongestPathObject *object, int64_t *delay, MlirStringRef *comment)
Definition Synth.cpp:261
IgraphInstancePath synthLongestPathObjectGetInstancePath(SynthLongestPathObject object)
Definition Synth.cpp:286
void synthLongestPathAnalysisDestroy(SynthLongestPathAnalysis analysis)
Definition Synth.cpp:99
void synthLongestPathCollectionDestroy(SynthLongestPathCollection collection)
Definition Synth.cpp:180
void synthLongestPathCollectionDropNonCriticalPaths(SynthLongestPathCollection collection, bool perEndPoint)
Definition Synth.cpp:206
SynthLongestPathCollection synthLongestPathAnalysisGetPathsFromInternalToOutputPorts(SynthLongestPathAnalysis analysis, MlirStringRef moduleName)
Definition Synth.cpp:156
SynthLongestPathObject synthLongestPathDataflowPathGetStartPoint(SynthLongestPathDataflowPath path)
Definition Synth.cpp:223
SynthLongestPathCollection synthLongestPathAnalysisGetPaths(SynthLongestPathAnalysis analysis, MlirValue value, int64_t bitPos, bool elaboratePaths)
Definition Synth.cpp:104
SynthLongestPathHistory synthLongestPathDataflowPathGetHistory(SynthLongestPathDataflowPath path)
Definition Synth.cpp:240
SynthLongestPathCollection synthLongestPathAnalysisGetPathsFromInputPortsToInternal(SynthLongestPathAnalysis analysis, MlirStringRef moduleName)
Definition Synth.cpp:138
SynthLongestPathAnalysis synthLongestPathAnalysisCreate(MlirOperation module, bool collectDebugInfo, bool keepOnlyMaxDelayPaths, bool lazyComputation, MlirStringRef topModuleName)
Definition Synth.cpp:82
SynthLongestPathObject synthLongestPathDataflowPathGetEndPoint(SynthLongestPathDataflowPath path)
Definition Synth.cpp:230
bool synthLongestPathCollectionIsNull(SynthLongestPathCollection collection)
Definition Synth.cpp:176
void synthLongestPathCollectionMerge(SynthLongestPathCollection dest, SynthLongestPathCollection src)
Definition Synth.cpp:199
DEFINE_C_API_PTR_METHODS(SynthLongestPathHistory, llvm::ImmutableListImpl< DebugPoint >) llvm
Definition Synth.cpp:49
SynthLongestPathDataflowPath synthLongestPathCollectionGetDataflowPath(SynthLongestPathCollection collection, size_t index)
Definition Synth.cpp:192
int64_t synthLongestPathDataflowPathGetDelay(SynthLongestPathDataflowPath path)
Definition Synth.cpp:217
void registerSynthPasses()
Definition Synth.cpp:38
bool synthLongestPathHistoryIsEmpty(SynthLongestPathHistory history)
Definition Synth.cpp:256
SynthLongestPathObject wrap(llvm::PointerUnion< Object *, DataflowPath::OutputPort * > object)
Definition Synth.cpp:61
MlirOperation synthLongestPathDataflowPathGetRoot(SynthLongestPathDataflowPath path)
Definition Synth.cpp:247
SynthLongestPathHistory synthLongestPathHistoryGetTail(SynthLongestPathHistory history)
Definition Synth.cpp:274
size_t synthLongestPathObjectBitPos(SynthLongestPathObject rawObject)
Definition Synth.cpp:311
SynthLongestPathCollection synthLongestPathAnalysisGetInternalPaths(SynthLongestPathAnalysis analysis, MlirStringRef moduleName, bool elaboratePaths)
Definition Synth.cpp:119
std::tuple< hw::HWModuleOp, size_t, size_t > OutputPort
void registerSynthesisPipeline()
Register the synthesis pipelines.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition synth.py:1
std::unique_ptr< LongestPathAnalysis > analysis
Definition Synth.cpp:43
std::unique_ptr< mlir::ModuleAnalysisManager > analysisManager
Definition Synth.cpp:42
Configuration options for the longest path analysis.