Skip to content

Commit e2076bf

Browse files
authored
[FirParser] Add instance choice selection as circt attribute (#7951)
Add a select option to firtool for instance choice specialization. The specified select argument is added as an attribute on the `CircuitOp`. The attribute is an array of strings, each string specifies the selected specialization for an option. The error checking will be done by the `SpecializeOptions` pass.
1 parent baba42c commit e2076bf

File tree

5 files changed

+35
-12
lines changed

5 files changed

+35
-12
lines changed

include/circt/Dialect/FIRRTL/FIRParser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ struct FIRParserOptions {
5555
std::vector<std::string> enableLayers;
5656
std::vector<std::string> disableLayers;
5757
std::optional<LayerSpecialization> defaultLayerSpecialization;
58+
std::vector<std::string> selectInstanceChoice;
5859
};
5960

6061
mlir::OwningOpRef<mlir::ModuleOp> importFIRFile(llvm::SourceMgr &sourceMgr,

include/circt/Dialect/FIRRTL/FIRRTLStructure.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ def CircuitOp : FIRRTLOp<"circuit",
3636
DefaultValuedAttr<AnnotationArrayAttr, "{}">:$annotations,
3737
OptionalAttr<SymbolRefArrayAttr>:$enable_layers,
3838
OptionalAttr<SymbolRefArrayAttr>:$disable_layers,
39-
OptionalAttr<LayerSpecializationAttr>:$default_layer_specialization
39+
OptionalAttr<LayerSpecializationAttr>:$default_layer_specialization,
40+
OptionalAttr<ArrayAttr>:$select_inst_choice
4041
);
4142
let results = (outs);
4243
let regions = (region SizedRegion<1>:$body);

lib/Dialect/FIRRTL/Import/FIRParser.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5804,7 +5804,7 @@ ParseResult FIRCircuitParser::parseCircuit(
58045804

58055805
// Helper to transform a layer name specification of the form `A::B::C` into
58065806
// a SymbolRefAttr.
5807-
auto parseLayerName = [&](StringRef name) {
5807+
auto parseLayerName = [&](StringRef name) -> Attribute {
58085808
// Parse the layer name into a SymbolRefAttr.
58095809
auto [head, rest] = name.split(".");
58105810
SmallVector<FlatSymbolRefAttr> nestedRefs;
@@ -5816,19 +5816,31 @@ ParseResult FIRCircuitParser::parseCircuit(
58165816
return SymbolRefAttr::get(getContext(), head, nestedRefs);
58175817
};
58185818

5819-
auto parseLayers = [&](const auto &layers) {
5820-
SmallVector<Attribute> layersAttr;
5821-
for (const auto &layer : layers)
5822-
layersAttr.push_back(parseLayerName(layer));
5823-
if (layersAttr.empty())
5819+
auto getArrayAttr = [&](ArrayRef<std::string> strArray, auto getAttr) {
5820+
SmallVector<Attribute> attrArray;
5821+
auto *context = getContext();
5822+
for (const auto &str : strArray)
5823+
attrArray.push_back(getAttr(str));
5824+
if (attrArray.empty())
58245825
return ArrayAttr();
5825-
return ArrayAttr::get(getContext(), layersAttr);
5826+
return ArrayAttr::get(context, attrArray);
58265827
};
58275828

5828-
if (auto enableLayers = parseLayers(getConstants().options.enableLayers))
5829+
if (auto enableLayers =
5830+
getArrayAttr(getConstants().options.enableLayers, parseLayerName))
58295831
circuit.setEnableLayersAttr(enableLayers);
5830-
if (auto disableLayers = parseLayers(getConstants().options.disableLayers))
5832+
if (auto disableLayers =
5833+
getArrayAttr(getConstants().options.disableLayers, parseLayerName))
58315834
circuit.setDisableLayersAttr(disableLayers);
5835+
5836+
auto getStrAttr = [&](StringRef str) -> Attribute {
5837+
return StringAttr::get(getContext(), str);
5838+
};
5839+
5840+
if (auto selectInstChoice =
5841+
getArrayAttr(getConstants().options.selectInstanceChoice, getStrAttr))
5842+
circuit.setSelectInstChoiceAttr(selectInstChoice);
5843+
58325844
circuit.setDefaultLayerSpecialization(
58335845
getConstants().options.defaultLayerSpecialization);
58345846

test/firtool/instchoice.fir

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
; RUN: firtool %s --parse-only | FileCheck %s
1+
; RUN: firtool %s --parse-only --select-instance-choice=Platform=ASIC | FileCheck %s
22

33
FIRRTL version 4.1.0
4+
; CHECK: firrtl.circuit "Foo" attributes {select_inst_choice = ["Platform=ASIC"]} {
45
circuit Foo:
56
; CHECK: firrtl.option @Platform
67
option Platform:
@@ -21,7 +22,7 @@ circuit Foo:
2122
public module Foo:
2223
input clock: Clock
2324

24-
; CHECK: %inst_clock = firrtl.instance_choice inst interesting_name @DefaultTarget
25+
; CHECK: %inst_clock = firrtl.instance_choice inst interesting_name @DefaultTarget
2526
; CHECK-SAME: alternatives @Platform {
2627
; CHECK-SAME: @FPGA -> @FPGATarget,
2728
; CHECK-SAME: @ASIC -> @ASICTarget

tools/firtool/firtool.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,13 @@ static llvm::cl::opt<LayerSpecializationOpt> defaultLayerSpecialization{
275275
"Layers are enabled")),
276276
cl::init(LayerSpecializationOpt::None), cl::cat(mainCategory)};
277277

278+
/// Specify the select option for specializing instance choice. Currently
279+
/// firtool does not support partially specified instance choice.
280+
static cl::list<std::string> selectInstanceChoice(
281+
"select-instance-choice",
282+
cl::desc("Options to specialize instance choice, in option=case format"),
283+
cl::MiscFlags::CommaSeparated, cl::cat(mainCategory));
284+
278285
/// Check output stream before writing bytecode to it.
279286
/// Warn and return true if output is known to be displayed.
280287
static bool checkBytecodeOutputToConsole(raw_ostream &os) {
@@ -370,6 +377,7 @@ static LogicalResult processBuffer(
370377
options.scalarizeExtModules = scalarizeExtModules;
371378
options.enableLayers = enableLayers;
372379
options.disableLayers = disableLayers;
380+
options.selectInstanceChoice = selectInstanceChoice;
373381

374382
switch (defaultLayerSpecialization) {
375383
case LayerSpecializationOpt::None:

0 commit comments

Comments
 (0)