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();
84 struct Impl : LLZKTypeSwitch<Impl, void> {
85 BuildShortTypeString &outer;
86 Impl(BuildShortTypeString &outerRef) : outer(outerRef) {}
88 void caseInvalid(Type) { outer.ss <<
"!INVALID"; }
89 void caseBool(IntegerType) { outer.ss <<
'b'; }
90 void caseIndex(IndexType) { outer.ss <<
'i'; }
91 void caseFelt(FeltType) { outer.ss <<
'f'; }
92 void caseString(StringType) { outer.ss <<
's'; }
93 void caseTypeVar(TypeVarType t) {
95 outer.appendSymName(llvm::cast<TypeVarType>(t).getRefName());
98 void caseArray(ArrayType t) {
100 outer.append(t.getElementType());
102 outer.append(t.getDimensionSizes());
105 void caseStruct(StructType t) {
107 outer.appendSymRef(t.getNameRef());
108 if (ArrayAttr params = t.getParams()) {
110 outer.append(params.getValue());
115 Impl(*this).match(type);
118 ret.find(PLACEHOLDER, position) == std::string::npos &&
119 "formatting a Type should not produce the 'PLACEHOLDER' char"
131 size_t position = ret.size();
133 if (
auto ia = llvm::dyn_cast<IntegerAttr>(a)) {
134 Type ty = ia.getType();
135 bool isUnsigned = ty.isUnsignedInteger() || ty.isSignlessInteger(1);
136 ia.getValue().print(ss, !isUnsigned);
137 }
else if (
auto sra = llvm::dyn_cast<SymbolRefAttr>(a)) {
139 }
else if (
auto ta = llvm::dyn_cast<TypeAttr>(a)) {
140 append(ta.getValue());
141 }
else if (
auto ama = llvm::dyn_cast<AffineMapAttr>(a)) {
144 filtered_raw_ostream fs(ss, [](
char c) {
return c ==
' '; });
145 ama.getValue().print(fs);
148 }
else if (
auto aa = llvm::dyn_cast<ArrayAttr>(a)) {
149 append(aa.getValue());
155 ret.find(PLACEHOLDER, position) == std::string::npos &&
156 "formatting a non-null Attribute should not produce the 'PLACEHOLDER' char"
162 llvm::interleave(attrs, ss, [
this](Attribute a) { append(a); },
"_");
167 BuildShortTypeString bldr;
169 bldr.ret.reserve(base.size() + attrs.size());
172 auto END = attrs.end();
173 auto IT = attrs.begin();
176 for (
size_t pos; (pos = base.find(PLACEHOLDER, start)) != std::string::npos; start = pos + 1) {
178 bldr.ret.append(base, start, pos - start);
180 assert(IT != END &&
"must have an Attribute for every 'PLACEHOLDER' char");
184 bldr.ret.append(base, start, base.size() - start);
190 bldr.append(ArrayRef(IT, END));
198template <
typename... Types>
class TypeList {
201 template <
typename StreamType>
struct Appender {
204 template <
typename Ty>
static inline void append(StreamType &stream) {
205 stream <<
'\'' << Ty::name <<
'\'';
209 template <
typename First,
typename Second,
typename... Rest>
210 static void append(StreamType &stream) {
211 append<First>(stream);
213 append<Second, Rest...>(stream);
217 static inline void append(StreamType &stream) {
219 append<Types...>(stream);
226 template <
typename T>
static inline bool matches(
const T &value) {
227 return llvm::isa_and_present<Types...>(value);
230 static void reportInvalid(
EmitErrorFn emitError,
const Twine &foundName,
const char *aspect) {
231 InFlightDiagnosticWrapper diag = emitError().append(aspect,
" must be one of ");
232 Appender<InFlightDiagnosticWrapper>::append(diag);
233 diag.append(
" but found '", foundName,
'\'').report();
236 static inline void reportInvalid(
EmitErrorFn emitError, Attribute found,
const char *aspect) {
238 reportInvalid(emitError, found ? found.getAbstractAttribute().getName() :
"nullptr", aspect);
243 static inline std::string
getNames() {
250template <
class... Ts>
struct make_unique {
251 using type = TypeList<Ts...>;
254template <
class... Ts>
struct make_unique<TypeList<>, Ts...> : make_unique<Ts...> {};
256template <
class U,
class... Us,
class... Ts>
257struct make_unique<TypeList<U, Us...>, Ts...>
258 : std::conditional_t<
259 (std::is_same_v<U, Us> || ...) || (std::is_same_v<U, Ts> || ...),
260 make_unique<TypeList<Us...>, Ts...>, make_unique<TypeList<Us...>, Ts..., U>> {};
262template <
class... Ts>
using TypeListUnion =
typename make_unique<Ts...>::type;
268using ArrayDimensionTypes = TypeList<IntegerAttr, SymbolRefAttr, AffineMapAttr>;
275using StructParamTypes = TypeList<IntegerAttr, SymbolRefAttr, TypeAttr, AffineMapAttr>;
278 struct ColumnCheckData {
279 SymbolTableCollection *symbolTable =
nullptr;
280 Operation *op =
nullptr;
283 bool no_felt : 1 =
false;
284 bool no_string : 1 =
false;
285 bool no_non_signal_struct : 1 =
false;
286 bool no_signal_struct : 1 =
false;
287 bool no_array : 1 =
false;
288 bool no_var : 1 =
false;
289 bool no_int : 1 =
false;
290 bool no_struct_params : 1 =
false;
291 bool must_be_column : 1 =
false;
293 ColumnCheckData columnCheck;
298 bool validColumns(StructType s) {
299 if (!must_be_column) {
302 assert(columnCheck.symbolTable);
303 assert(columnCheck.op);
304 return succeeded(s.hasColumns(*columnCheck.symbolTable, columnCheck.op));
308 constexpr AllowedTypes &noFelt() {
313 constexpr AllowedTypes &noString() {
318 constexpr AllowedTypes &noStruct() {
319 no_non_signal_struct =
true;
320 no_signal_struct =
true;
324 constexpr AllowedTypes &noStructExceptSignal() {
325 no_non_signal_struct =
true;
326 no_signal_struct =
false;
330 constexpr AllowedTypes &noArray() {
335 constexpr AllowedTypes &noVar() {
340 constexpr AllowedTypes &noInt() {
345 constexpr AllowedTypes &noStructParams(
bool noStructParams =
true) {
346 no_struct_params = noStructParams;
350 constexpr AllowedTypes &onlyInt() {
352 return noFelt().noString().noStruct().noArray().noVar();
355 constexpr AllowedTypes &mustBeColumn(SymbolTableCollection &symbolTable, Operation *op) {
356 must_be_column =
true;
357 columnCheck.symbolTable = &symbolTable;
363 bool isValidTypeImpl(Type type);
365 bool areValidArrayDimSizes(ArrayRef<Attribute> dimensionSizes,
EmitErrorFn emitError =
nullptr) {
367 if (dimensionSizes.empty()) {
369 emitError().append(
"array must have at least one dimension").report();
376 for (Attribute a : dimensionSizes) {
377 if (!ArrayDimensionTypes::matches(a)) {
378 ArrayDimensionTypes::reportInvalid(emitError, a,
"Array dimension");
380 }
else if (no_var && !llvm::isa_and_present<IntegerAttr>(a)) {
381 TypeList<IntegerAttr>::reportInvalid(emitError, a,
"Concrete array dimension");
392 bool isValidArrayElemTypeImpl(Type type) {
394 return !llvm::isa<ArrayType>(type) && isValidTypeImpl(type);
397 bool isValidArrayTypeImpl(
398 Type elementType, ArrayRef<Attribute> dimensionSizes,
EmitErrorFn emitError =
nullptr
400 if (!areValidArrayDimSizes(dimensionSizes, emitError)) {
405 if (!isValidArrayElemTypeImpl(elementType)) {
413 elementType.getAbstractType().getName(),
'\''
423 bool isValidArrayTypeImpl(Type type) {
424 if (ArrayType arrTy = llvm::dyn_cast<ArrayType>(type)) {
425 return isValidArrayTypeImpl(arrTy.getElementType(), arrTy.getDimensionSizes());
432 bool areValidStructTypeParams(ArrayAttr params,
EmitErrorFn emitError =
nullptr) {
436 if (no_struct_params) {
440 for (Attribute p : params) {
441 if (!StructParamTypes::matches(p)) {
442 StructParamTypes::reportInvalid(emitError, p,
"Struct parameter");
444 }
else if (TypeAttr tyAttr = llvm::dyn_cast<TypeAttr>(p)) {
445 if (!isValidTypeImpl(tyAttr.getValue())) {
447 emitError().append(
"expected a valid LLZK type but found ", tyAttr.getValue()).report();
451 }
else if (no_var && !llvm::isa<IntegerAttr>(p)) {
452 TypeList<IntegerAttr>::reportInvalid(emitError, p,
"Concrete struct parameter");
465bool AllowedTypes::isValidTypeImpl(Type type) {
467 !(no_int && no_felt && no_string && no_var && no_non_signal_struct && no_signal_struct &&
469 "All types have been deactivated"
471 struct Impl : LLZKTypeSwitch<Impl, bool> {
473 Impl(AllowedTypes &outerRef) : outer(outerRef) {}
475 bool caseBool(IntegerType t) {
return !outer.no_int && t.isSignlessInteger(1); }
476 bool caseIndex(IndexType) {
return !outer.no_int; }
477 bool caseFelt(FeltType) {
return !outer.no_felt; }
478 bool caseString(StringType) {
return !outer.no_string; }
479 bool caseTypeVar(TypeVarType) {
return !outer.no_var; }
480 bool caseArray(ArrayType t) {
481 return !outer.no_array &&
482 outer.isValidArrayTypeImpl(t.getElementType(), t.getDimensionSizes());
484 bool caseStruct(StructType t) {
486 if ((outer.no_signal_struct && outer.no_non_signal_struct) || !outer.validColumns(t)) {
490 (!outer.no_non_signal_struct && outer.areValidStructTypeParams(t.getParams()));
492 bool caseInvalid(Type _) {
return false; }
494 return Impl(*this).match(type);
499bool isValidType(Type type) {
return AllowedTypes().isValidTypeImpl(type); }
502 return AllowedTypes().noString().noInt().mustBeColumn(symbolTable, op).isValidTypeImpl(type);
508 return AllowedTypes().noString().noStructExceptSignal().isValidTypeImpl(type);
513 return AllowedTypes().noString().noStruct().noArray().isValidTypeImpl(type);
521 return AllowedTypes().noVar().noStructParams(!allowStructParams).isValidTypeImpl(type);
525 if (
auto structParamTy = llvm::dyn_cast<StructType>(type)) {
539 bool encountered =
false;
540 type.walk([&](AffineMapAttr a) {
542 return WalkResult::interrupt();
551 uint64_t caseBool(IntegerType) {
return 1; }
552 uint64_t caseIndex(IndexType) {
return 1; }
553 uint64_t caseFelt(
FeltType) {
return 1; }
555 int64_t n = t.getNumElements();
557 return static_cast<uint64_t
>(n);
563 llvm_unreachable(
"not a valid EmitEq type");
565 uint64_t caseString(
StringType) { llvm_unreachable(
"not a valid EmitEq type"); }
566 uint64_t caseTypeVar(
TypeVarType) { llvm_unreachable(
"tvar has unknown cardinality"); }
567 uint64_t caseInvalid(Type) { llvm_unreachable(
"not a valid LLZK type"); }
569 return Impl().match(type);
582using AffineInstantiations = DenseMap<std::pair<AffineMapAttr, Side>, IntegerAttr>;
585 ArrayRef<StringRef> rhsRevPrefix;
586 UnificationMap *unifications;
587 AffineInstantiations *affineToIntTracker;
590 llvm::function_ref<bool(Type oldTy, Type newTy)> overrideSuccess;
592 UnifierImpl(UnificationMap *unificationMap, ArrayRef<StringRef> rhsReversePrefix = {})
593 : rhsRevPrefix(rhsReversePrefix), unifications(unificationMap), affineToIntTracker(nullptr),
594 overrideSuccess(nullptr) {}
597 const ArrayRef<Attribute> &lhsParams,
const ArrayRef<Attribute> &rhsParams,
598 bool unifyDynamicSize =
false
600 auto pred = [
this, unifyDynamicSize](
auto lhsAttr,
auto rhsAttr) {
601 return paramAttrUnify(lhsAttr, rhsAttr, unifyDynamicSize);
603 return (lhsParams.size() == rhsParams.size()) &&
604 std::equal(lhsParams.begin(), lhsParams.end(), rhsParams.begin(), pred);
607 UnifierImpl &trackAffineToInt(AffineInstantiations *tracker) {
608 this->affineToIntTracker = tracker;
612 UnifierImpl &withOverrides(llvm::function_ref<
bool(Type oldTy, Type newTy)> overrides) {
613 this->overrideSuccess = overrides;
620 const ArrayAttr &lhsParams,
const ArrayAttr &rhsParams,
bool unifyDynamicSize =
false
622 if (lhsParams && rhsParams) {
623 return typeParamsUnify(lhsParams.getValue(), rhsParams.getValue(), unifyDynamicSize);
626 return !lhsParams && !rhsParams;
631 if (!
typesUnify(lhs.getElementType(), rhs.getElementType())) {
636 lhs.getDimensionSizes(), rhs.getDimensionSizes(),
true
642 SmallVector<StringRef> rhsNames =
getNames(rhs.getNameRef());
643 rhsNames.insert(rhsNames.begin(), rhsRevPrefix.rbegin(), rhsRevPrefix.rend());
644 if (rhsNames !=
getNames(lhs.getNameRef())) {
655 if (overrideSuccess && overrideSuccess(lhs, rhs)) {
659 if (TypeVarType lhsTvar = llvm::dyn_cast<TypeVarType>(lhs)) {
660 track(Side::LHS, lhsTvar.getNameRef(), rhs);
663 if (TypeVarType rhsTvar = llvm::dyn_cast<TypeVarType>(rhs)) {
664 track(Side::RHS, rhsTvar.getNameRef(), lhs);
667 if (llvm::isa<StructType>(lhs) && llvm::isa<StructType>(rhs)) {
668 return structTypesUnify(llvm::cast<StructType>(lhs), llvm::cast<StructType>(rhs));
670 if (llvm::isa<ArrayType>(lhs) && llvm::isa<ArrayType>(rhs)) {
671 return arrayTypesUnify(llvm::cast<ArrayType>(lhs), llvm::cast<ArrayType>(rhs));
677 template <
typename Tracker,
typename Key,
typename Val>
678 inline void track(Tracker &tracker, Side side, Key keyHead, Val val) {
679 auto key = std::make_pair(keyHead, side);
680 auto it = tracker.find(key);
681 if (it == tracker.end()) {
682 tracker.try_emplace(key, val);
683 }
else if (it->getSecond() != val) {
684 it->second =
nullptr;
688 void track(Side side, SymbolRefAttr symRef, Type ty) {
691 if (TypeVarType tvar = dyn_cast<TypeVarType>(ty)) {
693 attr = tvar.getNameRef();
696 attr = TypeAttr::get(ty);
700 track(*unifications, side, symRef, attr);
704 void track(Side side, SymbolRefAttr symRef, Attribute attr) {
707 if (TypeAttr tyAttr = dyn_cast<TypeAttr>(attr)) {
708 if (TypeVarType tvar = dyn_cast<TypeVarType>(tyAttr.getValue())) {
709 attr = tvar.getNameRef();
718 if (SymbolRefAttr otherSymAttr = dyn_cast<SymbolRefAttr>(attr)) {
719 track(*unifications,
reverse(side), otherSymAttr, symRef);
721 track(*unifications, side, symRef, attr);
725 void track(Side side, AffineMapAttr affineAttr, IntegerAttr intAttr) {
726 if (affineToIntTracker) {
730 track(*affineToIntTracker, side, affineAttr, intAttr);
734 bool paramAttrUnify(Attribute lhsAttr, Attribute rhsAttr,
bool unifyDynamicSize =
false) {
738 if (lhsAttr == rhsAttr) {
743 if (AffineMapAttr lhsAffine = llvm::dyn_cast<AffineMapAttr>(lhsAttr)) {
744 if (IntegerAttr rhsInt = llvm::dyn_cast<IntegerAttr>(rhsAttr)) {
746 track(Side::LHS, lhsAffine, rhsInt);
751 if (AffineMapAttr rhsAffine = llvm::dyn_cast<AffineMapAttr>(rhsAttr)) {
752 if (IntegerAttr lhsInt = llvm::dyn_cast<IntegerAttr>(lhsAttr)) {
754 track(Side::RHS, rhsAffine, lhsInt);
761 if (SymbolRefAttr lhsSymRef = llvm::dyn_cast<SymbolRefAttr>(lhsAttr)) {
762 track(Side::LHS, lhsSymRef, rhsAttr);
765 if (SymbolRefAttr rhsSymRef = llvm::dyn_cast<SymbolRefAttr>(rhsAttr)) {
766 track(Side::RHS, rhsSymRef, lhsAttr);
774 if (unifyDynamicSize) {
775 auto dyn_cast_if_dynamic = [](Attribute attr) -> IntegerAttr {
776 if (IntegerAttr intAttr = llvm::dyn_cast<IntegerAttr>(attr)) {
783 auto is_const_like = [](Attribute attr) {
784 return llvm::isa_and_present<IntegerAttr, SymbolRefAttr, AffineMapAttr>(attr);
786 if (IntegerAttr lhsIntAttr = dyn_cast_if_dynamic(lhsAttr)) {
787 if (is_const_like(rhsAttr)) {
791 if (IntegerAttr rhsIntAttr = dyn_cast_if_dynamic(rhsAttr)) {
792 if (is_const_like(lhsAttr)) {
798 if (TypeAttr lhsTy = llvm::dyn_cast<TypeAttr>(lhsAttr)) {
799 if (TypeAttr rhsTy = llvm::dyn_cast<TypeAttr>(rhsAttr)) {
800 return typesUnify(lhsTy.getValue(), rhsTy.getValue());
811 const ArrayRef<Attribute> &lhsParams,
const ArrayRef<Attribute> &rhsParams,
814 return UnifierImpl(unifications).typeParamsUnify(lhsParams, rhsParams);
820 const ArrayAttr &lhsParams,
const ArrayAttr &rhsParams,
UnificationMap *unifications
822 return UnifierImpl(unifications).typeParamsUnify(lhsParams, rhsParams);
828 return UnifierImpl(unifications, rhsReversePrefix).arrayTypesUnify(lhs, rhs);
835 return UnifierImpl(unifications, rhsReversePrefix).structTypesUnify(lhs, rhs);
839 Type lhs, Type rhs, ArrayRef<StringRef> rhsReversePrefix,
UnificationMap *unifications
841 return UnifierImpl(unifications, rhsReversePrefix).typesUnify(lhs, rhs);
845 Type oldTy, Type newTy, llvm::function_ref<
bool(Type oldTy, Type newTy)> knownOldToNew
848 AffineInstantiations affineInstantiations;
850 if (!UnifierImpl(&unifications)
851 .trackAffineToInt(&affineInstantiations)
852 .withOverrides(knownOldToNew)
862 auto entryIsRHS = [](
const auto &entry) {
return entry.first.second ==
Side::RHS; };
863 return !llvm::any_of(unifications, entryIsRHS) && !llvm::any_of(affineInstantiations, entryIsRHS);
867 if (llvm::isa<IndexType>(attr.getType())) {
872 APInt value = attr.getValue();
873 auto compare = value.getBitWidth() <=> IndexType::kInternalStorageBitWidth;
875 value = value.zext(IndexType::kInternalStorageBitWidth);
876 }
else if (compare > 0) {
877 return emitError().append(
"value is too large for `index` type: ",
debug::toStringOne(value));
879 return IntegerAttr::get(IndexType::get(attr.getContext()), value);
883 if (IntegerAttr intAttr = llvm::dyn_cast_if_present<IntegerAttr>(attr)) {
889FailureOr<SmallVector<Attribute>>
891 SmallVector<Attribute> result;
892 for (Attribute attr : attrList) {
894 if (failed(forced)) {
897 result.push_back(*forced);
903 if (IntegerAttr intAttr = llvm::dyn_cast_if_present<IntegerAttr>(in)) {
904 Type attrTy = intAttr.getType();
905 if (!AllowedTypes().onlyInt().isValidTypeImpl(attrTy)) {
908 .append(
"IntegerAttr must have type 'index' or 'i1' but found '", attrTy,
'\'')
918 if (AffineMapAttr affineAttr = llvm::dyn_cast_if_present<AffineMapAttr>(in)) {
919 AffineMap map = affineAttr.getValue();
920 if (map.getNumResults() != 1) {
924 "AffineMapAttr must yield a single result, but found ", map.getNumResults(),
936 return success(AllowedTypes().areValidStructTypeParams(params, emitError));
940 return success(AllowedTypes().areValidArrayDimSizes(dimensionSizes, emitError));
945 return success(AllowedTypes().isValidArrayTypeImpl(elementType, dimensionSizes, emitError));
950 using TypeVarAttrs = TypeList<SymbolRefAttr>;
951 if (!TypeListUnion<ArrayDimensionTypes, StructParamTypes, TypeVarAttrs>::matches(attr)) {
952 llvm::report_fatal_error(
953 "Legal type parameters are inconsistent. Encountered " +
954 attr.getAbstractAttribute().getName()
962 size_t numArrDims = dimsFromArr.size();
964 size_t numSubArrDims = dimsFromSubArr.size();
966 if (numArrDims < numSubArrDims) {
967 return emitError().append(
968 "subarray type ", subArrayType,
" has more dimensions than array type ", arrayType
972 size_t toDrop = numArrDims - numSubArrDims;
973 ArrayRef<Attribute> dimsFromArrReduced = dimsFromArr.drop_front(toDrop);
978 llvm::raw_string_ostream ss(message);
980 ss <<
"cannot unify array dimensions [";
981 llvm::interleaveComma(dimsFromArrReduced, ss, appendOne);
983 llvm::interleaveComma(dimsFromSubArr, ss, appendOne);
985 return emitError().append(message);
990 return emitError().append(
991 "incorrect array element type; expected: ", arrayType.
getElementType(),
1001 if (
auto subArrayType = llvm::dyn_cast<ArrayType>(subArrayOrElemType)) {
1005 return emitError().append(
1006 "incorrect array element type; expected: ", arrayType.
getElementType(),
1007 ", 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)