LLZK 2.0.0
An open-source IR for Zero Knowledge (ZK) circuits
Loading...
Searching...
No Matches
Debug.h
Go to the documentation of this file.
1//===-- Debug.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
12#include <mlir/IR/Attributes.h>
13#include <mlir/IR/Operation.h>
14#include <mlir/IR/SymbolTable.h>
15#include <mlir/IR/Value.h>
16#include <mlir/Interfaces/MemorySlotInterfaces.h>
17
18#include <llvm/ADT/DenseMap.h>
19#include <llvm/Support/raw_ostream.h>
20
21#include <optional>
22#include <string>
23
24namespace llzk::debug {
25
26namespace {
27
28// Define this concept instead of `std::ranges::range` because certain classes (like OperandRange)
29// do not work with `std::ranges::range`.
30template <typename T>
31concept Iterable = requires(T t) {
32 std::begin(t);
33 std::end(t);
34};
35
36struct Appender {
37 llvm::raw_string_ostream stream;
38 Appender(std::string &out) : stream(out) {}
39
40 void append(const mlir::MemorySlot &a);
41 void append(const mlir::DestructurableMemorySlot &a);
42 void append(const mlir::OpOperand &a);
43 void append(const mlir::NamedAttribute &a);
44 void append(const mlir::SymbolTable::SymbolUse &a);
45 // Adding StringRef explicitly so strings are not printed via appendList.
46 void append(const llvm::StringRef a);
47 template <typename T> void append(const std::optional<T> &a);
48 template <typename Any> void append(const Any &value);
49 template <typename A, typename B> void append(const std::pair<A, B> &a);
50 template <typename A, typename B> void append(const llvm::detail::DenseMapPair<A, B> &a);
51 template <Iterable InputIt> void append(const InputIt &collection);
52 template <typename InputIt> void appendList(InputIt begin, InputIt end);
53 template <typename Any> Appender &operator<<(const Any &v);
54};
55
56[[maybe_unused]]
57void Appender::append(const mlir::MemorySlot &a) {
58 stream << "ptr: " << a.ptr << "; type: " << a.elemType;
59}
60
61[[maybe_unused]]
62void Appender::append(const mlir::DestructurableMemorySlot &a) {
63 stream << "ptr: " << a.ptr << "; type: " << a.elemType << "; subelementTypes:\n";
64 for (const auto &p : a.subelementTypes) {
65 stream.indent(2);
66 append(p);
67 stream << '\n';
68 }
69}
70
71[[maybe_unused]]
72void Appender::append(const mlir::OpOperand &a) {
73 stream << a.get();
74}
75
76[[maybe_unused]]
77void Appender::append(const mlir::NamedAttribute &a) {
78 stream << a.getName() << '=' << a.getValue();
79}
80
81[[maybe_unused]]
82void Appender::append(const mlir::SymbolTable::SymbolUse &a) {
83 stream << a.getUser()->getName();
84}
85
86[[maybe_unused]]
87void Appender::append(const llvm::StringRef a) {
88 stream << a;
89}
90
91template <typename T>
92[[maybe_unused]]
93inline void Appender::append(const std::optional<T> &a) {
94 if (a.has_value()) {
95 append(a.value());
96 } else {
97 stream << "NONE";
98 }
99}
100
101template <typename Any>
102[[maybe_unused]]
103void Appender::append(const Any &value) {
104 stream << value;
105}
106
107template <typename A, typename B>
108[[maybe_unused]]
109void Appender::append(const std::pair<A, B> &a) {
110 stream << '(';
111 append(a.first);
112 stream << ',';
113 append(a.second);
114 stream << ')';
115}
116
117template <typename A, typename B>
118[[maybe_unused]]
119void Appender::append(const llvm::detail::DenseMapPair<A, B> &a) {
120 stream << '(';
121 append(a.first);
122 stream << ',';
123 append(a.second);
124 stream << ')';
125}
126
127template <Iterable InputIt>
128[[maybe_unused]]
129inline void Appender::append(const InputIt &collection) {
130 appendList(std::begin(collection), std::end(collection));
131}
132
133template <typename InputIt>
134[[maybe_unused]]
135void Appender::appendList(InputIt begin, InputIt end) {
136 stream << '[';
137 llvm::interleave(begin, end, [this](const auto &n) { this->append(n); }, [this] {
138 this->stream << ", ";
139 });
140 stream << ']';
141}
142
143template <typename Any>
144[[maybe_unused]]
145Appender &Appender::operator<<(const Any &v) {
146 append(v);
147 return *this;
148}
149
150} // namespace
151
154template <typename InputIt>
155[[maybe_unused]]
156inline std::string toStringList(InputIt begin, InputIt end) {
157 std::string output;
158 Appender(output).appendList(begin, end);
159 return output;
160}
161
164template <typename InputIt>
165[[maybe_unused]]
166inline std::string toStringList(const InputIt &collection) {
167 return toStringList(collection.begin(), collection.end());
168}
169
170template <typename InputIt>
171[[maybe_unused]]
172inline std::string toStringList(const std::optional<InputIt> &optionalCollection) {
173 if (optionalCollection.has_value()) {
174 return toStringList(optionalCollection.value());
175 } else {
176 return "NONE";
177 }
178}
179
180template <typename T>
181[[maybe_unused]]
182inline std::string toStringOne(const T &value) {
183 std::string output;
184 Appender(output).append(value);
185 return output;
186}
187
188[[maybe_unused]]
189void dumpSymbolTableWalk(mlir::Operation *symbolTableOp);
190
191[[maybe_unused]]
192void dumpSymbolTable(llvm::raw_ostream &stream, mlir::SymbolTable &symTab, unsigned indent = 0);
193
194[[maybe_unused]]
195void dumpSymbolTable(mlir::SymbolTable &symTab);
196
197[[maybe_unused]]
198void dumpSymbolTables(llvm::raw_ostream &stream, mlir::SymbolTableCollection &tables);
199
200[[maybe_unused]]
201void dumpSymbolTables(mlir::SymbolTableCollection &tables);
202
203[[maybe_unused]]
204void dumpToFile(mlir::Operation *op, llvm::StringRef filename);
205
206} // namespace llzk::debug
std::string toStringOne(const T &value)
Definition Debug.h:182
std::string toStringList(InputIt begin, InputIt end)
Generate a comma-separated string representation by traversing elements from begin to end where the e...
Definition Debug.h:156
void dumpSymbolTable(llvm::raw_ostream &stream, SymbolTable &symTab, unsigned indent)
Definition Debug.cpp:31
void dumpSymbolTables(llvm::raw_ostream &stream, SymbolTableCollection &tables)
Definition Debug.cpp:51
void dumpSymbolTableWalk(Operation *symbolTableOp)
Definition Debug.cpp:19
void dumpToFile(Operation *op, llvm::StringRef filename)
Definition Debug.cpp:72
Interval operator<<(const Interval &lhs, const Interval &rhs)