CIRCT  19.0.0git
LoweringOptions.cpp
Go to the documentation of this file.
1 //===- LoweringOptions.cpp - CIRCT Lowering Options -----------------------===//
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 // Options for controlling the lowering process. Contains command line
10 // option definitions and support.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "mlir/IR/BuiltinOps.h"
16 
17 using namespace circt;
18 using namespace mlir;
19 
20 //===----------------------------------------------------------------------===//
21 // LoweringOptions
22 //===----------------------------------------------------------------------===//
23 
24 LoweringOptions::LoweringOptions(StringRef options, ErrorHandlerT errorHandler)
25  : LoweringOptions() {
26  parse(options, errorHandler);
27 }
28 
29 LoweringOptions::LoweringOptions(mlir::ModuleOp module) : LoweringOptions() {
30  parseFromAttribute(module);
31 }
32 
33 static std::optional<LoweringOptions::LocationInfoStyle>
34 parseLocationInfoStyle(StringRef option) {
35  return llvm::StringSwitch<std::optional<LoweringOptions::LocationInfoStyle>>(
36  option)
37  .Case("plain", LoweringOptions::Plain)
38  .Case("wrapInAtSquareBracket", LoweringOptions::WrapInAtSquareBracket)
39  .Case("none", LoweringOptions::None)
40  .Default(std::nullopt);
41 }
42 
43 static std::optional<LoweringOptions::WireSpillingHeuristic>
44 parseWireSpillingHeuristic(StringRef option) {
45  return llvm::StringSwitch<
46  std::optional<LoweringOptions::WireSpillingHeuristic>>(option)
47  .Case("spillLargeTermsWithNamehints",
49  .Default(std::nullopt);
50 }
51 
52 void LoweringOptions::parse(StringRef text, ErrorHandlerT errorHandler) {
53  while (!text.empty()) {
54  // Remove the first option from the text.
55  auto split = text.split(",");
56  auto option = split.first.trim();
57  text = split.second;
58  if (option == "") {
59  // Empty options are fine.
60  } else if (option == "noAlwaysComb") {
61  noAlwaysComb = true;
62  } else if (option == "exprInEventControl") {
64  } else if (option == "disallowPackedArrays") {
65  disallowPackedArrays = true;
66  } else if (option == "disallowPackedStructAssignments") {
68  } else if (option == "disallowLocalVariables") {
70  } else if (option == "verifLabels") {
71  enforceVerifLabels = true;
72  } else if (option.consume_front("emittedLineLength=")) {
73  if (option.getAsInteger(10, emittedLineLength)) {
74  errorHandler("expected integer source width");
76  }
77  } else if (option == "explicitBitcast") {
78  explicitBitcast = true;
79  } else if (option == "emitReplicatedOpsToHeader") {
81  } else if (option.consume_front("maximumNumberOfTermsPerExpression=")) {
82  if (option.getAsInteger(10, maximumNumberOfTermsPerExpression)) {
83  errorHandler("expected integer source width");
85  }
86  } else if (option.consume_front("locationInfoStyle=")) {
87  if (auto style = parseLocationInfoStyle(option)) {
88  locationInfoStyle = *style;
89  } else {
90  errorHandler("expected 'plain', 'wrapInAtSquareBracket', or 'none'");
91  }
92  } else if (option == "disallowPortDeclSharing") {
94  } else if (option == "printDebugInfo") {
95  printDebugInfo = true;
96  } else if (option == "disallowExpressionInliningInPorts") {
98  } else if (option == "disallowMuxInlining") {
99  disallowMuxInlining = true;
100  } else if (option == "mitigateVivadoArrayIndexConstPropBug") {
102  } else if (option.consume_front("wireSpillingHeuristic=")) {
103  if (auto heuristic = parseWireSpillingHeuristic(option)) {
104  wireSpillingHeuristicSet |= *heuristic;
105  } else {
106  errorHandler("expected ''spillLargeTermsWithNamehints'");
107  }
108  } else if (option.consume_front("wireSpillingNamehintTermLimit=")) {
109  if (option.getAsInteger(10, wireSpillingNamehintTermLimit)) {
110  errorHandler(
111  "expected integer for number of namehint heurstic term limit");
113  }
114  } else if (option == "emitWireInPorts") {
115  emitWireInPorts = true;
116  } else if (option == "emitBindComments") {
117  emitBindComments = true;
118  } else if (option == "omitVersionComment") {
119  omitVersionComment = true;
120  } else if (option == "caseInsensitiveKeywords") {
122  } else if (option == "emitVerilogLocations") {
123  emitVerilogLocations = true;
124  } else {
125  errorHandler(llvm::Twine("unknown style option \'") + option + "\'");
126  // We continue parsing options after a failure.
127  }
128  }
129 }
130 
131 std::string LoweringOptions::toString() const {
132  std::string options = "";
133  // All options should add a trailing comma to simplify the code.
134  if (noAlwaysComb)
135  options += "noAlwaysComb,";
137  options += "exprInEventControl,";
139  options += "disallowPackedArrays,";
141  options += "disallowPackedStructAssignments,";
143  options += "disallowLocalVariables,";
144  if (enforceVerifLabels)
145  options += "verifLabels,";
146  if (explicitBitcast)
147  options += "explicitBitcast,";
149  options += "emitReplicatedOpsToHeader,";
150  if (locationInfoStyle == LocationInfoStyle::WrapInAtSquareBracket)
151  options += "locationInfoStyle=wrapInAtSquareBracket,";
152  if (locationInfoStyle == LocationInfoStyle::None)
153  options += "locationInfoStyle=none,";
155  options += "disallowPortDeclSharing,";
156  if (printDebugInfo)
157  options += "printDebugInfo,";
159  WireSpillingHeuristic::SpillLargeTermsWithNamehints))
160  options += "wireSpillingHeuristic=spillLargeTermsWithNamehints,";
162  options += "disallowExpressionInliningInPorts,";
164  options += "disallowMuxInlining,";
166  options += "mitigateVivadoArrayIndexConstPropBug,";
167 
169  options += "emittedLineLength=" + std::to_string(emittedLineLength) + ',';
171  options += "maximumNumberOfTermsPerExpression=" +
172  std::to_string(maximumNumberOfTermsPerExpression) + ',';
173  if (emitWireInPorts)
174  options += "emitWireInPorts,";
175  if (emitBindComments)
176  options += "emitBindComments,";
177  if (omitVersionComment)
178  options += "omitVersionComment,";
180  options += "caseInsensitiveKeywords,";
182  options += "emitVerilogLocations,";
183 
184  // Remove a trailing comma if present.
185  if (!options.empty()) {
186  assert(options.back() == ',' && "all options should add a trailing comma");
187  options.pop_back();
188  }
189  return options;
190 }
191 
192 StringAttr LoweringOptions::getAttributeFrom(ModuleOp module) {
193  return module->getAttrOfType<StringAttr>("circt.loweringOptions");
194 }
195 
196 void LoweringOptions::setAsAttribute(ModuleOp module) {
197  module->setAttr("circt.loweringOptions",
198  StringAttr::get(module.getContext(), toString()));
199 }
200 
201 void LoweringOptions::parseFromAttribute(ModuleOp module) {
202  if (auto styleAttr = getAttributeFrom(module))
203  parse(styleAttr.getValue(), [&](Twine error) { module.emitError(error); });
204 }
assert(baseType &&"element must be base type")
static std::optional< LoweringOptions::WireSpillingHeuristic > parseWireSpillingHeuristic(StringRef option)
static std::optional< LoweringOptions::LocationInfoStyle > parseLocationInfoStyle(StringRef option)
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
Definition: CalyxOps.cpp:54
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21
Options which control the emission from CIRCT to Verilog.
bool isWireSpillingHeuristicEnabled(WireSpillingHeuristic heurisic) const
bool noAlwaysComb
If true, emits sv.alwayscomb as Verilog always @(*) statements.
bool mitigateVivadoArrayIndexConstPropBug
If true, every expression used as an array index is driven by a wire, and the wire is marked as (* ke...
bool disallowLocalVariables
If true, do not emit SystemVerilog locally scoped "automatic" or logic declarations - emit top level ...
bool omitVersionComment
If true, do not emit a version comment at the top of each verilog file.
bool enforceVerifLabels
If true, verification statements like assert, assume, and cover will always be emitted with a label.
bool disallowExpressionInliningInPorts
If true, every expression passed to an instance port is driven by a wire.
bool printDebugInfo
Print debug info.
llvm::function_ref< void(llvm::Twine)> ErrorHandlerT
Error callback type used to indicate errors parsing the options string.
unsigned maximumNumberOfTermsPerExpression
void setAsAttribute(mlir::ModuleOp module)
Write the verilog emitter options to a module's attributes.
enum circt::LoweringOptions::LocationInfoStyle locationInfoStyle
unsigned wireSpillingNamehintTermLimit
bool disallowPortDeclSharing
If true, every port is declared separately (each includes direction and type (e.g....
bool disallowPackedArrays
If true, eliminate packed arrays for tools that don't support them (e.g.
bool explicitBitcast
Add an explicit bitcast for avoiding bitwidth mismatch LINT errors.
bool disallowMuxInlining
If true, every mux expression is spilled to a wire.
bool disallowPackedStructAssignments
If true, eliminate packed struct assignments in favor of a wire + assignments to the individual field...
void parse(llvm::StringRef options, ErrorHandlerT callback)
Read in options from a string, overriding only the set options in the string.
static mlir::StringAttr getAttributeFrom(mlir::ModuleOp module)
Return the value of the circt.loweringOptions in the specified module if present, or a null attribute...
bool caseInsensitiveKeywords
If true, then unique names that collide with keywords case insensitively.
void parseFromAttribute(mlir::ModuleOp module)
Load any emitter options from the module.
bool emitWireInPorts
If true, emit wire in port lists rather than nothing.
bool emitReplicatedOpsToHeader
If true, replicated ops are emitted to a header file.
std::string toString() const
Returns a string representation of the options.
LoweringOptions()=default
Create a LoweringOptions with the default values.
bool allowExprInEventControl
If true, expressions are allowed in the sensitivity list of always statements, otherwise they are for...
bool emitVerilogLocations
If true, then update the the mlir to include output verilog locations.
bool emitBindComments
If true, emit a comment wherever an instance wasn't printed, because it's emitted elsewhere as a bind...