diff --git a/flang/lib/Optimizer/Transforms/ExternalNameConversion.cpp b/flang/lib/Optimizer/Transforms/ExternalNameConversion.cpp index 3a9686418c2ea..b265c74c33dd5 100644 --- a/flang/lib/Optimizer/Transforms/ExternalNameConversion.cpp +++ b/flang/lib/Optimizer/Transforms/ExternalNameConversion.cpp @@ -12,13 +12,9 @@ #include "flang/Optimizer/Dialect/FIROpsSupport.h" #include "flang/Optimizer/Support/InternalNames.h" #include "flang/Optimizer/Transforms/Passes.h" -#include "mlir/Dialect/LLVMIR/LLVMDialect.h" -#include "mlir/Dialect/OpenACC/OpenACC.h" -#include "mlir/Dialect/OpenMP/OpenMPDialect.h" #include "mlir/IR/Attributes.h" #include "mlir/IR/SymbolTable.h" #include "mlir/Pass/Pass.h" -#include "mlir/Transforms/DialectConversion.h" namespace fir { #define GEN_PASS_DEF_EXTERNALNAMECONVERSION @@ -44,102 +40,8 @@ mangleExternalName(const std::pair { -public: - using OpRewritePattern::OpRewritePattern; - - MangleNameOnFuncOp(mlir::MLIRContext *ctx, bool appendUnderscore) - : mlir::OpRewritePattern(ctx), - appendUnderscore(appendUnderscore) {} - - mlir::LogicalResult - matchAndRewrite(mlir::func::FuncOp op, - mlir::PatternRewriter &rewriter) const override { - mlir::LogicalResult ret = success(); - rewriter.startOpModification(op); - llvm::StringRef oldName = op.getSymName(); - auto result = fir::NameUniquer::deconstruct(oldName); - if (fir::NameUniquer::isExternalFacingUniquedName(result)) { - auto newSymbol = - rewriter.getStringAttr(mangleExternalName(result, appendUnderscore)); - - // Try to update all SymbolRef's in the module that match the current op - if (mlir::ModuleOp mod = op->getParentOfType()) - ret = op.replaceAllSymbolUses(newSymbol, mod); - - op.setSymNameAttr(newSymbol); - mlir::SymbolTable::setSymbolName(op, newSymbol); - - op->setAttr(fir::getInternalFuncNameAttrName(), - mlir::StringAttr::get(op->getContext(), oldName)); - } - rewriter.finalizeOpModification(op); - return ret; - } - -private: - bool appendUnderscore; -}; - -struct MangleNameForCommonBlock : public mlir::OpRewritePattern { -public: - using OpRewritePattern::OpRewritePattern; - - MangleNameForCommonBlock(mlir::MLIRContext *ctx, bool appendUnderscore) - : mlir::OpRewritePattern(ctx), - appendUnderscore(appendUnderscore) {} - - mlir::LogicalResult - matchAndRewrite(fir::GlobalOp op, - mlir::PatternRewriter &rewriter) const override { - rewriter.startOpModification(op); - auto result = fir::NameUniquer::deconstruct( - op.getSymref().getRootReference().getValue()); - if (fir::NameUniquer::isExternalFacingUniquedName(result)) { - auto newName = mangleExternalName(result, appendUnderscore); - op.setSymrefAttr(mlir::SymbolRefAttr::get(op.getContext(), newName)); - SymbolTable::setSymbolName(op, newName); - } - rewriter.finalizeOpModification(op); - return success(); - } - -private: - bool appendUnderscore; -}; - -struct MangleNameOnAddrOfOp : public mlir::OpRewritePattern { -public: - using OpRewritePattern::OpRewritePattern; - - MangleNameOnAddrOfOp(mlir::MLIRContext *ctx, bool appendUnderscore) - : mlir::OpRewritePattern(ctx), - appendUnderscore(appendUnderscore) {} - - mlir::LogicalResult - matchAndRewrite(fir::AddrOfOp op, - mlir::PatternRewriter &rewriter) const override { - auto result = fir::NameUniquer::deconstruct( - op.getSymbol().getRootReference().getValue()); - if (fir::NameUniquer::isExternalFacingUniquedName(result)) { - auto newName = SymbolRefAttr::get( - op.getContext(), mangleExternalName(result, appendUnderscore)); - rewriter.replaceOpWithNewOp(op, op.getResTy().getType(), - newName); - } - return success(); - } - -private: - bool appendUnderscore; -}; - class ExternalNameConversionPass : public fir::impl::ExternalNameConversionBase { public: @@ -162,31 +64,42 @@ void ExternalNameConversionPass::runOnOperation() { auto *context = &getContext(); appendUnderscores = (usePassOpt) ? appendUnderscoreOpt : appendUnderscores; + llvm::DenseMap remappings; + // Update names of external Fortran functions and names of Common Block + // globals. + for (auto &funcOrGlobal : op->getRegion(0).front()) { + if (llvm::isa(funcOrGlobal) || + llvm::isa(funcOrGlobal)) { + auto symName = funcOrGlobal.getAttrOfType( + mlir::SymbolTable::getSymbolAttrName()); + auto deconstructedName = fir::NameUniquer::deconstruct(symName); + if (fir::NameUniquer::isExternalFacingUniquedName(deconstructedName)) { + auto newName = mangleExternalName(deconstructedName, appendUnderscores); + auto newAttr = mlir::StringAttr::get(context, newName); + mlir::SymbolTable::setSymbolName(&funcOrGlobal, newAttr); + auto newSymRef = mlir::FlatSymbolRefAttr::get(newAttr); + remappings.try_emplace(symName, newSymRef); + if (llvm::isa(funcOrGlobal)) + funcOrGlobal.setAttr(fir::getInternalFuncNameAttrName(), symName); + } + } + } - mlir::RewritePatternSet patterns(context); - patterns.insert(context, appendUnderscores); - - ConversionTarget target(*context); - target.addLegalDialect(); - - target.addDynamicallyLegalOp([](mlir::func::FuncOp op) { - return !fir::NameUniquer::needExternalNameMangling(op.getSymName()); - }); - - target.addDynamicallyLegalOp([](fir::GlobalOp op) { - return !fir::NameUniquer::needExternalNameMangling( - op.getSymref().getRootReference().getValue()); - }); - - target.addDynamicallyLegalOp([](fir::AddrOfOp op) { - return !fir::NameUniquer::needExternalNameMangling( - op.getSymbol().getRootReference().getValue()); + if (remappings.empty()) + return; + + // Update all uses of the functions and globals that have been renamed. + op.walk([&remappings](mlir::Operation *nestedOp) { + llvm::SmallVector> updates; + for (const mlir::NamedAttribute &attr : nestedOp->getAttrDictionary()) + if (auto symRef = llvm::dyn_cast(attr.getValue())) + if (auto remap = remappings.find(symRef.getRootReference()); + remap != remappings.end()) + updates.emplace_back(std::pair{ + attr.getName(), mlir::SymbolRefAttr(remap->second)}); + for (auto update : updates) + nestedOp->setAttr(update.first, update.second); }); - - if (failed(applyPartialConversion(op, target, std::move(patterns)))) - signalPassFailure(); } std::unique_ptr fir::createExternalNameConversionPass() {