1927b7074SRiver Riddle //===- SymbolTable.cpp - MLIR Symbol Table Class --------------------------===// 2927b7074SRiver Riddle // 3927b7074SRiver Riddle // Copyright 2019 The MLIR Authors. 4927b7074SRiver Riddle // 5927b7074SRiver Riddle // Licensed under the Apache License, Version 2.0 (the "License"); 6927b7074SRiver Riddle // you may not use this file except in compliance with the License. 7927b7074SRiver Riddle // You may obtain a copy of the License at 8927b7074SRiver Riddle // 9927b7074SRiver Riddle // http://www.apache.org/licenses/LICENSE-2.0 10927b7074SRiver Riddle // 11927b7074SRiver Riddle // Unless required by applicable law or agreed to in writing, software 12927b7074SRiver Riddle // distributed under the License is distributed on an "AS IS" BASIS, 13927b7074SRiver Riddle // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14927b7074SRiver Riddle // See the License for the specific language governing permissions and 15927b7074SRiver Riddle // limitations under the License. 16927b7074SRiver Riddle // ============================================================================= 17927b7074SRiver Riddle 18927b7074SRiver Riddle #include "mlir/IR/SymbolTable.h" 198c47e2edSRiver Riddle #include "mlir/IR/Module.h" 20927b7074SRiver Riddle 21927b7074SRiver Riddle using namespace mlir; 22927b7074SRiver Riddle 238c47e2edSRiver Riddle /// Build a symbol table with the symbols within the given module. 248c47e2edSRiver Riddle SymbolTable::SymbolTable(Module *module) : context(module->getContext()) { 25*54cd6a7eSRiver Riddle for (auto func : *module) { 26*54cd6a7eSRiver Riddle auto inserted = symbolTable.insert({func.getName(), func}); 278c47e2edSRiver Riddle (void)inserted; 288c47e2edSRiver Riddle assert(inserted.second && 298c47e2edSRiver Riddle "expected module to contain uniquely named functions"); 308c47e2edSRiver Riddle } 318c47e2edSRiver Riddle } 328c47e2edSRiver Riddle 33927b7074SRiver Riddle /// Look up a symbol with the specified name, returning null if no such name 34927b7074SRiver Riddle /// exists. Names never include the @ on them. 35*54cd6a7eSRiver Riddle Function SymbolTable::lookup(StringRef name) const { 36927b7074SRiver Riddle return lookup(Identifier::get(name, context)); 37927b7074SRiver Riddle } 38927b7074SRiver Riddle 39927b7074SRiver Riddle /// Look up a symbol with the specified name, returning null if no such name 40927b7074SRiver Riddle /// exists. Names never include the @ on them. 41*54cd6a7eSRiver Riddle Function SymbolTable::lookup(Identifier name) const { 42927b7074SRiver Riddle return symbolTable.lookup(name); 43927b7074SRiver Riddle } 44927b7074SRiver Riddle 45927b7074SRiver Riddle /// Erase the given symbol from the table. 46*54cd6a7eSRiver Riddle void SymbolTable::erase(Function symbol) { 47*54cd6a7eSRiver Riddle auto it = symbolTable.find(symbol.getName()); 48927b7074SRiver Riddle if (it != symbolTable.end() && it->second == symbol) 49927b7074SRiver Riddle symbolTable.erase(it); 50927b7074SRiver Riddle } 51927b7074SRiver Riddle 52927b7074SRiver Riddle /// Insert a new symbol into the table, and rename it as necessary to avoid 53927b7074SRiver Riddle /// collisions. 54*54cd6a7eSRiver Riddle void SymbolTable::insert(Function symbol) { 55927b7074SRiver Riddle // Add this symbol to the symbol table, uniquing the name if a conflict is 56927b7074SRiver Riddle // detected. 57*54cd6a7eSRiver Riddle if (symbolTable.insert({symbol.getName(), symbol}).second) 58927b7074SRiver Riddle return; 59927b7074SRiver Riddle 60927b7074SRiver Riddle // If a conflict was detected, then the function will not have been added to 61927b7074SRiver Riddle // the symbol table. Try suffixes until we get to a unique name that works. 62*54cd6a7eSRiver Riddle SmallString<128> nameBuffer(symbol.getName()); 63927b7074SRiver Riddle unsigned originalLength = nameBuffer.size(); 64927b7074SRiver Riddle 65927b7074SRiver Riddle // Iteratively try suffixes until we find one that isn't used. We use a 66927b7074SRiver Riddle // module level uniquing counter to avoid N^2 behavior. 67927b7074SRiver Riddle do { 68927b7074SRiver Riddle nameBuffer.resize(originalLength); 69927b7074SRiver Riddle nameBuffer += '_'; 70927b7074SRiver Riddle nameBuffer += std::to_string(uniquingCounter++); 71*54cd6a7eSRiver Riddle symbol.setName(Identifier::get(nameBuffer, context)); 72*54cd6a7eSRiver Riddle } while (!symbolTable.insert({symbol.getName(), symbol}).second); 73927b7074SRiver Riddle } 74