12#include "mlir/IR/Builders.h"
13#include "mlir/IR/DialectImplementation.h"
14#include "llvm/ADT/TypeSwitch.h"
15#include "llvm/Support/Format.h"
39 return (
value.getBitWidth() == key.getBitWidth() &&
value == key);
43 return llvm::hash_value(key);
58APInt BitVectorAttr::getValue()
const {
return getImpl()->value; }
60LogicalResult BitVectorAttr::verify(
61 function_ref<InFlightDiagnostic()> emitError,
63 if (value.getBitWidth() < 1)
64 return emitError() <<
"bit-width must be at least 1, but got "
65 << value.getBitWidth();
69std::string BitVectorAttr::getValueAsString(
bool prefix)
const {
70 unsigned width = getValue().getBitWidth();
71 SmallVector<char> toPrint;
72 StringRef pref = prefix ?
"#" :
"";
74 getValue().toString(toPrint, 16,
false,
false,
false);
77 SmallVector<char> leadingZeros(width / 4 - toPrint.size(),
'0');
78 return (pref +
"x" + Twine(leadingZeros) + toPrint).str();
81 getValue().toString(toPrint, 2,
false,
false,
false);
83 SmallVector<char> leadingZeros(width - toPrint.size(),
'0');
84 return (pref +
"b" + Twine(leadingZeros) + toPrint).str();
88static FailureOr<APInt>
92 return emitError() <<
"expected '#'";
95 return emitError() <<
"expected at least one digit";
98 return APInt(value.size() - 2, std::string(value.begin() + 2, value.end()),
102 return APInt((value.size() - 2) * 4,
103 std::string(value.begin() + 2, value.end()), 16);
105 return emitError() <<
"expected either 'b' or 'x'";
108BitVectorAttr BitVectorAttr::get(MLIRContext *context, StringRef value) {
111 assert(succeeded(maybeValue) &&
"string must have SMT-LIB format");
112 return Base::get(context, *maybeValue);
116BitVectorAttr::getChecked(function_ref<InFlightDiagnostic()> emitError,
117 MLIRContext *context, StringRef value) {
119 if (failed(maybeValue))
122 return Base::getChecked(emitError, context, *maybeValue);
125BitVectorAttr BitVectorAttr::get(MLIRContext *context, uint64_t value,
127 return Base::get(context, APInt(width, value));
131BitVectorAttr::getChecked(function_ref<InFlightDiagnostic()> emitError,
132 MLIRContext *context, uint64_t value,
134 if (width < 64 && value >= (UINT64_C(1) << width)) {
135 emitError() <<
"value does not fit in a bit-vector of desired width";
138 return Base::getChecked(emitError, context, APInt(width, value));
141Attribute BitVectorAttr::parse(AsmParser &odsParser, Type odsType) {
142 llvm::SMLoc loc = odsParser.getCurrentLocation();
145 if (odsParser.parseLess() || odsParser.parseInteger(val) ||
146 odsParser.parseGreater())
150 if (!odsType || !llvm::isa<BitVectorType>(odsType)) {
151 odsParser.emitError(loc) <<
"explicit bit-vector type required";
155 unsigned width = llvm::cast<BitVectorType>(odsType).getWidth();
157 if (width > val.getBitWidth()) {
161 val = val.sext(width);
162 }
else if (width < val.getBitWidth()) {
165 unsigned neededBits =
166 val.isNegative() ? val.getSignificantBits() : val.getActiveBits();
167 if (width < neededBits) {
168 odsParser.emitError(loc)
169 <<
"integer value out of range for given bit-vector type " << odsType;
172 val = val.trunc(width);
175 return BitVectorAttr::get(odsParser.getContext(), val);
178void BitVectorAttr::print(AsmPrinter &odsPrinter)
const {
182 odsPrinter <<
"<" << getValue() <<
">";
185Type BitVectorAttr::getType()
const {
186 return BitVectorType::get(getContext(), getValue().
getBitWidth());
193#define GET_ATTRDEF_CLASSES
194#include "circt/Dialect/SMT/SMTAttributes.cpp.inc"
196void SMTDialect::registerAttributes() {
198#define GET_ATTRDEF_LIST
199#include "circt/Dialect/SMT/SMTAttributes.cpp.inc"
assert(baseType &&"element must be base type")
static FailureOr< APInt > parseBitVectorString(function_ref< InFlightDiagnostic()> emitError, StringRef value)
Parse an SMT-LIB formatted bit-vector string.
int64_t getBitWidth(mlir::Type type)
Return the hardware bit width of a type.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
static llvm::hash_code hashKey(const KeyTy &key)
bool operator==(const KeyTy &key) const
BitVectorAttrStorage(APInt value)
static BitVectorAttrStorage * construct(mlir::AttributeStorageAllocator &allocator, KeyTy &&key)