LLZK 0.1.0
Veridise's ZK Language IR
Loading...
Searching...
No Matches
TypeHelper.h
Go to the documentation of this file.
1//===-- TypeHelper.h --------------------------------------------*- C++ -*-===//
2//
3// Part of the LLZK Project, under the Apache License v2.0.
4// See LICENSE.txt for license information.
5// Copyright 2025 Veridise Inc.
6// SPDX-License-Identifier: Apache-2.0
7//
8//===----------------------------------------------------------------------===//
9
10#pragma once
11
13
14#include <mlir/IR/OpImplementation.h>
15#include <mlir/IR/Operation.h>
16#include <mlir/IR/SymbolTable.h>
17
18#include <llvm/ADT/ArrayRef.h>
19#include <llvm/ADT/DenseMap.h>
20#include <llvm/ADT/StringRef.h>
21
22namespace llzk {
23
24// Forward declarations
25namespace component {
26class StructType;
27} // namespace component
28namespace array {
29class ArrayType;
30} // namespace array
31
36class BuildShortTypeString {
37 static constexpr char PLACEHOLDER = '\x1A';
38
39 std::string ret;
40 llvm::raw_string_ostream ss;
41
42 BuildShortTypeString() : ret(), ss(ret) {}
43 BuildShortTypeString &append(mlir::Type);
44 BuildShortTypeString &append(mlir::ArrayRef<mlir::Attribute>);
45 BuildShortTypeString &append(mlir::Attribute);
46
47 void appendSymRef(mlir::SymbolRefAttr);
48 void appendSymName(mlir::StringRef);
49
50public:
52 static inline std::string from(mlir::Type type) {
53 return BuildShortTypeString().append(type).ret;
54 }
55
58 static inline std::string from(mlir::ArrayRef<mlir::Attribute> attrs) {
59 return BuildShortTypeString().append(attrs).ret;
60 }
61
69 static std::string from(const std::string &base, mlir::ArrayRef<mlir::Attribute> attrs);
70};
71
72// This function asserts that the given Attribute kind is legal within the LLZK types that can
73// contain Attribute parameters (i.e. ArrayType, StructType, and TypeVarType). This should be used
74// in any function that examines the attribute parameters within parameterized LLZK types to ensure
75// that the function handles all possible cases properly, especially if more legal attributes are
76// added in the future. Throw a fatal error if anything illegal is found, indicating that the caller
77// of this function should be updated.
78void assertValidAttrForParamOfType(mlir::Attribute attr);
79
81bool isValidType(mlir::Type type);
82
86 mlir::Type type, mlir::SymbolTableCollection &symbolTable, mlir::Operation *op
87);
88
90bool isValidGlobalType(mlir::Type type);
91
93bool isValidEmitEqType(mlir::Type type);
94
96bool isValidConstReadType(mlir::Type type);
97
99bool isValidArrayElemType(mlir::Type type);
100
102bool isValidArrayType(mlir::Type type);
103
105bool isConcreteType(mlir::Type type, bool allowStructParams = true);
106
107inline mlir::LogicalResult checkValidType(EmitErrorFn emitError, mlir::Type type) {
108 if (!isValidType(type)) {
109 return emitError() << "expected a valid LLZK type but found " << type;
110 } else {
111 return mlir::success();
112 }
113}
114
116bool isSignalType(mlir::Type type);
117
120
122bool hasAffineMapAttr(mlir::Type type);
123
124enum class Side { EMPTY = 0, LHS, RHS, TOMB };
125static inline mlir::raw_ostream &operator<<(mlir::raw_ostream &os, const Side &val) {
126 switch (val) {
127 case Side::EMPTY:
128 os << "EMPTY";
129 break;
130 case Side::TOMB:
131 os << "TOMB";
132 break;
133 case Side::LHS:
134 os << "LHS";
135 break;
136 case Side::RHS:
137 os << "RHS";
138 break;
139 }
140 return os;
141}
142
143inline Side reverse(Side in) {
144 switch (in) {
145 case Side::LHS:
146 return Side::RHS;
147 case Side::RHS:
148 return Side::LHS;
149 default:
150 return in;
151 }
152}
153
154} // namespace llzk
155
156namespace llvm {
157template <> struct DenseMapInfo<llzk::Side> {
158 using T = llzk::Side;
159 static inline T getEmptyKey() { return T::EMPTY; }
160 static inline T getTombstoneKey() { return T::TOMB; }
161 static unsigned getHashValue(const T &val) {
162 using UT = std::underlying_type_t<T>;
163 return llvm::DenseMapInfo<UT>::getHashValue(static_cast<UT>(val));
164 }
165 static bool isEqual(const T &lhs, const T &rhs) { return lhs == rhs; }
166};
167} // namespace llvm
168
169namespace llzk {
170
171bool isDynamic(mlir::IntegerAttr intAttr);
172
181using UnificationMap = mlir::DenseMap<std::pair<mlir::SymbolRefAttr, Side>, mlir::Attribute>;
182
186 const mlir::ArrayRef<mlir::Attribute> &lhsParams,
187 const mlir::ArrayRef<mlir::Attribute> &rhsParams, UnificationMap *unifications = nullptr
188);
189
193 const mlir::ArrayAttr &lhsParams, const mlir::ArrayAttr &rhsParams,
194 UnificationMap *unifications = nullptr
195);
196
201 mlir::ArrayRef<llvm::StringRef> rhsReversePrefix = {}, UnificationMap *unifications = nullptr
202);
203
208 mlir::ArrayRef<llvm::StringRef> rhsReversePrefix = {}, UnificationMap *unifications = nullptr
209);
210
214 mlir::Type lhs, mlir::Type rhs, mlir::ArrayRef<llvm::StringRef> rhsReversePrefix = {},
215 UnificationMap *unifications = nullptr
216);
217
220template <typename Iter1, typename Iter2>
221inline bool typeListsUnify(
222 Iter1 lhs, Iter2 rhs, mlir::ArrayRef<llvm::StringRef> rhsReversePrefix = {},
223 UnificationMap *unifications = nullptr
224) {
225 return (lhs.size() == rhs.size()) &&
226 std::equal(lhs.begin(), lhs.end(), rhs.begin(), [&](mlir::Type a, mlir::Type b) {
227 return typesUnify(a, b, rhsReversePrefix, unifications);
228 });
229}
230
231template <typename Iter1, typename Iter2>
233 Iter1 lhs, Iter2 rhs, mlir::ArrayRef<llvm::StringRef> rhsReversePrefix = {},
234 UnificationMap *unifications = nullptr
235) {
236 return lhs.size() == 1 && rhs.size() == 1 &&
237 typesUnify(lhs.front(), rhs.front(), rhsReversePrefix, unifications);
238}
239
247 mlir::Type oldTy, mlir::Type newTy,
248 llvm::function_ref<bool(mlir::Type oldTy, mlir::Type newTy)> knownOldToNew = nullptr
249);
250
251template <typename TypeClass> inline TypeClass getIfSingleton(mlir::TypeRange types) {
252 return (types.size() == 1) ? llvm::dyn_cast<TypeClass>(types.front()) : nullptr;
253}
254
255template <typename TypeClass> inline TypeClass getAtIndex(mlir::TypeRange types, size_t index) {
256 return (types.size() > index) ? llvm::dyn_cast<TypeClass>(types[index]) : nullptr;
257}
258
260mlir::IntegerAttr forceIntType(mlir::IntegerAttr attr);
261
263mlir::Attribute forceIntAttrType(mlir::Attribute attr);
264
266llvm::SmallVector<mlir::Attribute> forceIntAttrTypes(llvm::ArrayRef<mlir::Attribute> attrList);
267
269mlir::LogicalResult verifyIntAttrType(EmitErrorFn emitError, mlir::Attribute in);
270
272mlir::LogicalResult verifyAffineMapAttrType(EmitErrorFn emitError, mlir::Attribute in);
273
275mlir::LogicalResult verifyStructTypeParams(EmitErrorFn emitError, mlir::ArrayAttr params);
276
278mlir::LogicalResult
279verifyArrayDimSizes(EmitErrorFn emitError, mlir::ArrayRef<mlir::Attribute> dimensionSizes);
280
282mlir::LogicalResult verifyArrayType(
283 EmitErrorFn emitError, mlir::Type elementType, mlir::ArrayRef<mlir::Attribute> dimensionSizes
284);
285
286} // namespace llzk
static std::string from(mlir::ArrayRef< mlir::Attribute > attrs)
Return a brief string representation of the attribute list from a parameterized type.
Definition TypeHelper.h:58
static std::string from(const std::string &base, mlir::ArrayRef< mlir::Attribute > attrs)
Take an existing name prefix/base that contains N>=0 PLACEHOLDER character(s) and the Attribute list ...
static std::string from(mlir::Type type)
Return a brief string representation of the given LLZK type.
Definition TypeHelper.h:52
LogicalResult verifyAffineMapAttrType(EmitErrorFn emitError, Attribute in)
void assertValidAttrForParamOfType(Attribute attr)
mlir::raw_ostream & operator<<(mlir::raw_ostream &os, const ConstrainRef &rhs)
bool isValidArrayType(Type type)
LogicalResult verifyIntAttrType(EmitErrorFn emitError, Attribute in)
bool typeListsUnify(Iter1 lhs, Iter2 rhs, mlir::ArrayRef< llvm::StringRef > rhsReversePrefix={}, UnificationMap *unifications=nullptr)
Return true iff the two lists of Type instances are equivalent or could be equivalent after full inst...
Definition TypeHelper.h:221
bool isConcreteType(Type type, bool allowStructParams)
bool isValidArrayElemType(Type type)
llvm::function_ref< mlir::InFlightDiagnostic()> EmitErrorFn
Definition ErrorHelper.h:18
TypeClass getIfSingleton(mlir::TypeRange types)
Definition TypeHelper.h:251
bool isValidGlobalType(Type type)
bool singletonTypeListsUnify(Iter1 lhs, Iter2 rhs, mlir::ArrayRef< llvm::StringRef > rhsReversePrefix={}, UnificationMap *unifications=nullptr)
Definition TypeHelper.h:232
bool structTypesUnify(StructType lhs, StructType rhs, ArrayRef< StringRef > rhsReversePrefix, UnificationMap *unifications)
SmallVector< Attribute > forceIntAttrTypes(ArrayRef< Attribute > attrList)
LogicalResult verifyArrayType(EmitErrorFn emitError, Type elementType, ArrayRef< Attribute > dimensionSizes)
bool isValidColumnType(Type type, SymbolTableCollection &symbolTable, Operation *op)
mlir::DenseMap< std::pair< mlir::SymbolRefAttr, Side >, mlir::Attribute > UnificationMap
Optional result from type unifications.
Definition TypeHelper.h:181
bool isValidEmitEqType(Type type)
TypeClass getAtIndex(mlir::TypeRange types, size_t index)
Definition TypeHelper.h:255
bool isValidType(Type type)
bool arrayTypesUnify(ArrayType lhs, ArrayType rhs, ArrayRef< StringRef > rhsReversePrefix, UnificationMap *unifications)
bool isDynamic(IntegerAttr intAttr)
Side reverse(Side in)
Definition TypeHelper.h:143
bool isSignalType(Type type)
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)
Attribute forceIntAttrType(Attribute attr)
IntegerAttr forceIntType(IntegerAttr attr)
bool hasAffineMapAttr(Type type)
mlir::LogicalResult checkValidType(EmitErrorFn emitError, mlir::Type type)
Definition TypeHelper.h:107
bool isValidConstReadType(Type type)
LogicalResult verifyArrayDimSizes(EmitErrorFn emitError, ArrayRef< Attribute > dimensionSizes)
static bool isEqual(const T &lhs, const T &rhs)
Definition TypeHelper.h:165
static unsigned getHashValue(const T &val)
Definition TypeHelper.h:161