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