1*927b7074SRiver Riddle //===- SymbolTable.cpp - MLIR Symbol Table Class --------------------------===// 2*927b7074SRiver Riddle // 3*927b7074SRiver Riddle // Copyright 2019 The MLIR Authors. 4*927b7074SRiver Riddle // 5*927b7074SRiver Riddle // Licensed under the Apache License, Version 2.0 (the "License"); 6*927b7074SRiver Riddle // you may not use this file except in compliance with the License. 7*927b7074SRiver Riddle // You may obtain a copy of the License at 8*927b7074SRiver Riddle // 9*927b7074SRiver Riddle // http://www.apache.org/licenses/LICENSE-2.0 10*927b7074SRiver Riddle // 11*927b7074SRiver Riddle // Unless required by applicable law or agreed to in writing, software 12*927b7074SRiver Riddle // distributed under the License is distributed on an "AS IS" BASIS, 13*927b7074SRiver Riddle // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*927b7074SRiver Riddle // See the License for the specific language governing permissions and 15*927b7074SRiver Riddle // limitations under the License. 16*927b7074SRiver Riddle // ============================================================================= 17*927b7074SRiver Riddle 18*927b7074SRiver Riddle #include "mlir/IR/SymbolTable.h" 19*927b7074SRiver Riddle #include "mlir/IR/Function.h" 20*927b7074SRiver Riddle 21*927b7074SRiver Riddle using namespace mlir; 22*927b7074SRiver Riddle 23*927b7074SRiver Riddle /// Look up a symbol with the specified name, returning null if no such name 24*927b7074SRiver Riddle /// exists. Names never include the @ on them. 25*927b7074SRiver Riddle Function *SymbolTable::lookup(StringRef name) const { 26*927b7074SRiver Riddle return lookup(Identifier::get(name, context)); 27*927b7074SRiver Riddle } 28*927b7074SRiver Riddle 29*927b7074SRiver Riddle /// Look up a symbol with the specified name, returning null if no such name 30*927b7074SRiver Riddle /// exists. Names never include the @ on them. 31*927b7074SRiver Riddle Function *SymbolTable::lookup(Identifier name) const { 32*927b7074SRiver Riddle return symbolTable.lookup(name); 33*927b7074SRiver Riddle } 34*927b7074SRiver Riddle 35*927b7074SRiver Riddle /// Erase the given symbol from the table. 36*927b7074SRiver Riddle void SymbolTable::erase(Function *symbol) { 37*927b7074SRiver Riddle auto it = symbolTable.find(symbol->getName()); 38*927b7074SRiver Riddle if (it != symbolTable.end() && it->second == symbol) 39*927b7074SRiver Riddle symbolTable.erase(it); 40*927b7074SRiver Riddle } 41*927b7074SRiver Riddle 42*927b7074SRiver Riddle /// Insert a new symbol into the table, and rename it as necessary to avoid 43*927b7074SRiver Riddle /// collisions. 44*927b7074SRiver Riddle void SymbolTable::insert(Function *symbol) { 45*927b7074SRiver Riddle // Add this symbol to the symbol table, uniquing the name if a conflict is 46*927b7074SRiver Riddle // detected. 47*927b7074SRiver Riddle if (symbolTable.insert({symbol->getName(), symbol}).second) 48*927b7074SRiver Riddle return; 49*927b7074SRiver Riddle 50*927b7074SRiver Riddle // If a conflict was detected, then the function will not have been added to 51*927b7074SRiver Riddle // the symbol table. Try suffixes until we get to a unique name that works. 52*927b7074SRiver Riddle SmallString<128> nameBuffer(symbol->getName()); 53*927b7074SRiver Riddle unsigned originalLength = nameBuffer.size(); 54*927b7074SRiver Riddle 55*927b7074SRiver Riddle // Iteratively try suffixes until we find one that isn't used. We use a 56*927b7074SRiver Riddle // module level uniquing counter to avoid N^2 behavior. 57*927b7074SRiver Riddle do { 58*927b7074SRiver Riddle nameBuffer.resize(originalLength); 59*927b7074SRiver Riddle nameBuffer += '_'; 60*927b7074SRiver Riddle nameBuffer += std::to_string(uniquingCounter++); 61*927b7074SRiver Riddle symbol->setName(Identifier::get(nameBuffer, context)); 62*927b7074SRiver Riddle } while (!symbolTable.insert({symbol->getName(), symbol}).second); 63*927b7074SRiver Riddle } 64