LLZK 0.1.0
Veridise's ZK Language IR
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 {
25namespace debug {
26
27namespace {
28
29// Define this concept instead of `std::ranges::range` because certain classes (like OperandRange)
30// do not work with `std::ranges::range`.
31template <typename T>
32concept Iterable = requires(T t) {
33 std::begin(t);
34 std::end(t);
35};
36
37struct Appender {
38 llvm::raw_string_ostream stream;
39 Appender(std::string &out) : stream(out) {}
40
41 void append(const mlir::MemorySlot &a);
42 void append(const mlir::DestructurableMemorySlot &a);
43 void append(const mlir::OpOperand &a);
44 void append(const mlir::NamedAttribute &a);
45 void append(const mlir::SymbolTable::SymbolUse &a);
46 template <typename T> void append(const std::optional<T> &a);
47 template <typename Any> void append(const Any &value);
48 template <typename A, typename B> void append(const std::pair<A, B> &a);
49 template <typename A, typename B> void append(const llvm::detail::DenseMapPair<A, B> &a);
50 template <Iterable InputIt> void append(const InputIt &collection);
51 template <typename InputIt> void appendList(InputIt begin, InputIt end);
52 template <typename Any> Appender &operator<<(const Any &v);
53};
54
55[[maybe_unused]]
56void Appender::append(const mlir::MemorySlot &a) {
57 stream << "ptr: " << a.ptr << "; type: " << a.elemType;
58}
59
60[[maybe_unused]]
61void Appender::append(const mlir::DestructurableMemorySlot &a) {
62 stream << "ptr: " << a.ptr << "; type: " << a.elemType << "; elementPtrs:\n";
63 for (auto &p : a.elementPtrs) {
64 stream.indent(2);
65 append(p);
66 stream << '\n';
67 }
68}
69
70[[maybe_unused]]
71void Appender::append(const mlir::OpOperand &a) {
72 stream << a.get();
73}
74
75[[maybe_unused]]
76void Appender::append(const mlir::NamedAttribute &a) {
77 stream << a.getName() << '=' << a.getValue();
78}
79
80[[maybe_unused]]
81void Appender::append(const mlir::SymbolTable::SymbolUse &a) {
82 stream << a.getUser()->getName();
83}
84
85template <typename T>
86[[maybe_unused]]
87inline void Appender::append(const std::optional<T> &a) {
88 if (a.has_value()) {
89 append(a.value());
90 } else {
91 stream << "NONE";
92 }
93}
94
95template <typename Any>
96[[maybe_unused]]
97void Appender::append(const Any &value) {
98 stream << value;
99}
100
101template <typename A, typename B>
102[[maybe_unused]]
103void Appender::append(const std::pair<A, B> &a) {
104 stream << '(';
105 append(a.first);
106 stream << ',';
107 append(a.second);
108 stream << ')';
109}
110
111template <typename A, typename B>
112[[maybe_unused]]
113void Appender::append(const llvm::detail::DenseMapPair<A, B> &a) {
114 stream << '(';
115 append(a.first);
116 stream << ',';
117 append(a.second);
118 stream << ')';
119}
120
121template <Iterable InputIt>
122[[maybe_unused]]
123inline void Appender::append(const InputIt &collection) {
124 appendList(std::begin(collection), std::end(collection));
125}
126
127template <typename InputIt>
128[[maybe_unused]]
129void Appender::appendList(InputIt begin, InputIt end) {
130 stream << '[';
131 llvm::interleave(begin, end, [this](const auto &n) { this->append(n); }, [this] {
132 this->stream << ", ";
133 });
134 stream << ']';
135}
136
137template <typename Any>
138[[maybe_unused]]
139Appender &Appender::operator<<(const Any &v) {
140 append(v);
141 return *this;
142}
143
144} // namespace
145
148template <typename InputIt>
149[[maybe_unused]]
150inline std::string toStringList(InputIt begin, InputIt end) {
151 std::string output;
152 Appender(output).appendList(begin, end);
153 return output;
154}
155
158template <typename InputIt>
159[[maybe_unused]]
160inline std::string toStringList(const InputIt &collection) {
161 return toStringList(collection.begin(), collection.end());
162}
163
164template <typename InputIt>
165[[maybe_unused]]
166inline std::string toStringList(const std::optional<InputIt> &optionalCollection) {
167 if (optionalCollection.has_value()) {
168 return toStringList(optionalCollection.value());
169 } else {
170 return "NONE";
171 }
172}
173
174template <typename T>
175[[maybe_unused]]
176inline std::string toStringOne(const T &value) {
177 std::string output;
178 Appender(output).append(value);
179 return output;
180}
181
182[[maybe_unused]]
183void dumpSymbolTableWalk(mlir::Operation *symbolTableOp);
184
185[[maybe_unused]]
186void dumpSymbolTable(llvm::raw_ostream &stream, mlir::SymbolTable &symTab, unsigned indent = 0);
187
188[[maybe_unused]]
189void dumpSymbolTable(mlir::SymbolTable &symTab);
190
191[[maybe_unused]]
192void dumpSymbolTables(llvm::raw_ostream &stream, mlir::SymbolTableCollection &tables);
193
194[[maybe_unused]]
195void dumpSymbolTables(mlir::SymbolTableCollection &tables);
196
197[[maybe_unused]]
198void dumpToFile(mlir::Operation *op, llvm::StringRef filename);
199
200} // namespace debug
201} // namespace llzk
std::string toStringOne(const T &value)
Definition Debug.h:176
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:150
void dumpSymbolTable(llvm::raw_ostream &stream, SymbolTable &symTab, unsigned indent)
Definition Debug.cpp:30
void dumpSymbolTables(llvm::raw_ostream &stream, SymbolTableCollection &tables)
Definition Debug.cpp:50
void dumpSymbolTableWalk(Operation *symbolTableOp)
Definition Debug.cpp:18
void dumpToFile(Operation *op, llvm::StringRef filename)
Definition Debug.cpp:71
raw_ostream & operator<<(raw_ostream &os, const ConstrainRef &rhs)