CIRCT  20.0.0git
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 
18 namespace circt {
19 #define GEN_PASS_DEF_PRINTOPCOUNT
20 #include "circt/Transforms/Passes.h.inc"
21 } // namespace circt
22 
23 using namespace mlir;
24 using namespace circt;
25 
26 namespace {
27 
28 void 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 
55 void 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 
67 struct PrintOpCountPass
68  : public circt::impl::PrintOpCountBase<PrintOpCountPass> {
69 public:
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 
92 namespace circt {
93 // Construct with alternative output stream where desired
94 std::unique_ptr<mlir::Pass> createPrintOpCountPass(llvm::raw_ostream &os) {
95  return std::make_unique<PrintOpCountPass>(os);
96 }
97 
98 // Print to outs by default
99 std::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.
Definition: DebugAnalysis.h:21
std::unique_ptr< mlir::Pass > createPrintOpCountPass(llvm::raw_ostream &os)