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" 19*8c47e2edSRiver Riddle #include "mlir/IR/Module.h" 20927b7074SRiver Riddle 21927b7074SRiver Riddle using namespace mlir; 22927b7074SRiver Riddle 23*8c47e2edSRiver Riddle /// Build a symbol table with the symbols within the given module. 24*8c47e2edSRiver Riddle SymbolTable::SymbolTable(Module *module) : context(module->getContext()) { 25*8c47e2edSRiver Riddle for (auto &func : *module) { 26*8c47e2edSRiver Riddle auto inserted = symbolTable.insert({func.getName(), &func}); 27*8c47e2edSRiver Riddle (void)inserted; 28*8c47e2edSRiver Riddle assert(inserted.second && 29*8c47e2edSRiver Riddle "expected module to contain uniquely named functions"); 30*8c47e2edSRiver Riddle } 31*8c47e2edSRiver Riddle } 32*8c47e2edSRiver 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. 35927b7074SRiver 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. 41927b7074SRiver 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. 46927b7074SRiver Riddle void SymbolTable::erase(Function *symbol) { 47927b7074SRiver 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. 54927b7074SRiver 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. 57927b7074SRiver 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. 62927b7074SRiver 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++); 71927b7074SRiver Riddle symbol->setName(Identifier::get(nameBuffer, context)); 72927b7074SRiver Riddle } while (!symbolTable.insert({symbol->getName(), symbol}).second); 73927b7074SRiver Riddle } 74