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
55void Appender::append(const mlir::MemorySlot &a) {
56 stream << "ptr: " << a.ptr << "; type: " << a.elemType;
57}
58
59void Appender::append(const mlir::DestructurableMemorySlot &a) {
60 stream << "ptr: " << a.ptr << "; type: " << a.elemType << "; elementPtrs:\n";
61 for (auto &p : a.elementPtrs) {
62 stream << " ";
63 append(p);
64 stream << '\n';
65 }
66}
67
68void Appender::append(const mlir::OpOperand &a) { stream << a.get(); }
69
70void Appender::append(const mlir::NamedAttribute &a) {
71 stream << a.getName() << '=' << a.getValue();
72}
73
74void Appender::append(const mlir::SymbolTable::SymbolUse &a) { stream << a.getUser()->getName(); }
75
76template <typename T> inline void Appender::append(const std::optional<T> &a) {
77 if (a.has_value()) {
78 append(a.value());
79 } else {
80 stream << "NONE";
81 }
82}
83
84template <typename Any> void Appender::append(const Any &value) { stream << value; }
85
86template <typename A, typename B> void Appender::append(const std::pair<A, B> &a) {
87 stream << '(';
88 append(a.first);
89 stream << ',';
90 append(a.second);
91 stream << ')';
92}
93
94template <typename A, typename B> void Appender::append(const llvm::detail::DenseMapPair<A, B> &a) {
95 stream << '(';
96 append(a.first);
97 stream << ',';
98 append(a.second);
99 stream << ')';
100}
101
102template <Iterable InputIt> inline void Appender::append(const InputIt &collection) {
103 appendList(std::begin(collection), std::end(collection));
104}
105
106template <typename InputIt> void Appender::appendList(InputIt begin, InputIt end) {
107 stream << '[';
108 llvm::interleave(begin, end, [this](const auto &n) { append(n); }, [this] { stream << ", "; });
109 stream << ']';
110}
111
112template <typename Any> Appender &Appender::operator<<(const Any &v) {
113 append(v);
114 return *this;
115}
116
117} // namespace
118
121template <typename InputIt> inline std::string toStringList(InputIt begin, InputIt end) {
122 std::string output;
123 Appender(output).appendList(begin, end);
124 return output;
125}
126
129template <typename InputIt> inline std::string toStringList(const InputIt &collection) {
130 return toStringList(collection.begin(), collection.end());
131}
132
133template <typename InputIt>
134inline std::string toStringList(const std::optional<InputIt> &optionalCollection) {
135 if (optionalCollection.has_value()) {
136 return toStringList(optionalCollection.value());
137 } else {
138 return "NONE";
139 }
140}
141
142template <typename T> inline std::string toStringOne(const T &value) {
143 std::string output;
144 Appender(output).append(value);
145 return output;
146}
147
148void dumpSymbolTableWalk(mlir::Operation *symbolTableOp);
149
150void dumpSymbolTable(llvm::raw_ostream &stream, mlir::SymbolTable &symTab, unsigned indent = 0);
151
152void dumpSymbolTable(mlir::SymbolTable &symTab);
153
154void dumpSymbolTables(llvm::raw_ostream &stream, mlir::SymbolTableCollection &tables);
155
156void dumpSymbolTables(mlir::SymbolTableCollection &tables);
157
158void dumpToFile(mlir::Operation *op, llvm::StringRef filename);
159
160} // namespace debug
161} // namespace llzk
std::string toStringOne(const T &value)
Definition Debug.h:142
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:121
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
mlir::raw_ostream & operator<<(mlir::raw_ostream &os, const ConstrainRef &rhs)