1*ac91e673SRiver Riddle //===- TestSymbolUses.cpp - Pass to test symbol uselists ------------------===//
2*ac91e673SRiver Riddle //
3*ac91e673SRiver Riddle // Copyright 2019 The MLIR Authors.
4*ac91e673SRiver Riddle //
5*ac91e673SRiver Riddle // Licensed under the Apache License, Version 2.0 (the "License");
6*ac91e673SRiver Riddle // you may not use this file except in compliance with the License.
7*ac91e673SRiver Riddle // You may obtain a copy of the License at
8*ac91e673SRiver Riddle //
9*ac91e673SRiver Riddle //   http://www.apache.org/licenses/LICENSE-2.0
10*ac91e673SRiver Riddle //
11*ac91e673SRiver Riddle // Unless required by applicable law or agreed to in writing, software
12*ac91e673SRiver Riddle // distributed under the License is distributed on an "AS IS" BASIS,
13*ac91e673SRiver Riddle // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*ac91e673SRiver Riddle // See the License for the specific language governing permissions and
15*ac91e673SRiver Riddle // limitations under the License.
16*ac91e673SRiver Riddle // =============================================================================
17*ac91e673SRiver Riddle 
18*ac91e673SRiver Riddle #include "mlir/IR/Function.h"
19*ac91e673SRiver Riddle #include "mlir/Pass/Pass.h"
20*ac91e673SRiver Riddle 
21*ac91e673SRiver Riddle using namespace mlir;
22*ac91e673SRiver Riddle 
23*ac91e673SRiver Riddle namespace {
24*ac91e673SRiver Riddle /// This is a symbol test pass that tests the symbol uselist functionality
25*ac91e673SRiver Riddle /// provided by the symbol table.
26*ac91e673SRiver Riddle struct SymbolUsesPass : public ModulePass<SymbolUsesPass> {
27*ac91e673SRiver Riddle   void runOnModule() override {
28*ac91e673SRiver Riddle     auto module = getModule();
29*ac91e673SRiver Riddle 
30*ac91e673SRiver Riddle     for (FuncOp func : module.getOps<FuncOp>()) {
31*ac91e673SRiver Riddle       // Test computing uses on a non symboltable op.
32*ac91e673SRiver Riddle       unsigned numUses = 0;
33*ac91e673SRiver Riddle       SymbolTable::walkSymbolUses(func, [&](SymbolTable::SymbolUse) {
34*ac91e673SRiver Riddle         ++numUses;
35*ac91e673SRiver Riddle         return WalkResult::advance();
36*ac91e673SRiver Riddle       });
37*ac91e673SRiver Riddle       if (numUses != 0)
38*ac91e673SRiver Riddle         func.emitRemark() << "function contains " << numUses
39*ac91e673SRiver Riddle                           << " nested references";
40*ac91e673SRiver Riddle 
41*ac91e673SRiver Riddle       // Test the functionality of symbol_use_empty.
42*ac91e673SRiver Riddle       if (SymbolTable::symbol_use_empty(func.getName(), module)) {
43*ac91e673SRiver Riddle         func.emitRemark() << "function has no uses";
44*ac91e673SRiver Riddle         continue;
45*ac91e673SRiver Riddle       }
46*ac91e673SRiver Riddle 
47*ac91e673SRiver Riddle       // Test the functionality of walkSymbolUses.
48*ac91e673SRiver Riddle       numUses = 0;
49*ac91e673SRiver Riddle       SymbolTable::walkSymbolUses(
50*ac91e673SRiver Riddle           func.getName(), module, [&](SymbolTable::SymbolUse symbolUse) {
51*ac91e673SRiver Riddle             symbolUse.getUser()->emitRemark()
52*ac91e673SRiver Riddle                 << "found use of function : " << symbolUse.getSymbolRef();
53*ac91e673SRiver Riddle             ++numUses;
54*ac91e673SRiver Riddle             return WalkResult::advance();
55*ac91e673SRiver Riddle           });
56*ac91e673SRiver Riddle       func.emitRemark() << "function has " << numUses << " uses";
57*ac91e673SRiver Riddle     }
58*ac91e673SRiver Riddle   }
59*ac91e673SRiver Riddle };
60*ac91e673SRiver Riddle } // end anonymous namespace
61*ac91e673SRiver Riddle 
62*ac91e673SRiver Riddle static PassRegistration<SymbolUsesPass> pass("test-symbol-uses",
63*ac91e673SRiver Riddle                                              "Test detection of symbol uses");
64