1111//
1212// ===----------------------------------------------------------------------===//
1313
14- #include " circt/Conversion/ArcToLLVM.h"
15- #include " circt/Conversion/CombToArith.h"
16- #include " circt/Conversion/ConvertToArcs.h"
1714#include " circt/Conversion/Passes.h"
18- #include " circt/Conversion/SeqToSV.h"
1915#include " circt/Dialect/Arc/ArcDialect.h"
2016#include " circt/Dialect/Arc/ArcInterfaces.h"
2117#include " circt/Dialect/Arc/ArcOps.h"
2420#include " circt/Dialect/Arc/ModelInfoExport.h"
2521#include " circt/Dialect/Comb/CombDialect.h"
2622#include " circt/Dialect/Emit/EmitDialect.h"
27- #include " circt/Dialect/Emit/EmitPasses.h"
28- #include " circt/Dialect/HW/HWPasses.h"
2923#include " circt/Dialect/LLHD/IR/LLHDDialect.h"
3024#include " circt/Dialect/OM/OMDialect.h"
31- #include " circt/Dialect/OM/OMPasses.h"
3225#include " circt/Dialect/SV/SVDialect.h"
33- #include " circt/Dialect/Seq/SeqPasses.h"
3426#include " circt/Dialect/Sim/SimDialect.h"
35- #include " circt/Dialect/Sim/SimPasses.h"
3627#include " circt/Dialect/Verif/VerifDialect.h"
3728#include " circt/Support/Passes.h"
3829#include " circt/Support/Version.h"
6455#include " mlir/Target/LLVMIR/Export.h"
6556#include " mlir/Transforms/GreedyPatternRewriteDriver.h"
6657#include " mlir/Transforms/Passes.h"
58+ #include " pipelines.h"
6759#include " llvm/IR/LLVMContext.h"
6860#include " llvm/IR/Module.h"
6961#include " llvm/Support/CommandLine.h"
@@ -96,59 +88,12 @@ static llvm::cl::opt<std::string>
9688 llvm::cl::value_desc(" filename" ), llvm::cl::init(" -" ),
9789 llvm::cl::cat(mainCategory));
9890
99- static llvm::cl::opt<bool >
100- observePorts (" observe-ports" , llvm::cl::desc(" Make all ports observable" ),
101- llvm::cl::init(false ), llvm::cl::cat(mainCategory));
102-
103- static llvm::cl::opt<bool >
104- observeWires (" observe-wires" , llvm::cl::desc(" Make all wires observable" ),
105- llvm::cl::init(false ), llvm::cl::cat(mainCategory));
106-
107- static llvm::cl::opt<bool > observeNamedValues (
108- " observe-named-values" ,
109- llvm::cl::desc (" Make values with `sv.namehint` observable" ),
110- llvm::cl::init(false ), llvm::cl::cat(mainCategory));
111-
112- static llvm::cl::opt<bool >
113- observeRegisters (" observe-registers" ,
114- llvm::cl::desc (" Make all registers observable" ),
115- llvm::cl::init(false ), llvm::cl::cat(mainCategory));
116-
117- static llvm::cl::opt<bool >
118- observeMemories (" observe-memories" ,
119- llvm::cl::desc (" Make all memory contents observable" ),
120- llvm::cl::init(false ), llvm::cl::cat(mainCategory));
121-
12291static llvm::cl::opt<std::string> stateFile (" state-file" ,
12392 llvm::cl::desc (" State file" ),
12493 llvm::cl::value_desc(" filename" ),
12594 llvm::cl::init(" " ),
12695 llvm::cl::cat(mainCategory));
12796
128- static llvm::cl::opt<bool > shouldInline (" inline" , llvm::cl::desc(" Inline arcs" ),
129- llvm::cl::init(true ),
130- llvm::cl::cat(mainCategory));
131-
132- static llvm::cl::opt<bool > shouldDedup (" dedup" ,
133- llvm::cl::desc (" Deduplicate arcs" ),
134- llvm::cl::init(true ),
135- llvm::cl::cat(mainCategory));
136-
137- static llvm::cl::opt<bool > shouldDetectEnables (
138- " detect-enables" ,
139- llvm::cl::desc (" Infer enable conditions for states to avoid computation" ),
140- llvm::cl::init(true ), llvm::cl::cat(mainCategory));
141-
142- static llvm::cl::opt<bool > shouldDetectResets (
143- " detect-resets" ,
144- llvm::cl::desc (" Infer reset conditions for states to avoid computation" ),
145- llvm::cl::init(false ), llvm::cl::cat(mainCategory));
146-
147- static llvm::cl::opt<bool >
148- shouldMakeLUTs (" lookup-tables" ,
149- llvm::cl::desc (" Optimize arcs into lookup tables" ),
150- llvm::cl::init(true ), llvm::cl::cat(mainCategory));
151-
15297static llvm::cl::opt<bool >
15398 printDebugInfo (" print-debug-info" ,
15499 llvm::cl::desc (" Print debug information" ),
@@ -176,12 +121,6 @@ static llvm::cl::opt<bool> splitInputFile(
176121 " chunk independently" ),
177122 llvm::cl::init(false ), llvm::cl::Hidden, llvm::cl::cat(mainCategory));
178123
179- static llvm::cl::opt<unsigned > splitFuncsThreshold (
180- " split-funcs-threshold" ,
181- llvm::cl::desc (
182- " Split large MLIR functions that occur above the given size threshold" ),
183- llvm::cl::ValueOptional, llvm::cl::cat(mainCategory));
184-
185124// Options to control early-out from pipeline.
186125enum Until {
187126 UntilPreprocessing,
@@ -250,105 +189,28 @@ static void populateHwModuleToArcPipeline(PassManager &pm) {
250189 // represented as intrinsic ops.
251190 if (untilReached (UntilPreprocessing))
252191 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 ());
192+ arcPreprocessingPipeline (pm);
274193
275194 // Restructure the input from a `hw.module` hierarchy to a collection of arcs.
276195 if (untilReached (UntilArcConversion))
277196 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 ());
197+ arcConversionPipeline (pm);
288198
289199 // Perform arc-level optimizations that are not specific to software
290200 // simulation.
291201 if (untilReached (UntilArcOpt))
292202 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-
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());
203+ arcOptimizationPipeline (pm);
321204
322205 // Lower stateful arcs into explicit state reads and writes.
323206 if (untilReached (UntilStateLowering))
324207 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 ());
208+ arcStateLoweringPipeline (pm);
339209
340210 // Allocate states.
341211 if (untilReached (UntilStateAlloc))
342212 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 ());
213+ arcStateAllocationPipeline (pm);
352214}
353215
354216// / Populate a pass manager with the Arc to LLVM pipeline for the given
@@ -357,9 +219,7 @@ static void populateArcToLLVMPipeline(PassManager &pm) {
357219 // Lower the arcs and update functions to LLVM.
358220 if (untilReached (UntilLLVMLowering))
359221 return ;
360- pm.addPass (createLowerArcToLLVMPass ());
361- pm.addPass (createCSEPass ());
362- pm.addPass (arc::createArcCanonicalizerPass ());
222+ arcToLLVMPipeline (pm);
363223}
364224
365225static LogicalResult processBuffer (
@@ -379,6 +239,7 @@ static LogicalResult processBuffer(
379239 pmArc.enableTiming (ts);
380240 if (failed (applyPassManagerCLOptions (pmArc)))
381241 return failure ();
242+
382243 populateHwModuleToArcPipeline (pmArc);
383244
384245 if (failed (pmArc.run (module .get ())))
0 commit comments