|
36 | 36 | #include "circt/Dialect/Verif/VerifDialect.h" |
37 | 37 | #include "circt/Support/Passes.h" |
38 | 38 | #include "circt/Support/Version.h" |
| 39 | +#include "circt/Tools/arcilator/pipelines.h" |
39 | 40 | #include "mlir/Bytecode/BytecodeReader.h" |
40 | 41 | #include "mlir/Bytecode/BytecodeWriter.h" |
41 | 42 | #include "mlir/Dialect/Arith/IR/Arith.h" |
@@ -250,105 +251,49 @@ static void populateHwModuleToArcPipeline(PassManager &pm) { |
250 | 251 | // represented as intrinsic ops. |
251 | 252 | if (untilReached(UntilPreprocessing)) |
252 | 253 | return; |
253 | | - pm.addPass(om::createStripOMPass()); |
254 | | - pm.addPass(emit::createStripEmitPass()); |
255 | | - pm.addPass(createLowerFirMemPass()); |
256 | | - pm.addPass(createLowerVerifSimulationsPass()); |
257 | | - { |
258 | | - arc::AddTapsOptions opts; |
259 | | - opts.tapPorts = observePorts; |
260 | | - opts.tapWires = observeWires; |
261 | | - opts.tapNamedValues = observeNamedValues; |
262 | | - pm.addPass(arc::createAddTapsPass(opts)); |
263 | | - } |
264 | | - pm.addPass(arc::createStripSVPass()); |
265 | | - { |
266 | | - arc::InferMemoriesOptions opts; |
267 | | - opts.tapPorts = observePorts; |
268 | | - opts.tapMemories = observeMemories; |
269 | | - pm.addPass(arc::createInferMemoriesPass(opts)); |
270 | | - } |
271 | | - pm.addPass(sim::createLowerDPIFunc()); |
272 | | - pm.addPass(createCSEPass()); |
273 | | - pm.addPass(arc::createArcCanonicalizerPass()); |
| 254 | + |
| 255 | + ArcPreprocessingOptions preprocessing_opt; |
| 256 | + preprocessing_opt.observePorts = observePorts; |
| 257 | + preprocessing_opt.observeWires = observeWires; |
| 258 | + preprocessing_opt.observeNamedValues = observeNamedValues; |
| 259 | + preprocessing_opt.observeMemories = observeMemories; |
| 260 | + arcPreprocessingPipeline(pm, preprocessing_opt); |
274 | 261 |
|
275 | 262 | // Restructure the input from a `hw.module` hierarchy to a collection of arcs. |
276 | 263 | if (untilReached(UntilArcConversion)) |
277 | 264 | return; |
278 | | - { |
279 | | - ConvertToArcsPassOptions opts; |
280 | | - opts.tapRegisters = observeRegisters; |
281 | | - pm.addPass(createConvertToArcsPass(opts)); |
282 | | - } |
283 | | - if (shouldDedup) |
284 | | - pm.addPass(arc::createDedupPass()); |
285 | | - pm.addPass(hw::createFlattenModules()); |
286 | | - pm.addPass(createCSEPass()); |
287 | | - pm.addPass(arc::createArcCanonicalizerPass()); |
| 265 | + |
| 266 | + ArcConversionOptions conversion_opt; |
| 267 | + conversion_opt.observeRegisters = observeRegisters; |
| 268 | + conversion_opt.shouldDedup = shouldDedup; |
| 269 | + arcConversionPipeline(pm, conversion_opt); |
288 | 270 |
|
289 | 271 | // Perform arc-level optimizations that are not specific to software |
290 | 272 | // simulation. |
291 | 273 | if (untilReached(UntilArcOpt)) |
292 | 274 | return; |
293 | | - pm.addPass(arc::createSplitLoopsPass()); |
294 | | - if (shouldDedup) |
295 | | - pm.addPass(arc::createDedupPass()); |
296 | | - { |
297 | | - arc::InferStatePropertiesOptions opts; |
298 | | - opts.detectEnables = shouldDetectEnables; |
299 | | - opts.detectResets = shouldDetectResets; |
300 | | - pm.addPass(arc::createInferStateProperties(opts)); |
301 | | - } |
302 | | - pm.addPass(createCSEPass()); |
303 | | - pm.addPass(arc::createArcCanonicalizerPass()); |
304 | | - pm.addNestedPass<hw::HWModuleOp>(arc::createMergeTaps()); |
305 | | - if (shouldMakeLUTs) |
306 | | - pm.addPass(arc::createMakeTablesPass()); |
307 | | - pm.addPass(createCSEPass()); |
308 | | - pm.addPass(arc::createArcCanonicalizerPass()); |
309 | 275 |
|
310 | | - // Now some arguments may be unused because reset conditions are not passed as |
311 | | - // inputs anymore pm.addPass(arc::createRemoveUnusedArcArgumentsPass()); |
312 | | - // Because we replace a lot of StateOp inputs with constants in the enable |
313 | | - // patterns we may be able to sink a lot of them |
314 | | - // TODO: maybe merge RemoveUnusedArcArguments with SinkInputs? |
315 | | - // pm.addPass(arc::createSinkInputsPass()); |
316 | | - // pm.addPass(createCSEPass()); |
317 | | - // pm.addPass(createSimpleCanonicalizerPass()); |
318 | | - // Removing some muxes etc. may lead to additional dedup opportunities |
319 | | - // if (shouldDedup) |
320 | | - // pm.addPass(arc::createDedupPass()); |
| 276 | + ArcOptimizationOptions optimization_opt; |
| 277 | + optimization_opt.shouldDetectEnables = shouldDetectEnables; |
| 278 | + optimization_opt.shouldDetectResets = shouldDetectResets; |
| 279 | + optimization_opt.shouldMakeLUTs = shouldMakeLUTs; |
| 280 | + arcOptimizationPipeline(pm, optimization_opt); |
321 | 281 |
|
322 | 282 | // Lower stateful arcs into explicit state reads and writes. |
323 | 283 | if (untilReached(UntilStateLowering)) |
324 | 284 | return; |
325 | | - pm.addPass(arc::createLowerStatePass()); |
326 | | - |
327 | | - // TODO: LowerClocksToFuncsPass might not properly consider scf.if operations |
328 | | - // (or nested regions in general) and thus errors out when muxes are also |
329 | | - // converted in the hw.module or arc.model |
330 | | - // TODO: InlineArcs seems to not properly handle scf.if operations, thus the |
331 | | - // following is commented out |
332 | | - // pm.addPass(arc::createMuxToControlFlowPass()); |
333 | | - if (shouldInline) |
334 | | - pm.addPass(arc::createInlineArcsPass()); |
335 | | - |
336 | | - pm.addPass(arc::createMergeIfsPass()); |
337 | | - pm.addPass(createCSEPass()); |
338 | | - pm.addPass(arc::createArcCanonicalizerPass()); |
| 285 | + |
| 286 | + ArcStateLoweringOptions lowering_opt; |
| 287 | + lowering_opt.shouldInline = shouldInline; |
| 288 | + arcStateLoweringPipeline(pm, lowering_opt); |
339 | 289 |
|
340 | 290 | // Allocate states. |
341 | 291 | if (untilReached(UntilStateAlloc)) |
342 | 292 | return; |
343 | | - pm.addPass(arc::createLowerArcsToFuncsPass()); |
344 | | - pm.nest<arc::ModelOp>().addPass(arc::createAllocateStatePass()); |
345 | | - pm.addPass(arc::createLowerClocksToFuncsPass()); // no CSE between state alloc |
346 | | - // and clock func lowering |
347 | | - if (splitFuncsThreshold.getNumOccurrences()) { |
348 | | - pm.addPass(arc::createSplitFuncs({splitFuncsThreshold})); |
349 | | - } |
350 | | - pm.addPass(createCSEPass()); |
351 | | - pm.addPass(arc::createArcCanonicalizerPass()); |
| 293 | + |
| 294 | + ArcStateAllocationOptions allocation_opt; |
| 295 | + allocation_opt.splitFuncsThreshold = splitFuncsThreshold; |
| 296 | + arcStateAllocationPipeline(pm, allocation_opt); |
352 | 297 | } |
353 | 298 |
|
354 | 299 | /// Populate a pass manager with the Arc to LLVM pipeline for the given |
|
0 commit comments