LLZK 0.1.0
Veridise's ZK Language IR
Loading...
Searching...
No Matches
SymbolHelper.h
Go to the documentation of this file.
1//===-- SymbolHelper.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/Interfaces/CallInterfaces.h>
15
16#include <ranges>
17
18namespace llzk {
19
20namespace component {
21class StructType;
22class StructDefOp;
23} // namespace component
24
25namespace function {
26class FuncDefOp;
27} // namespace function
28
29llvm::SmallVector<mlir::StringRef> getNames(mlir::SymbolRefAttr ref);
30llvm::SmallVector<mlir::FlatSymbolRefAttr> getPieces(mlir::SymbolRefAttr ref);
31
33inline mlir::FlatSymbolRefAttr
34getFlatSymbolRefAttr(mlir::MLIRContext *context, const mlir::Twine &twine) {
35 return mlir::FlatSymbolRefAttr::get(mlir::StringAttr::get(context, twine));
36}
37
39inline mlir::SymbolRefAttr asSymbolRefAttr(mlir::StringAttr root, mlir::SymbolRefAttr tail) {
40 return mlir::SymbolRefAttr::get(root, getPieces(tail));
41}
42
44inline mlir::SymbolRefAttr asSymbolRefAttr(llvm::ArrayRef<mlir::FlatSymbolRefAttr> path) {
45 return mlir::SymbolRefAttr::get(path.front().getAttr(), path.drop_front());
46}
47
49inline mlir::SymbolRefAttr asSymbolRefAttr(std::vector<mlir::FlatSymbolRefAttr> path) {
50 return asSymbolRefAttr(llvm::ArrayRef<mlir::FlatSymbolRefAttr>(path));
51}
52
54inline mlir::SymbolRefAttr getTailAsSymbolRefAttr(mlir::SymbolRefAttr symbol) {
55 return asSymbolRefAttr(symbol.getNestedReferences());
56}
57
59inline mlir::SymbolRefAttr getPrefixAsSymbolRefAttr(mlir::SymbolRefAttr symbol) {
60 return mlir::SymbolRefAttr::get(
61 symbol.getRootReference(), symbol.getNestedReferences().drop_back()
62 );
63}
64
66mlir::SymbolRefAttr replaceLeaf(mlir::SymbolRefAttr orig, mlir::FlatSymbolRefAttr newLeaf);
67inline mlir::SymbolRefAttr replaceLeaf(mlir::SymbolRefAttr orig, mlir::StringAttr newLeaf) {
68 return replaceLeaf(orig, mlir::FlatSymbolRefAttr::get(newLeaf));
69}
70inline mlir::SymbolRefAttr replaceLeaf(mlir::SymbolRefAttr orig, const mlir::Twine &newLeaf) {
71 return replaceLeaf(orig, mlir::StringAttr::get(orig.getContext(), newLeaf));
72}
73
75mlir::SymbolRefAttr appendLeaf(mlir::SymbolRefAttr orig, mlir::FlatSymbolRefAttr newLeaf);
76inline mlir::SymbolRefAttr appendLeaf(mlir::SymbolRefAttr orig, mlir::StringAttr newLeaf) {
77 return appendLeaf(orig, mlir::FlatSymbolRefAttr::get(newLeaf));
78}
79inline mlir::SymbolRefAttr appendLeaf(mlir::SymbolRefAttr orig, const mlir::Twine &newLeaf) {
80 return appendLeaf(orig, mlir::StringAttr::get(orig.getContext(), newLeaf));
81}
82
85mlir::SymbolRefAttr appendLeafName(mlir::SymbolRefAttr orig, const mlir::Twine &newLeafSuffix);
86
87mlir::FailureOr<mlir::ModuleOp> getRootModule(mlir::Operation *from);
88mlir::FailureOr<mlir::SymbolRefAttr> getPathFromRoot(component::StructDefOp &to);
89mlir::FailureOr<mlir::SymbolRefAttr> getPathFromRoot(function::FuncDefOp &to);
90
93mlir::FailureOr<mlir::ModuleOp> getTopRootModule(mlir::Operation *from);
94mlir::FailureOr<mlir::SymbolRefAttr> getPathFromTopRoot(component::StructDefOp &to);
95mlir::FailureOr<mlir::SymbolRefAttr> getPathFromTopRoot(function::FuncDefOp &to);
96
102template <typename T>
103inline mlir::FailureOr<SymbolLookupResult<T>>
104resolveCallable(mlir::SymbolTableCollection &symbolTable, mlir::CallOpInterface call) {
105 mlir::CallInterfaceCallable callable = call.getCallableForCallee();
106 if (auto symbolVal = llvm::dyn_cast<mlir::Value>(callable)) {
107 return SymbolLookupResult<T>(symbolVal.getDefiningOp());
108 }
109
110 // If the callable isn't a value, lookup the symbol reference.
111 // We first try to resolve in the nearest symbol table, as per the default
112 // MLIR behavior. If the resulting operation is not found, we will then
113 // use the LLZK lookup helpers.
114 auto symbolRef = callable.get<mlir::SymbolRefAttr>();
115 mlir::Operation *op = symbolTable.lookupNearestSymbolFrom(call.getOperation(), symbolRef);
116
117 if (op) {
118 return SymbolLookupResult<T>(std::move(op));
119 }
120 // Otherwise, use the top-level lookup.
121 return lookupTopLevelSymbol<T>(symbolTable, symbolRef, call.getOperation());
122}
123
124template <typename T>
125inline mlir::FailureOr<SymbolLookupResult<T>> resolveCallable(mlir::CallOpInterface call) {
126 mlir::SymbolTableCollection symbolTable;
127 return resolveCallable<T>(symbolTable, call);
128}
129
131bool hasUsesWithin(mlir::Operation *symbol, mlir::Operation *from);
132
134mlir::LogicalResult verifyParamOfType(
135 mlir::SymbolTableCollection &tables, mlir::SymbolRefAttr param, mlir::Type structOrArrayType,
136 mlir::Operation *origin
137);
138
141mlir::LogicalResult verifyParamsOfType(
142 mlir::SymbolTableCollection &tables, mlir::ArrayRef<mlir::Attribute> tyParams,
143 mlir::Type structOrArrayType, mlir::Operation *origin
144);
145
147mlir::FailureOr<component::StructDefOp> verifyStructTypeResolution(
148 mlir::SymbolTableCollection &tables, component::StructType ty, mlir::Operation *origin
149);
150
152mlir::LogicalResult
153verifyTypeResolution(mlir::SymbolTableCollection &tables, mlir::Operation *origin, mlir::Type type);
154
156template <std::ranges::input_range Range>
157mlir::LogicalResult verifyTypeResolution(
158 mlir::SymbolTableCollection &tables, mlir::Operation *origin, const Range &types
159) {
160 // Check all before returning to present all applicable type errors in one compilation.
161 bool failed = false;
162 for (const auto &t : types) {
163 failed |= mlir::failed(verifyTypeResolution(tables, origin, t));
164 }
165 return mlir::LogicalResult::failure(failed);
166}
167
168} // namespace llzk
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for and distribution as defined by Sections through of this document Licensor shall mean the copyright owner or entity authorized by the copyright owner that is granting the License Legal Entity shall mean the union of the acting entity and all other entities that control are controlled by or are under common control with that entity For the purposes of this definition control direct or to cause the direction or management of such whether by contract or including but not limited to software source documentation and configuration files Object form shall mean any form resulting from mechanical transformation or translation of a Source including but not limited to compiled object generated and conversions to other media types Work shall mean the work of whether in Source or Object made available under the as indicated by a copyright notice that is included in or attached to the whether in Source or Object that is based or other modifications as a an original work of authorship For the purposes of this Derivative Works shall not include works that remain separable from
Definition LICENSE.txt:45
This file defines methods symbol lookup across LLZK operations and included files.
mlir::SymbolRefAttr getPrefixAsSymbolRefAttr(mlir::SymbolRefAttr symbol)
Return SymbolRefAttr like the one given but with the leaf/final element removed.
FailureOr< SymbolRefAttr > getPathFromRoot(StructDefOp &to)
SymbolRefAttr appendLeafName(SymbolRefAttr orig, const Twine &newLeafSuffix)
bool hasUsesWithin(Operation *symbol, Operation *from)
mlir::FlatSymbolRefAttr getFlatSymbolRefAttr(mlir::MLIRContext *context, const mlir::Twine &twine)
Construct a FlatSymbolRefAttr with the given content.
mlir::FailureOr< SymbolLookupResultUntyped > lookupTopLevelSymbol(mlir::SymbolTableCollection &tables, mlir::SymbolRefAttr symbol, mlir::Operation *origin, bool reportMissing=true)
llvm::SmallVector< StringRef > getNames(SymbolRefAttr ref)
FailureOr< ModuleOp > getRootModule(Operation *from)
SymbolRefAttr appendLeaf(SymbolRefAttr orig, FlatSymbolRefAttr newLeaf)
SymbolRefAttr replaceLeaf(SymbolRefAttr orig, FlatSymbolRefAttr newLeaf)
FailureOr< StructDefOp > verifyStructTypeResolution(SymbolTableCollection &tables, StructType ty, Operation *origin)
FailureOr< SymbolRefAttr > getPathFromTopRoot(StructDefOp &to)
mlir::FailureOr< SymbolLookupResult< T > > resolveCallable(mlir::SymbolTableCollection &symbolTable, mlir::CallOpInterface call)
Based on mlir::CallOpInterface::resolveCallable, but using LLZK lookup helpers.
FailureOr< ModuleOp > getTopRootModule(Operation *from)
LogicalResult verifyTypeResolution(SymbolTableCollection &tables, Operation *origin, Type ty)
LogicalResult verifyParamsOfType(SymbolTableCollection &tables, ArrayRef< Attribute > tyParams, Type parameterizedType, Operation *origin)
mlir::SymbolRefAttr asSymbolRefAttr(mlir::StringAttr root, mlir::SymbolRefAttr tail)
Build a SymbolRefAttr that prepends tail with root, i.e. root::tail.
mlir::SymbolRefAttr getTailAsSymbolRefAttr(mlir::SymbolRefAttr symbol)
Return SymbolRefAttr like the one given but with the root/head element removed.
LogicalResult verifyParamOfType(SymbolTableCollection &tables, SymbolRefAttr param, Type parameterizedType, Operation *origin)
llvm::SmallVector< FlatSymbolRefAttr > getPieces(SymbolRefAttr ref)