CIRCT 23.0.0git
Loading...
Searching...
No Matches
pipelines.cpp
Go to the documentation of this file.
1//===- pipelines.cpp - Arcilator lowering pipelines -----------------------===//
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 the 'arcilator' lowering pipelines.
10//
11//===----------------------------------------------------------------------===//
12
14
28#include "mlir/Transforms/Passes.h"
29
30using namespace mlir;
31using namespace circt;
32using namespace arc;
33
35 OpPassManager &pm, const ArcPreprocessingOptions &options) {
36 pm.addPass(arc::createResolveXMRRef());
37 pm.addPass(om::createStripOMPass());
38 pm.addPass(emit::createStripEmitPass());
39 pm.addPass(createLowerFirMemPass());
40 pm.addPass(createLowerVerifSimulationsPass());
41 {
42 arc::AddTapsOptions opts;
43 opts.tapPorts = options.observePorts;
44 opts.tapWires = options.observeWires;
45 opts.tapNamedValues = options.observeNamedValues;
46 pm.addPass(arc::createAddTaps(opts));
47 }
48 pm.addPass(arc::createStripSV({options.asyncResetsAsSync}));
49 {
50 arc::InferMemoriesOptions opts;
51 opts.tapPorts = options.observePorts;
52 opts.tapMemories = options.observeMemories;
53 pm.addPass(arc::createInferMemories(opts));
54 }
55 pm.addPass(sim::createLowerDPIFunc());
56 pm.addPass(createCSEPass());
57 pm.addPass(arc::createArcCanonicalizer());
58}
59
60void circt::populateArcConversionPipeline(OpPassManager &pm,
61 const ArcConversionOptions &options) {
62 {
63 sim::SquashSimTriggeredOptions opts;
64 opts.convertToHW = true;
65 pm.addNestedPass<hw::HWModuleOp>(sim::createSquashSimTriggered(opts));
66 }
67 pm.addPass(arc::createLowerProcessesPass());
68 {
69 ConvertToArcsPassOptions opts;
70 opts.tapRegisters = options.observeRegisters;
71 pm.addPass(createConvertToArcsPass(opts));
72 }
73 if (options.shouldDedup)
74 pm.addPass(arc::createDedup());
75 pm.addPass(hw::createFlattenModules());
76 pm.addPass(createCSEPass());
77 pm.addPass(arc::createArcCanonicalizer());
78}
79
81 OpPassManager &pm, const ArcOptimizationOptions &options) {
82 // Perform arc-level optimizations that are not specific to software
83 // simulation.
84 pm.addPass(arc::createSplitLoops());
85 if (options.shouldDedup)
86 pm.addPass(arc::createDedup());
87 {
88 arc::InferStatePropertiesOptions opts;
89 opts.detectEnables = options.shouldDetectEnables;
90 opts.detectResets = options.shouldDetectResets;
91 pm.addPass(arc::createInferStateProperties(opts));
92 }
93 pm.addPass(createCSEPass());
94 pm.addPass(arc::createArcCanonicalizer());
95 pm.addNestedPass<hw::HWModuleOp>(arc::createMergeTaps());
96 if (options.shouldMakeLUTs)
97 pm.addPass(arc::createMakeTables());
98 pm.addPass(createCSEPass());
99 pm.addPass(arc::createArcCanonicalizer());
100
101 // Now some arguments may be unused because reset conditions are not passed as
102 // inputs anymore pm.addPass(arc::createRemoveUnusedArcArguments());
103 // Because we replace a lot of StateOp inputs with constants in the enable
104 // patterns we may be able to sink a lot of them
105 // TODO: maybe merge RemoveUnusedArcArguments with SinkInputs?
106 // pm.addPass(arc::createSinkInputs());
107 // pm.addPass(createCSEPass());
108 // pm.addPass(createSimpleCanonicalizerPass());
109 // Removing some muxes etc. may lead to additional dedup opportunities
110 // if (options.shouldDedup)
111 // pm.addPass(arc::createDedup());
112}
113
115 OpPassManager &pm, const ArcStateLoweringOptions &options) {
116 pm.addPass(arc::createLowerStatePass());
117
118 // TODO: LowerClocksToFuncsPass might not properly consider scf.if operations
119 // (or nested regions in general) and thus errors out when muxes are also
120 // converted in the hw.module or arc.model
121 // TODO: InlineArcs seems to not properly handle scf.if operations, thus the
122 // following is commented out
123 // pm.addPass(arc::createMuxToControlFlow());
124 if (options.shouldInline)
125 pm.addPass(arc::createInlineArcs());
126
127 pm.addPass(arc::createMergeIfsPass());
128 pm.addPass(createCSEPass());
129 pm.addPass(arc::createArcCanonicalizer());
130 pm.addPass(arc::createLowerCoroutinesPass());
131}
132
134 OpPassManager &pm, const ArcStateAllocationOptions &options) {
135 pm.addPass(arc::createLowerArcsToFuncs());
136 pm.addPass(arc::createRemoveI0Types());
137 {
138 AllocateStateOptions allocStateOpts;
139 allocStateOpts.insertTraceTaps = options.insertTraceTaps;
140 pm.nest<arc::ModelOp>().addPass(arc::createAllocateState(allocStateOpts));
141 }
142 pm.nest<arc::ModelOp>().addPass(arc::createAllocateState());
143 pm.addPass(arc::createLowerClocksToFuncs()); // no CSE between state alloc
144 // and clock func lowering
145 if (options.splitFuncsThreshold.getNumOccurrences()) {
146 pm.addPass(arc::createSplitFuncs({options.splitFuncsThreshold}));
147 }
148 pm.addPass(createCSEPass());
149 pm.addPass(arc::createArcCanonicalizer());
150}
151
152void circt::populateArcToLLVMPipeline(OpPassManager &pm,
153 const ArcToLLVMOptions &options) {
154 if (!options.noGenerateDriver)
155 pm.addPass(createGenerateDriver());
156 {
157 hw::HWConvertBitcastsOptions options;
158 options.allowPartialConversion = false;
159 pm.addPass(hw::createHWConvertBitcasts(options));
160 }
161 if (!options.noRuntime) {
162 InsertRuntimeOptions opts;
163 opts.extraArgs = options.extraRuntimeArgs;
164 opts.traceFileName = options.traceFileName;
165 pm.addPass(createInsertRuntime(opts));
166 }
167 if (options.bufferizeArrays) {
168 pm.addPass(createLowerArrays());
169 }
170 pm.addPass(createLowerArcToLLVMPass());
171 pm.addPass(createCSEPass());
172 pm.addPass(arc::createArcCanonicalizer());
173}
Definition arc.py:1
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
void populateArcStateLoweringPipeline(mlir::OpPassManager &pm, const ArcStateLoweringOptions &options={})
void populateArcToLLVMPipeline(mlir::OpPassManager &pm, const ArcToLLVMOptions &options={})
void populateArcOptimizationPipeline(mlir::OpPassManager &pm, const ArcOptimizationOptions &options={})
void populateArcConversionPipeline(mlir::OpPassManager &pm, const ArcConversionOptions &options={})
std::unique_ptr< mlir::Pass > createLowerFirMemPass()
std::unique_ptr< OperationPass< ModuleOp > > createLowerArcToLLVMPass()
void populateArcPreprocessingPipeline(mlir::OpPassManager &pm, const ArcPreprocessingOptions &options={})
void populateArcStateAllocationPipeline(mlir::OpPassManager &pm, const ArcStateAllocationOptions &options={})
Option< bool > observeRegisters
Definition pipelines.h:55
Option< bool > shouldDedup
Definition pipelines.h:59
Option< bool > shouldMakeLUTs
Definition pipelines.h:82
Option< bool > shouldDetectResets
Definition pipelines.h:77
Option< bool > shouldDetectEnables
Definition pipelines.h:72
Option< bool > observeNamedValues
Definition pipelines.h:35
Option< bool > observeMemories
Definition pipelines.h:40
Option< bool > asyncResetsAsSync
Definition pipelines.h:45
Option< unsigned > splitFuncsThreshold
Definition pipelines.h:101
Option< bool > noGenerateDriver
Definition pipelines.h:117
Option< std::string > extraRuntimeArgs
Definition pipelines.h:125