1ac91e673SRiver Riddle //===- TestSymbolUses.cpp - Pass to test symbol uselists ------------------===// 2ac91e673SRiver Riddle // 3ac91e673SRiver Riddle // Copyright 2019 The MLIR Authors. 4ac91e673SRiver Riddle // 5ac91e673SRiver Riddle // Licensed under the Apache License, Version 2.0 (the "License"); 6ac91e673SRiver Riddle // you may not use this file except in compliance with the License. 7ac91e673SRiver Riddle // You may obtain a copy of the License at 8ac91e673SRiver Riddle // 9ac91e673SRiver Riddle // http://www.apache.org/licenses/LICENSE-2.0 10ac91e673SRiver Riddle // 11ac91e673SRiver Riddle // Unless required by applicable law or agreed to in writing, software 12ac91e673SRiver Riddle // distributed under the License is distributed on an "AS IS" BASIS, 13ac91e673SRiver Riddle // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14ac91e673SRiver Riddle // See the License for the specific language governing permissions and 15ac91e673SRiver Riddle // limitations under the License. 16ac91e673SRiver Riddle // ============================================================================= 17ac91e673SRiver Riddle 18ac91e673SRiver Riddle #include "mlir/IR/Function.h" 19ac91e673SRiver Riddle #include "mlir/Pass/Pass.h" 20ac91e673SRiver Riddle 21ac91e673SRiver Riddle using namespace mlir; 22ac91e673SRiver Riddle 23ac91e673SRiver Riddle namespace { 24ac91e673SRiver Riddle /// This is a symbol test pass that tests the symbol uselist functionality 25ac91e673SRiver Riddle /// provided by the symbol table. 26ac91e673SRiver Riddle struct SymbolUsesPass : public ModulePass<SymbolUsesPass> { 27ac91e673SRiver Riddle void runOnModule() override { 28ac91e673SRiver Riddle auto module = getModule(); 29ac91e673SRiver Riddle 30ac91e673SRiver Riddle for (FuncOp func : module.getOps<FuncOp>()) { 31ac91e673SRiver Riddle // Test computing uses on a non symboltable op. 32b3a6ae83SRiver Riddle Optional<SymbolTable::UseRange> symbolUses = 33b3a6ae83SRiver Riddle SymbolTable::getSymbolUses(func); 34b3a6ae83SRiver Riddle 35b3a6ae83SRiver Riddle // Test the conservative failure case. 36b3a6ae83SRiver Riddle if (!symbolUses) { 37b3a6ae83SRiver Riddle func.emitRemark() << "function contains an unknown nested operation " 38b3a6ae83SRiver Riddle "that 'may' define a new symbol table"; 39b3a6ae83SRiver Riddle return; 40b3a6ae83SRiver Riddle } 41b3a6ae83SRiver Riddle if (unsigned numUses = llvm::size(*symbolUses)) 42ac91e673SRiver Riddle func.emitRemark() << "function contains " << numUses 43ac91e673SRiver Riddle << " nested references"; 44ac91e673SRiver Riddle 45b3a6ae83SRiver Riddle // Test the functionality of symbolKnownUseEmpty. 469ac459e8SRiver Riddle if (func.symbolKnownUseEmpty(module)) { 47ac91e673SRiver Riddle func.emitRemark() << "function has no uses"; 48ac91e673SRiver Riddle continue; 49ac91e673SRiver Riddle } 50ac91e673SRiver Riddle 51b3a6ae83SRiver Riddle // Test the functionality of getSymbolUses. 529ac459e8SRiver Riddle symbolUses = func.getSymbolUses(module); 53b3a6ae83SRiver Riddle assert(symbolUses.hasValue() && "expected no unknown operations"); 54b3a6ae83SRiver Riddle for (SymbolTable::SymbolUse symbolUse : *symbolUses) { 55ac91e673SRiver Riddle symbolUse.getUser()->emitRemark() 56ac91e673SRiver Riddle << "found use of function : " << symbolUse.getSymbolRef(); 57b3a6ae83SRiver Riddle } 58b3a6ae83SRiver Riddle func.emitRemark() << "function has " << llvm::size(*symbolUses) 59b3a6ae83SRiver Riddle << " uses"; 60ac91e673SRiver Riddle } 61ac91e673SRiver Riddle } 62ac91e673SRiver Riddle }; 63*ef43b565SRiver Riddle 64*ef43b565SRiver Riddle /// This is a symbol test pass that tests the symbol use replacement 65*ef43b565SRiver Riddle /// functionality provided by the symbol table. 66*ef43b565SRiver Riddle struct SymbolReplacementPass : public ModulePass<SymbolReplacementPass> { 67*ef43b565SRiver Riddle void runOnModule() override { 68*ef43b565SRiver Riddle auto module = getModule(); 69*ef43b565SRiver Riddle 70*ef43b565SRiver Riddle for (FuncOp func : module.getOps<FuncOp>()) { 71*ef43b565SRiver Riddle StringAttr newName = func.getAttrOfType<StringAttr>("sym.new_name"); 72*ef43b565SRiver Riddle if (!newName) 73*ef43b565SRiver Riddle continue; 74*ef43b565SRiver Riddle if (succeeded(func.replaceAllSymbolUses(newName.getValue(), module))) 75*ef43b565SRiver Riddle func.setName(newName.getValue()); 76*ef43b565SRiver Riddle } 77*ef43b565SRiver Riddle } 78*ef43b565SRiver Riddle }; 79ac91e673SRiver Riddle } // end anonymous namespace 80ac91e673SRiver Riddle 81ac91e673SRiver Riddle static PassRegistration<SymbolUsesPass> pass("test-symbol-uses", 82ac91e673SRiver Riddle "Test detection of symbol uses"); 83*ef43b565SRiver Riddle 84*ef43b565SRiver Riddle static PassRegistration<SymbolReplacementPass> 85*ef43b565SRiver Riddle rauwPass("test-symbol-rauw", "Test replacement of symbol uses"); 86