CIRCT 20.0.0git
Loading...
Searching...
No Matches
PrintOpCount.cpp
Go to the documentation of this file.
1//===- PrintOpCount.cpp - Operation Count Emission Pass ---------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Contains a pass to emit operation count results
10//
11//===----------------------------------------------------------------------===//
12
15#include "mlir/Pass/Pass.h"
16#include "llvm/Support/JSON.h"
17
18namespace circt {
19#define GEN_PASS_DEF_PRINTOPCOUNT
20#include "circt/Transforms/Passes.h.inc"
21} // namespace circt
22
23using namespace mlir;
24using namespace circt;
25
26namespace {
27
28void printOpAndOperandCounts(analysis::OpCountAnalysis &opCount,
29 raw_ostream &os, bool sorted = false) {
30 auto opNames = opCount.getFoundOpNames();
31 // Sort to account for non-deterministic DenseMap ordering
32 if (sorted)
33 llvm::sort(opNames, [](OperationName name1, OperationName name2) {
34 return name1.getStringRef() < name2.getStringRef();
35 });
36 for (auto opName : opNames) {
37 os << "- name: " << opName << "\n";
38 os << " count: " << opCount.getOpCount(opName) << "\n";
39 auto operandMap = opCount.getOperandCountMap(opName);
40 if (operandMap.size() <= 1)
41 continue;
42 llvm::SmallVector<size_t> keys;
43 for (auto pair : operandMap)
44 keys.push_back(pair.first);
45 // Sort for determinism if required again
46 if (sorted)
47 llvm::sort(keys);
48 for (auto num : keys) {
49 os << " - operands: " << num << "\n";
50 os << " count: " << operandMap[num] << "\n";
51 }
52 }
53}
54
55void printOpAndOperandJSON(analysis::OpCountAnalysis &opCount,
56 raw_ostream &os) {
57 auto jos = llvm::json::OStream(os);
58 jos.object([&] {
59 for (auto opName : opCount.getFoundOpNames())
60 jos.attributeObject(opName.getStringRef(), [&] {
61 for (auto pair : opCount.getOperandCountMap(opName))
62 jos.attribute(std::to_string(pair.first), pair.second);
63 });
64 });
65}
66
67struct PrintOpCountPass
68 : public circt::impl::PrintOpCountBase<PrintOpCountPass> {
69public:
70 PrintOpCountPass(raw_ostream &os) : os(os) {}
71
72 void runOnOperation() override {
73 auto &opCount = getAnalysis<circt::analysis::OpCountAnalysis>();
74 switch (emissionFormat) {
75 case OpCountEmissionFormat::Readable:
76 printOpAndOperandCounts(opCount, os);
77 break;
78 case OpCountEmissionFormat::ReadableSorted:
79 printOpAndOperandCounts(opCount, os, /*sorted=*/true);
80 break;
81 case OpCountEmissionFormat::JSON:
82 printOpAndOperandJSON(opCount, os);
83 break;
84 }
85 }
86 /// Output stream for emission
87 raw_ostream &os;
88};
89
90} // namespace
91
92namespace circt {
93// Construct with alternative output stream where desired
94std::unique_ptr<mlir::Pass> createPrintOpCountPass(llvm::raw_ostream &os) {
95 return std::make_unique<PrintOpCountPass>(os);
96}
97
98// Print to outs by default
99std::unique_ptr<mlir::Pass> createPrintOpCountPass() {
100 return std::make_unique<PrintOpCountPass>(llvm::outs());
101}
102} // namespace circt
size_t getOpCount(OperationName opName)
Get the frequency of operations of a specific name.
DenseMap< size_t, size_t > getOperandCountMap(OperationName opName)
Get a map from number of operands to corresponding frequency for the given operation.
SmallVector< OperationName > getFoundOpNames()
Get the names of all distinct operations found by the analysis.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
std::unique_ptr< mlir::Pass > createPrintOpCountPass()