21#include <llvm/ADT/TypeSwitch.h>
36 inline ResultType
match(Type type) {
37 return llvm::TypeSwitch<Type, ResultType>(type)
38 .template Case<IndexType>([
this](
auto t) {
39 return static_cast<Derived *
>(
this)->caseIndex(t);
41 .
template Case<FeltType>([
this](
auto t) {
42 return static_cast<Derived *
>(
this)->caseFelt(t);
44 .
template Case<StringType>([
this](
auto t) {
45 return static_cast<Derived *
>(
this)->caseString(t);
47 .
template Case<TypeVarType>([
this](
auto t) {
48 return static_cast<Derived *
>(
this)->caseTypeVar(t);
50 .
template Case<ArrayType>([
this](
auto t) {
51 return static_cast<Derived *
>(
this)->caseArray(t);
53 .
template Case<StructType>([
this](
auto t) {
54 return static_cast<Derived *
>(
this)->caseStruct(t);
55 }).Default([
this](Type t) {
56 if (t.isSignlessInteger(1)) {
59 return static_cast<Derived *
>(
this)->caseInvalid(t);
65void BuildShortTypeString::appendSymName(StringRef str) {
73void BuildShortTypeString::appendSymRef(SymbolRefAttr sa) {
74 appendSymName(sa.getRootReference().getValue());
75 for (FlatSymbolRefAttr nestedRef : sa.getNestedReferences()) {
77 appendSymName(nestedRef.getValue());
82 size_t position = ret.size();
85 struct Impl : LLZKTypeSwitch<Impl, void> {
86 BuildShortTypeString &outer;
87 Impl(BuildShortTypeString &outerRef) : outer(outerRef) {}
89 void caseInvalid(Type) { outer.ss <<
"!INVALID"; }
90 void caseBool(IntegerType) { outer.ss <<
'b'; }
91 void caseIndex(IndexType) { outer.ss <<
'i'; }
92 void caseFelt(FeltType) { outer.ss <<
'f'; }
93 void caseString(StringType) { outer.ss <<
's'; }
94 void caseTypeVar(TypeVarType t) {
96 outer.appendSymName(llvm::cast<TypeVarType>(t).getRefName());
99 void caseArray(ArrayType t) {
101 outer.append(t.getElementType());
103 outer.append(t.getDimensionSizes());
106 void caseStruct(StructType t) {
108 outer.appendSymRef(t.getNameRef());
109 if (ArrayAttr params = t.getParams()) {
111 outer.append(params.getValue());
116 Impl(*this).match(type);
119 ret.find(PLACEHOLDER, position) == std::string::npos &&
120 "formatting a Type should not produce the 'PLACEHOLDER' char"
132 size_t position = ret.size();
136 if (
auto ia = llvm::dyn_cast<IntegerAttr>(a)) {
137 Type ty = ia.getType();
138 bool isUnsigned = ty.isUnsignedInteger() || ty.isSignlessInteger(1);
139 ia.getValue().print(ss, !isUnsigned);
140 }
else if (
auto sra = llvm::dyn_cast<SymbolRefAttr>(a)) {
142 }
else if (
auto ta = llvm::dyn_cast<TypeAttr>(a)) {
143 append(ta.getValue());
144 }
else if (
auto ama = llvm::dyn_cast<AffineMapAttr>(a)) {
147 filtered_raw_ostream fs(ss, [](
char c) {
return c ==
' '; });
148 ama.getValue().print(fs);
151 }
else if (
auto aa = llvm::dyn_cast<ArrayAttr>(a)) {
152 append(aa.getValue());
158 ret.find(PLACEHOLDER, position) == std::string::npos &&
159 "formatting a non-null Attribute should not produce the 'PLACEHOLDER' char"
165 llvm::interleave(attrs, ss, [
this](Attribute a) { append(a); },
"_");
170 BuildShortTypeString bldr;
172 bldr.ret.reserve(base.size() + attrs.size());
175 auto END = attrs.end();
176 auto IT = attrs.begin();
179 for (
size_t pos; (pos = base.find(PLACEHOLDER, start)) != std::string::npos; start = pos + 1) {
181 bldr.ret.append(base, start, pos - start);
183 assert(IT != END &&
"must have an Attribute for every 'PLACEHOLDER' char");
187 bldr.ret.append(base, start, base.size() - start);
193 bldr.append(ArrayRef(IT, END));
201template <
typename... Types>
class TypeList {
204 template <
typename StreamType>
struct Appender {
207 template <
typename Ty>
static inline void append(StreamType &stream) {
208 stream <<
'\'' << Ty::name <<
'\'';
212 template <
typename First,
typename Second,
typename... Rest>
213 static void append(StreamType &stream) {
214 append<First>(stream);
216 append<Second, Rest...>(stream);
220 static inline void append(StreamType &stream) {
222 append<Types...>(stream);
229 template <
typename T>
static inline bool matches(
const T &value) {
230 return llvm::isa_and_present<Types...>(value);
233 static void reportInvalid(
EmitErrorFn emitError,
const Twine &foundName,
const char *aspect) {
234 InFlightDiagnosticWrapper diag = emitError().append(aspect,
" must be one of ");
235 Appender<InFlightDiagnosticWrapper>::append(diag);
236 diag.append(
" but found '", foundName,
'\'').report();
239 static inline void reportInvalid(
EmitErrorFn emitError, Attribute found,
const char *aspect) {
241 reportInvalid(emitError, found ? found.getAbstractAttribute().getName() :
"nullptr", aspect);
246 static inline std::string
getNames() {
253template <
class... Ts>
struct make_unique {
254 using type = TypeList<Ts...>;
257template <
class... Ts>
struct make_unique<TypeList<>, Ts...> : make_unique<Ts...> {};
259template <
class U,
class... Us,
class... Ts>
260struct make_unique<TypeList<U, Us...>, Ts...>
261 : std::conditional_t<
262 (std::is_same_v<U, Us> || ...) || (std::is_same_v<U, Ts> || ...),
263 make_unique<TypeList<Us...>, Ts...>, make_unique<TypeList<Us...>, Ts..., U>> {};
265template <
class... Ts>
using TypeListUnion =
typename make_unique<Ts...>::type;
271using ArrayDimensionTypes = TypeList<IntegerAttr, SymbolRefAttr, AffineMapAttr>;
278using StructParamTypes = TypeList<IntegerAttr, SymbolRefAttr, TypeAttr, AffineMapAttr>;
281 struct ColumnCheckData {
282 SymbolTableCollection *symbolTable =
nullptr;
283 Operation *op =
nullptr;
286 bool no_felt : 1 =
false;
287 bool no_string : 1 =
false;
288 bool no_non_signal_struct : 1 =
false;
289 bool no_signal_struct : 1 =
false;
290 bool no_array : 1 =
false;
291 bool no_var : 1 =
false;
292 bool no_int : 1 =
false;
293 bool no_struct_params : 1 =
false;
294 bool must_be_column : 1 =
false;
296 ColumnCheckData columnCheck;
301 bool validColumns(StructType s) {
302 if (!must_be_column) {
305 assert(columnCheck.symbolTable);
306 assert(columnCheck.op);
307 return succeeded(s.hasColumns(*columnCheck.symbolTable, columnCheck.op));
311 constexpr AllowedTypes &noFelt() {
316 constexpr AllowedTypes &noString() {
321 constexpr AllowedTypes &noStruct() {
322 no_non_signal_struct =
true;
323 no_signal_struct =
true;
327 constexpr AllowedTypes &noStructExceptSignal() {
328 no_non_signal_struct =
true;
329 no_signal_struct =
false;
333 constexpr AllowedTypes &noArray() {
338 constexpr AllowedTypes &noVar() {
343 constexpr AllowedTypes &noInt() {
348 constexpr AllowedTypes &noStructParams(
bool noStructParams =
true) {
349 no_struct_params = noStructParams;
353 constexpr AllowedTypes &onlyInt() {
355 return noFelt().noString().noStruct().noArray().noVar();
358 constexpr AllowedTypes &mustBeColumn(SymbolTableCollection &symbolTable, Operation *op) {
359 must_be_column =
true;
360 columnCheck.symbolTable = &symbolTable;
366 bool isValidTypeImpl(Type type);
368 bool areValidArrayDimSizes(ArrayRef<Attribute> dimensionSizes,
EmitErrorFn emitError =
nullptr) {
370 if (dimensionSizes.empty()) {
372 emitError().append(
"array must have at least one dimension").report();
379 for (Attribute a : dimensionSizes) {
380 if (!ArrayDimensionTypes::matches(a)) {
381 ArrayDimensionTypes::reportInvalid(emitError, a,
"Array dimension");
383 }
else if (no_var && !llvm::isa_and_present<IntegerAttr>(a)) {
384 TypeList<IntegerAttr>::reportInvalid(emitError, a,
"Concrete array dimension");
395 bool isValidArrayElemTypeImpl(Type type) {
397 return !llvm::isa<ArrayType>(type) && isValidTypeImpl(type);
400 bool isValidArrayTypeImpl(
401 Type elementType, ArrayRef<Attribute> dimensionSizes,
EmitErrorFn emitError =
nullptr
403 if (!areValidArrayDimSizes(dimensionSizes, emitError)) {
408 if (!isValidArrayElemTypeImpl(elementType)) {
416 elementType.getAbstractType().getName(),
'\''
426 bool isValidArrayTypeImpl(Type type) {
427 if (ArrayType arrTy = llvm::dyn_cast<ArrayType>(type)) {
428 return isValidArrayTypeImpl(arrTy.getElementType(), arrTy.getDimensionSizes());
435 bool areValidStructTypeParams(ArrayAttr params,
EmitErrorFn emitError =
nullptr) {
439 if (no_struct_params) {
443 for (Attribute p : params) {
444 if (!StructParamTypes::matches(p)) {
445 StructParamTypes::reportInvalid(emitError, p,
"Struct parameter");
447 }
else if (TypeAttr tyAttr = llvm::dyn_cast<TypeAttr>(p)) {
448 if (!isValidTypeImpl(tyAttr.getValue())) {
450 emitError().append(
"expected a valid LLZK type but found ", tyAttr.getValue()).report();
454 }
else if (no_var && !llvm::isa<IntegerAttr>(p)) {
455 TypeList<IntegerAttr>::reportInvalid(emitError, p,
"Concrete struct parameter");
468bool AllowedTypes::isValidTypeImpl(Type type) {
470 !(no_int && no_felt && no_string && no_var && no_non_signal_struct && no_signal_struct &&
472 "All types have been deactivated"
474 struct Impl : LLZKTypeSwitch<Impl, bool> {
476 Impl(AllowedTypes &outerRef) : outer(outerRef) {}
478 bool caseBool(IntegerType t) {
return !outer.no_int && t.isSignlessInteger(1); }
479 bool caseIndex(IndexType) {
return !outer.no_int; }
480 bool caseFelt(FeltType) {
return !outer.no_felt; }
481 bool caseString(StringType) {
return !outer.no_string; }
482 bool caseTypeVar(TypeVarType) {
return !outer.no_var; }
483 bool caseArray(ArrayType t) {
484 return !outer.no_array &&
485 outer.isValidArrayTypeImpl(t.getElementType(), t.getDimensionSizes());
487 bool caseStruct(StructType t) {
489 if ((outer.no_signal_struct && outer.no_non_signal_struct) || !outer.validColumns(t)) {
493 (!outer.no_non_signal_struct && outer.areValidStructTypeParams(t.getParams()));
495 bool caseInvalid(Type _) {
return false; }
497 return Impl(*this).match(type);
502bool isValidType(Type type) {
return AllowedTypes().isValidTypeImpl(type); }
505 return AllowedTypes().noString().noInt().mustBeColumn(symbolTable, op).isValidTypeImpl(type);
511 return AllowedTypes().noString().noStructExceptSignal().isValidTypeImpl(type);
516 return AllowedTypes().noString().noStruct().noArray().isValidTypeImpl(type);
524 return AllowedTypes().noVar().noStructParams(!allowStructParams).isValidTypeImpl(type);
528 if (
auto structParamTy = llvm::dyn_cast<StructType>(type)) {
542 bool encountered =
false;
543 type.walk([&](AffineMapAttr a) {
545 return WalkResult::interrupt();
554 uint64_t caseBool(IntegerType) {
return 1; }
555 uint64_t caseIndex(IndexType) {
return 1; }
556 uint64_t caseFelt(
FeltType) {
return 1; }
558 int64_t n = t.getNumElements();
560 return static_cast<uint64_t
>(n);
566 llvm_unreachable(
"not a valid EmitEq type");
568 uint64_t caseString(
StringType) { llvm_unreachable(
"not a valid EmitEq type"); }
569 uint64_t caseTypeVar(
TypeVarType) { llvm_unreachable(
"tvar has unknown cardinality"); }
570 uint64_t caseInvalid(Type) { llvm_unreachable(
"not a valid LLZK type"); }
572 return Impl().match(type);
585using AffineInstantiations = DenseMap<std::pair<AffineMapAttr, Side>, IntegerAttr>;
588 ArrayRef<StringRef> rhsRevPrefix;
589 UnificationMap *unifications;
590 AffineInstantiations *affineToIntTracker;
593 llvm::function_ref<bool(Type oldTy, Type newTy)> overrideSuccess;
595 UnifierImpl(UnificationMap *unificationMap, ArrayRef<StringRef> rhsReversePrefix = {})
596 : rhsRevPrefix(rhsReversePrefix), unifications(unificationMap), affineToIntTracker(nullptr),
597 overrideSuccess(nullptr) {}
600 const ArrayRef<Attribute> &lhsParams,
const ArrayRef<Attribute> &rhsParams,
601 bool unifyDynamicSize =
false
603 auto pred = [
this, unifyDynamicSize](
auto lhsAttr,
auto rhsAttr) {
604 return paramAttrUnify(lhsAttr, rhsAttr, unifyDynamicSize);
606 return (lhsParams.size() == rhsParams.size()) &&
607 std::equal(lhsParams.begin(), lhsParams.end(), rhsParams.begin(), pred);
610 UnifierImpl &trackAffineToInt(AffineInstantiations *tracker) {
611 this->affineToIntTracker = tracker;
615 UnifierImpl &withOverrides(llvm::function_ref<
bool(Type oldTy, Type newTy)> overrides) {
616 this->overrideSuccess = overrides;
623 const ArrayAttr &lhsParams,
const ArrayAttr &rhsParams,
bool unifyDynamicSize =
false
625 if (lhsParams && rhsParams) {
626 return typeParamsUnify(lhsParams.getValue(), rhsParams.getValue(), unifyDynamicSize);
629 return !lhsParams && !rhsParams;
634 if (!
typesUnify(lhs.getElementType(), rhs.getElementType())) {
639 lhs.getDimensionSizes(), rhs.getDimensionSizes(),
true
645 SmallVector<StringRef> rhsNames =
getNames(rhs.getNameRef());
646 rhsNames.insert(rhsNames.begin(), rhsRevPrefix.rbegin(), rhsRevPrefix.rend());
647 if (rhsNames !=
getNames(lhs.getNameRef())) {
658 if (overrideSuccess && overrideSuccess(lhs, rhs)) {
662 if (TypeVarType lhsTvar = llvm::dyn_cast<TypeVarType>(lhs)) {
663 track(Side::LHS, lhsTvar.getNameRef(), rhs);
666 if (TypeVarType rhsTvar = llvm::dyn_cast<TypeVarType>(rhs)) {
667 track(Side::RHS, rhsTvar.getNameRef(), lhs);
670 if (llvm::isa<StructType>(lhs) && llvm::isa<StructType>(rhs)) {
671 return structTypesUnify(llvm::cast<StructType>(lhs), llvm::cast<StructType>(rhs));
673 if (llvm::isa<ArrayType>(lhs) && llvm::isa<ArrayType>(rhs)) {
674 return arrayTypesUnify(llvm::cast<ArrayType>(lhs), llvm::cast<ArrayType>(rhs));
680 template <
typename Tracker,
typename Key,
typename Val>
681 inline void track(Tracker &tracker, Side side, Key keyHead, Val val) {
682 auto key = std::make_pair(keyHead, side);
683 auto it = tracker.find(key);
684 if (it == tracker.end()) {
685 tracker.try_emplace(key, val);
686 }
else if (it->getSecond() != val) {
687 it->second =
nullptr;
691 void track(Side side, SymbolRefAttr symRef, Type ty) {
694 if (TypeVarType tvar = dyn_cast<TypeVarType>(ty)) {
696 attr = tvar.getNameRef();
699 attr = TypeAttr::get(ty);
703 track(*unifications, side, symRef, attr);
707 void track(Side side, SymbolRefAttr symRef, Attribute attr) {
710 if (TypeAttr tyAttr = dyn_cast<TypeAttr>(attr)) {
711 if (TypeVarType tvar = dyn_cast<TypeVarType>(tyAttr.getValue())) {
712 attr = tvar.getNameRef();
721 if (SymbolRefAttr otherSymAttr = dyn_cast<SymbolRefAttr>(attr)) {
722 track(*unifications,
reverse(side), otherSymAttr, symRef);
724 track(*unifications, side, symRef, attr);
728 void track(Side side, AffineMapAttr affineAttr, IntegerAttr intAttr) {
729 if (affineToIntTracker) {
733 track(*affineToIntTracker, side, affineAttr, intAttr);
737 bool paramAttrUnify(Attribute lhsAttr, Attribute rhsAttr,
bool unifyDynamicSize =
false) {
741 if (lhsAttr == rhsAttr) {
746 if (AffineMapAttr lhsAffine = llvm::dyn_cast<AffineMapAttr>(lhsAttr)) {
747 if (IntegerAttr rhsInt = llvm::dyn_cast<IntegerAttr>(rhsAttr)) {
749 track(Side::LHS, lhsAffine, rhsInt);
754 if (AffineMapAttr rhsAffine = llvm::dyn_cast<AffineMapAttr>(rhsAttr)) {
755 if (IntegerAttr lhsInt = llvm::dyn_cast<IntegerAttr>(lhsAttr)) {
757 track(Side::RHS, rhsAffine, lhsInt);
764 if (SymbolRefAttr lhsSymRef = llvm::dyn_cast<SymbolRefAttr>(lhsAttr)) {
765 track(Side::LHS, lhsSymRef, rhsAttr);
768 if (SymbolRefAttr rhsSymRef = llvm::dyn_cast<SymbolRefAttr>(rhsAttr)) {
769 track(Side::RHS, rhsSymRef, lhsAttr);
777 if (unifyDynamicSize) {
778 auto dyn_cast_if_dynamic = [](Attribute attr) -> IntegerAttr {
779 if (IntegerAttr intAttr = llvm::dyn_cast<IntegerAttr>(attr)) {
786 auto is_const_like = [](Attribute attr) {
787 return llvm::isa_and_present<IntegerAttr, SymbolRefAttr, AffineMapAttr>(attr);
789 if (IntegerAttr lhsIntAttr = dyn_cast_if_dynamic(lhsAttr)) {
790 if (is_const_like(rhsAttr)) {
794 if (IntegerAttr rhsIntAttr = dyn_cast_if_dynamic(rhsAttr)) {
795 if (is_const_like(lhsAttr)) {
801 if (TypeAttr lhsTy = llvm::dyn_cast<TypeAttr>(lhsAttr)) {
802 if (TypeAttr rhsTy = llvm::dyn_cast<TypeAttr>(rhsAttr)) {
803 return typesUnify(lhsTy.getValue(), rhsTy.getValue());
814 const ArrayRef<Attribute> &lhsParams,
const ArrayRef<Attribute> &rhsParams,
817 return UnifierImpl(unifications).typeParamsUnify(lhsParams, rhsParams);
823 const ArrayAttr &lhsParams,
const ArrayAttr &rhsParams,
UnificationMap *unifications
825 return UnifierImpl(unifications).typeParamsUnify(lhsParams, rhsParams);
831 return UnifierImpl(unifications, rhsReversePrefix).arrayTypesUnify(lhs, rhs);
838 return UnifierImpl(unifications, rhsReversePrefix).structTypesUnify(lhs, rhs);
842 Type lhs, Type rhs, ArrayRef<StringRef> rhsReversePrefix,
UnificationMap *unifications
844 return UnifierImpl(unifications, rhsReversePrefix).typesUnify(lhs, rhs);
848 Type oldTy, Type newTy, llvm::function_ref<
bool(Type oldTy, Type newTy)> knownOldToNew
851 AffineInstantiations affineInstantiations;
853 if (!UnifierImpl(&unifications)
854 .trackAffineToInt(&affineInstantiations)
855 .withOverrides(knownOldToNew)
865 auto entryIsRHS = [](
const auto &entry) {
return entry.first.second ==
Side::RHS; };
866 return !llvm::any_of(unifications, entryIsRHS) && !llvm::any_of(affineInstantiations, entryIsRHS);
870 if (llvm::isa<IndexType>(attr.getType())) {
875 APInt value = attr.getValue();
876 auto compare = value.getBitWidth() <=> IndexType::kInternalStorageBitWidth;
878 value = value.zext(IndexType::kInternalStorageBitWidth);
879 }
else if (compare > 0) {
880 return emitError().append(
"value is too large for `index` type: ",
debug::toStringOne(value));
882 return IntegerAttr::get(IndexType::get(attr.getContext()), value);
886 if (IntegerAttr intAttr = llvm::dyn_cast_if_present<IntegerAttr>(attr)) {
892FailureOr<SmallVector<Attribute>>
894 SmallVector<Attribute> result;
895 for (Attribute attr : attrList) {
897 if (failed(forced)) {
900 result.push_back(*forced);
906 if (IntegerAttr intAttr = llvm::dyn_cast_if_present<IntegerAttr>(in)) {
907 Type attrTy = intAttr.getType();
908 if (!AllowedTypes().onlyInt().isValidTypeImpl(attrTy)) {
911 .append(
"IntegerAttr must have type 'index' or 'i1' but found '", attrTy,
'\'')
921 if (AffineMapAttr affineAttr = llvm::dyn_cast_if_present<AffineMapAttr>(in)) {
922 AffineMap map = affineAttr.getValue();
923 if (map.getNumResults() != 1) {
927 "AffineMapAttr must yield a single result, but found ", map.getNumResults(),
939 return success(AllowedTypes().areValidStructTypeParams(params, emitError));
943 return success(AllowedTypes().areValidArrayDimSizes(dimensionSizes, emitError));
948 return success(AllowedTypes().isValidArrayTypeImpl(elementType, dimensionSizes, emitError));
953 using TypeVarAttrs = TypeList<SymbolRefAttr>;
954 if (!TypeListUnion<ArrayDimensionTypes, StructParamTypes, TypeVarAttrs>::matches(attr)) {
955 llvm::report_fatal_error(
956 "Legal type parameters are inconsistent. Encountered " +
957 attr.getAbstractAttribute().getName()
965 size_t numArrDims = dimsFromArr.size();
967 size_t numSubArrDims = dimsFromSubArr.size();
969 if (numArrDims < numSubArrDims) {
970 return emitError().append(
971 "subarray type ", subArrayType,
" has more dimensions than array type ", arrayType
975 size_t toDrop = numArrDims - numSubArrDims;
976 ArrayRef<Attribute> dimsFromArrReduced = dimsFromArr.drop_front(toDrop);
981 llvm::raw_string_ostream ss(message);
983 ss <<
"cannot unify array dimensions [";
984 llvm::interleaveComma(dimsFromArrReduced, ss, appendOne);
986 llvm::interleaveComma(dimsFromSubArr, ss, appendOne);
988 return emitError().append(message);
993 return emitError().append(
994 "incorrect array element type; expected: ", arrayType.
getElementType(),
1004 if (
auto subArrayType = llvm::dyn_cast<ArrayType>(subArrayOrElemType)) {
1008 return emitError().append(
1009 "incorrect array element type; expected: ", arrayType.
getElementType(),
1010 ", found: ", subArrayOrElemType
Note: If any symbol refs in an input Type/Attribute use any of the special characters that this class...
static std::string from(mlir::Type type)
Return a brief string representation of the given LLZK type.
::mlir::Type getElementType() const
::llvm::ArrayRef<::mlir::Attribute > getDimensionSizes() const
static constexpr ::llvm::StringLiteral name
::mlir::SymbolRefAttr getNameRef() const
std::string toStringOne(const T &value)
LogicalResult verifyAffineMapAttrType(EmitErrorFn emitError, Attribute in)
void assertValidAttrForParamOfType(Attribute attr)
LogicalResult verifySubArrayType(EmitErrorFn emitError, ArrayType arrayType, ArrayType subArrayType)
Determine if the subArrayType is a valid subarray of arrayType.
FailureOr< Attribute > forceIntAttrType(Attribute attr, EmitErrorFn emitError)
uint64_t computeEmitEqCardinality(Type type)
bool isValidArrayType(Type type)
LogicalResult verifyIntAttrType(EmitErrorFn emitError, Attribute in)
bool isConcreteType(Type type, bool allowStructParams)
bool isValidArrayElemType(Type type)
llvm::SmallVector< StringRef > getNames(SymbolRefAttr ref)
bool isValidGlobalType(Type type)
FailureOr< IntegerAttr > forceIntType(IntegerAttr attr, EmitErrorFn emitError)
bool structTypesUnify(StructType lhs, StructType rhs, ArrayRef< StringRef > rhsReversePrefix, UnificationMap *unifications)
LogicalResult verifyArrayType(EmitErrorFn emitError, Type elementType, ArrayRef< Attribute > dimensionSizes)
LogicalResult verifySubArrayOrElementType(EmitErrorFn emitError, ArrayType arrayType, Type subArrayOrElemType)
bool isValidColumnType(Type type, SymbolTableCollection &symbolTable, Operation *op)
mlir::DenseMap< std::pair< mlir::SymbolRefAttr, Side >, mlir::Attribute > UnificationMap
Optional result from type unifications.
llvm::function_ref< InFlightDiagnosticWrapper()> EmitErrorFn
Callback to produce an error diagnostic.
FailureOr< SmallVector< Attribute > > forceIntAttrTypes(ArrayRef< Attribute > attrList, EmitErrorFn emitError)
bool isNullOrEmpty(mlir::ArrayAttr a)
bool isValidEmitEqType(Type type)
bool isValidType(Type type)
bool arrayTypesUnify(ArrayType lhs, ArrayType rhs, ArrayRef< StringRef > rhsReversePrefix, UnificationMap *unifications)
bool isDynamic(IntegerAttr intAttr)
bool isSignalType(Type type)
int64_t fromAPInt(const llvm::APInt &i)
constexpr char COMPONENT_NAME_SIGNAL[]
Symbol name for the struct/component representing a signal.
bool typesUnify(Type lhs, Type rhs, ArrayRef< StringRef > rhsReversePrefix, UnificationMap *unifications)
bool typeParamsUnify(const ArrayRef< Attribute > &lhsParams, const ArrayRef< Attribute > &rhsParams, UnificationMap *unifications)
bool isMoreConcreteUnification(Type oldTy, Type newTy, llvm::function_ref< bool(Type oldTy, Type newTy)> knownOldToNew)
LogicalResult verifyStructTypeParams(EmitErrorFn emitError, ArrayAttr params)
void appendWithoutType(mlir::raw_ostream &os, mlir::Attribute a)
std::string buildStringViaCallback(Func &&appendFn, Args &&...args)
Generate a string by calling the given appendFn with an llvm::raw_ostream & as the first argument fol...
bool hasAffineMapAttr(Type type)
mlir::LogicalResult checkValidType(EmitErrorFn emitError, mlir::Type type)
bool isValidConstReadType(Type type)
LogicalResult verifyArrayDimSizes(EmitErrorFn emitError, ArrayRef< Attribute > dimensionSizes)
Template pattern for performing some operation by cases based on a given LLZK type.
ResultType match(Type type)