1//===- TestPrintDefUse.cpp - Passes to illustrate the IR def-use chains ---===//
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#include "mlir/IR/BuiltinOps.h"
10#include "mlir/Pass/Pass.h"
11
12using namespace mlir;
13
14namespace {
15/// This pass illustrates the IR def-use chains through printing.
16struct TestPrintDefUsePass
17 : public PassWrapper<TestPrintDefUsePass, OperationPass<>> {
18 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestPrintDefUsePass)
19
20 StringRef getArgument() const final { return "test-print-defuse"; }
21 StringRef getDescription() const final { return "Test various printing."; }
22 void runOnOperation() override {
23 // Recursively traverse the IR nested under the current operation and print
24 // every single operation and their operands and users.
25 getOperation()->walk(callback: [](Operation *op) {
26 llvm::outs() << "Visiting op '" << op->getName() << "' with "
27 << op->getNumOperands() << " operands:\n";
28
29 // Print information about the producer of each of the operands.
30 for (Value operand : op->getOperands()) {
31 if (Operation *producer = operand.getDefiningOp()) {
32 llvm::outs() << " - Operand produced by operation '"
33 << producer->getName() << "'\n";
34 } else {
35 // If there is no defining op, the Value is necessarily a Block
36 // argument.
37 auto blockArg = cast<BlockArgument>(Val&: operand);
38 llvm::outs() << " - Operand produced by Block argument, number "
39 << blockArg.getArgNumber() << "\n";
40 }
41 }
42
43 // Print information about the user of each of the result.
44 llvm::outs() << "Has " << op->getNumResults() << " results:\n";
45 for (const auto &indexedResult : llvm::enumerate(First: op->getResults())) {
46 Value result = indexedResult.value();
47 llvm::outs() << " - Result " << indexedResult.index();
48 if (result.use_empty()) {
49 llvm::outs() << " has no uses\n";
50 continue;
51 }
52 if (result.hasOneUse()) {
53 llvm::outs() << " has a single use: ";
54 } else {
55 llvm::outs() << " has "
56 << std::distance(first: result.getUses().begin(),
57 last: result.getUses().end())
58 << " uses:\n";
59 }
60 for (Operation *userOp : result.getUsers()) {
61 llvm::outs() << " - " << userOp->getName() << "\n";
62 }
63 }
64 });
65 }
66};
67} // namespace
68
69namespace mlir {
70void registerTestPrintDefUsePass() { PassRegistration<TestPrintDefUsePass>(); }
71} // namespace mlir
72

source code of mlir/test/lib/IR/TestPrintDefUse.cpp