LLZK 3.0.0
An open-source IR for Zero Knowledge (ZK) circuits
Loading...
Searching...
No Matches
CallGraphPasses.cpp
Go to the documentation of this file.
1//===-- CallGraphPasses.cpp -------------------------------------*- 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// The contents of this file are adapted from llvm/lib/Analysis/CallGraph.cpp
9// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
10// See https://llvm.org/LICENSE.txt for license information.
11// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
12//
13//===----------------------------------------------------------------------===//
19//===----------------------------------------------------------------------===//
20
25
26#include <llvm/ADT/SmallVector.h>
27#include <llvm/Support/ErrorHandling.h>
28
29namespace llzk {
30#define GEN_PASS_DEF_CALLGRAPHPRINTERPASS
31#define GEN_PASS_DEF_CALLGRAPHSCCSPRINTERPASS
33} // namespace llzk
34
35namespace {
36
37class PassImpl : public llzk::impl::CallGraphPrinterPassBase<PassImpl> {
38 using Base = CallGraphPrinterPassBase<PassImpl>;
40
41 void runOnOperation() override {
42 markAllAnalysesPreserved();
44 auto &cga = getAnalysis<llzk::CallGraphAnalysis>();
45 cga.getCallGraph().print(llzk::toStream(outputStream));
46 }
47};
49class SCCPassImpl : public llzk::impl::CallGraphSCCsPrinterPassBase<SCCPassImpl> {
52
53 void runOnOperation() override {
54 markAllAnalysesPreserved();
55
57 auto &CG = getAnalysis<llzk::CallGraphAnalysis>();
58 unsigned sccNum = 0;
59 os << "SCCs for the program in PostOrder:";
60 for (auto SCCI = llvm::scc_begin<const llzk::CallGraph *>(&CG.getCallGraph()); !SCCI.isAtEnd();
61 ++SCCI) {
62 const std::vector<const llzk::CallGraphNode *> &nextSCC = *SCCI;
63 os << "\nSCC #" << ++sccNum << ": ";
64 bool First = true;
65 for (const llzk::CallGraphNode *CGN : nextSCC) {
66 if (First) {
67 First = false;
68 } else {
69 os << ", ";
70 }
71 if (CGN->isExternal()) {
72 os << "external node";
73 } else {
74 mlir::CallableOpInterface calledFn = CGN->getCalledFunction();
75 auto calledSym = llvm::dyn_cast<mlir::SymbolOpInterface>(calledFn.getOperation());
76 assert(calledSym && "call graph nodes must refer to callable symbols");
77 os << llzk::getFullyQualifiedName(calledSym);
78 }
79 }
80
81 if (nextSCC.size() == 1 && SCCI.hasCycle()) {
82 os << " (Has self-loop).";
83 }
84 }
85 os << '\n';
86 }
87};
88
89} // namespace
This is a simple port of the mlir::CallGraphNode with llzk::CallGraph as a friend class,...
Definition CallGraph.h:36
::mlir::Pass::Option<::llzk::OutputStream > outputStream
llvm::raw_ostream & toStream(OutputStream val)
mlir::SymbolRefAttr getFullyQualifiedName(mlir::SymbolOpInterface symbol, bool requireParent=true)
Return the full name for this symbol from the root module, including any surrounding symbol table nam...