[lldb] Add ability to hide the root name of a value
[llvm-project.git] / flang / lib / Optimizer / Transforms / ExternalNameConversion.cpp
blob47b2b0f85d2367db0005f2999fc6f91af3de3fdb
1 //===- ExternalNameConversion.cpp -- convert name with external convention ===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "flang/Optimizer/Dialect/FIRDialect.h"
10 #include "flang/Optimizer/Dialect/FIROps.h"
11 #include "flang/Optimizer/Support/InternalNames.h"
12 #include "flang/Optimizer/Transforms/Passes.h"
13 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
14 #include "mlir/Dialect/OpenACC/OpenACC.h"
15 #include "mlir/Dialect/OpenMP/OpenMPDialect.h"
16 #include "mlir/IR/SymbolTable.h"
17 #include "mlir/Pass/Pass.h"
18 #include "mlir/Transforms/DialectConversion.h"
20 namespace fir {
21 #define GEN_PASS_DEF_EXTERNALNAMECONVERSION
22 #include "flang/Optimizer/Transforms/Passes.h.inc"
23 } // namespace fir
25 using namespace mlir;
27 //===----------------------------------------------------------------------===//
28 // Helper functions
29 //===----------------------------------------------------------------------===//
31 /// Mangle the name with gfortran convention.
32 std::string
33 mangleExternalName(const std::pair<fir::NameUniquer::NameKind,
34 fir::NameUniquer::DeconstructedName>
35 result,
36 bool appendUnderscore) {
37 if (result.first == fir::NameUniquer::NameKind::COMMON &&
38 result.second.name.empty())
39 return "__BLNK__";
41 if (appendUnderscore)
42 return result.second.name + "_";
44 return result.second.name;
47 //===----------------------------------------------------------------------===//
48 // Rewrite patterns
49 //===----------------------------------------------------------------------===//
51 namespace {
53 struct MangleNameOnFuncOp : public mlir::OpRewritePattern<mlir::func::FuncOp> {
54 public:
55 using OpRewritePattern::OpRewritePattern;
57 MangleNameOnFuncOp(mlir::MLIRContext *ctx, bool appendUnderscore)
58 : mlir::OpRewritePattern<mlir::func::FuncOp>(ctx),
59 appendUnderscore(appendUnderscore) {}
61 mlir::LogicalResult
62 matchAndRewrite(mlir::func::FuncOp op,
63 mlir::PatternRewriter &rewriter) const override {
64 mlir::LogicalResult ret = success();
65 rewriter.startRootUpdate(op);
66 auto result = fir::NameUniquer::deconstruct(op.getSymName());
67 if (fir::NameUniquer::isExternalFacingUniquedName(result)) {
68 auto newSymbol =
69 rewriter.getStringAttr(mangleExternalName(result, appendUnderscore));
71 // Try to update all SymbolRef's in the module that match the current op
72 if (mlir::ModuleOp mod = op->getParentOfType<mlir::ModuleOp>())
73 ret = op.replaceAllSymbolUses(newSymbol, mod);
75 op.setSymNameAttr(newSymbol);
76 mlir::SymbolTable::setSymbolName(op, newSymbol);
79 rewriter.finalizeRootUpdate(op);
80 return ret;
83 private:
84 bool appendUnderscore;
87 struct MangleNameForCommonBlock : public mlir::OpRewritePattern<fir::GlobalOp> {
88 public:
89 using OpRewritePattern::OpRewritePattern;
91 MangleNameForCommonBlock(mlir::MLIRContext *ctx, bool appendUnderscore)
92 : mlir::OpRewritePattern<fir::GlobalOp>(ctx),
93 appendUnderscore(appendUnderscore) {}
95 mlir::LogicalResult
96 matchAndRewrite(fir::GlobalOp op,
97 mlir::PatternRewriter &rewriter) const override {
98 rewriter.startRootUpdate(op);
99 auto result = fir::NameUniquer::deconstruct(
100 op.getSymref().getRootReference().getValue());
101 if (fir::NameUniquer::isExternalFacingUniquedName(result)) {
102 auto newName = mangleExternalName(result, appendUnderscore);
103 op.setSymrefAttr(mlir::SymbolRefAttr::get(op.getContext(), newName));
104 SymbolTable::setSymbolName(op, newName);
106 rewriter.finalizeRootUpdate(op);
107 return success();
110 private:
111 bool appendUnderscore;
114 struct MangleNameOnAddrOfOp : public mlir::OpRewritePattern<fir::AddrOfOp> {
115 public:
116 using OpRewritePattern::OpRewritePattern;
118 MangleNameOnAddrOfOp(mlir::MLIRContext *ctx, bool appendUnderscore)
119 : mlir::OpRewritePattern<fir::AddrOfOp>(ctx),
120 appendUnderscore(appendUnderscore) {}
122 mlir::LogicalResult
123 matchAndRewrite(fir::AddrOfOp op,
124 mlir::PatternRewriter &rewriter) const override {
125 auto result = fir::NameUniquer::deconstruct(
126 op.getSymbol().getRootReference().getValue());
127 if (fir::NameUniquer::isExternalFacingUniquedName(result)) {
128 auto newName = SymbolRefAttr::get(
129 op.getContext(), mangleExternalName(result, appendUnderscore));
130 rewriter.replaceOpWithNewOp<fir::AddrOfOp>(op, op.getResTy().getType(),
131 newName);
133 return success();
136 private:
137 bool appendUnderscore;
140 class ExternalNameConversionPass
141 : public fir::impl::ExternalNameConversionBase<ExternalNameConversionPass> {
142 public:
143 ExternalNameConversionPass(bool appendUnderscoring)
144 : appendUnderscores(appendUnderscoring) {}
146 ExternalNameConversionPass() { appendUnderscores = appendUnderscore; }
148 mlir::ModuleOp getModule() { return getOperation(); }
149 void runOnOperation() override;
151 private:
152 bool appendUnderscores;
154 } // namespace
156 void ExternalNameConversionPass::runOnOperation() {
157 auto op = getOperation();
158 auto *context = &getContext();
160 mlir::RewritePatternSet patterns(context);
161 patterns.insert<MangleNameOnFuncOp, MangleNameForCommonBlock,
162 MangleNameOnAddrOfOp>(context, appendUnderscore);
164 ConversionTarget target(*context);
165 target.addLegalDialect<fir::FIROpsDialect, LLVM::LLVMDialect,
166 acc::OpenACCDialect, omp::OpenMPDialect>();
168 target.addDynamicallyLegalOp<mlir::func::FuncOp>([](mlir::func::FuncOp op) {
169 return !fir::NameUniquer::needExternalNameMangling(op.getSymName());
172 target.addDynamicallyLegalOp<fir::GlobalOp>([](fir::GlobalOp op) {
173 return !fir::NameUniquer::needExternalNameMangling(
174 op.getSymref().getRootReference().getValue());
177 target.addDynamicallyLegalOp<fir::AddrOfOp>([](fir::AddrOfOp op) {
178 return !fir::NameUniquer::needExternalNameMangling(
179 op.getSymbol().getRootReference().getValue());
182 if (failed(applyPartialConversion(op, target, std::move(patterns))))
183 signalPassFailure();
186 std::unique_ptr<mlir::Pass> fir::createExternalNameConversionPass() {
187 return std::make_unique<ExternalNameConversionPass>();
190 std::unique_ptr<mlir::Pass>
191 fir::createExternalNameConversionPass(bool appendUnderscoring) {
192 return std::make_unique<ExternalNameConversionPass>(appendUnderscoring);