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
+ // ===----------------------------------------------------------------------===//
8
+
9
+ #include " PassDetail.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/Pass/Pass.h"
17
+ #include " mlir/Transforms/DialectConversion.h"
18
+
19
+ // ===----------------------------------------------------------------------===//
20
+ // Helper functions
21
+ // ===----------------------------------------------------------------------===//
22
+
23
+ // / Mangle the name with gfortran convention.
24
+ std::string
25
+ mangleExternalName (const std::pair<fir::NameUniquer::NameKind,
26
+ fir::NameUniquer::DeconstructedName>
27
+ result) {
28
+ if (result.first == fir::NameUniquer::NameKind::COMMON &&
29
+ result.second .name .empty ())
30
+ return " __BLNK__" ;
31
+ return result.second .name + " _" ;
32
+ }
33
+
34
+ // ===----------------------------------------------------------------------===//
35
+ // Rewrite patterns
36
+ // ===----------------------------------------------------------------------===//
37
+
38
+ namespace {
39
+
40
+ class MangleNameOnCallOp : public mlir ::OpRewritePattern<fir::CallOp> {
41
+ public:
42
+ using OpRewritePattern::OpRewritePattern;
43
+
44
+ mlir::LogicalResult
45
+ matchAndRewrite (fir::CallOp op,
46
+ mlir::PatternRewriter &rewriter) const override {
47
+ rewriter.startRootUpdate (op);
48
+ auto callee = op.callee ();
49
+ if (callee.hasValue ()) {
50
+ auto result =
51
+ fir::NameUniquer::deconstruct (callee.getValue ().getRootReference ());
52
+ if (fir::NameUniquer::isExternalFacingUniquedName (result))
53
+ op.calleeAttr (
54
+ SymbolRefAttr::get (op.getContext (), mangleExternalName (result)));
55
+ }
56
+ rewriter.finalizeRootUpdate (op);
57
+ return success ();
58
+ }
59
+ };
60
+
61
+ struct MangleNameOnFuncOp : public mlir ::OpRewritePattern<mlir::FuncOp> {
62
+ public:
63
+ using OpRewritePattern::OpRewritePattern;
64
+
65
+ mlir::LogicalResult
66
+ matchAndRewrite (mlir::FuncOp op,
67
+ mlir::PatternRewriter &rewriter) const override {
68
+ rewriter.startRootUpdate (op);
69
+ auto result = fir::NameUniquer::deconstruct (op.sym_name ());
70
+ if (fir::NameUniquer::isExternalFacingUniquedName (result)) {
71
+ op.sym_nameAttr (rewriter.getStringAttr (mangleExternalName (result)));
72
+ }
73
+ rewriter.finalizeRootUpdate (op);
74
+ return success ();
75
+ }
76
+ };
77
+
78
+ struct MangleNameForCommonBlock : public mlir ::OpRewritePattern<fir::GlobalOp> {
79
+ public:
80
+ using OpRewritePattern::OpRewritePattern;
81
+
82
+ mlir::LogicalResult
83
+ matchAndRewrite (fir::GlobalOp op,
84
+ mlir::PatternRewriter &rewriter) const override {
85
+ rewriter.startRootUpdate (op);
86
+ auto result = fir::NameUniquer::deconstruct (op.symref ().getRootReference ());
87
+ if (fir::NameUniquer::isExternalFacingUniquedName (result))
88
+ op.symrefAttr (mlir::SymbolRefAttr::get (op.getContext (),
89
+ mangleExternalName (result)));
90
+ rewriter.finalizeRootUpdate (op);
91
+ return success ();
92
+ }
93
+ };
94
+
95
+ struct MangleNameOnAddrOfOp : public mlir ::OpRewritePattern<fir::AddrOfOp> {
96
+ public:
97
+ using OpRewritePattern::OpRewritePattern;
98
+
99
+ mlir::LogicalResult
100
+ matchAndRewrite (fir::AddrOfOp op,
101
+ mlir::PatternRewriter &rewriter) const override {
102
+ auto result = fir::NameUniquer::deconstruct (op.symbol ().getRootReference ());
103
+ if (fir::NameUniquer::isExternalFacingUniquedName (result)) {
104
+ auto newName = rewriter.getSymbolRefAttr (mangleExternalName (result));
105
+ rewriter.replaceOpWithNewOp <fir::AddrOfOp>(op, op.resTy ().getType (),
106
+ newName);
107
+ }
108
+ return success ();
109
+ }
110
+ };
111
+
112
+ struct MangleNameOnEmboxProcOp
113
+ : public mlir::OpRewritePattern<fir::EmboxProcOp> {
114
+ public:
115
+ using OpRewritePattern::OpRewritePattern;
116
+
117
+ mlir::LogicalResult
118
+ matchAndRewrite (fir::EmboxProcOp op,
119
+ mlir::PatternRewriter &rewriter) const override {
120
+ rewriter.startRootUpdate (op);
121
+ auto result =
122
+ fir::NameUniquer::deconstruct (op.funcname ().getRootReference ());
123
+ if (fir::NameUniquer::isExternalFacingUniquedName (result))
124
+ op.funcnameAttr (
125
+ SymbolRefAttr::get (op.getContext (), mangleExternalName (result)));
126
+ rewriter.finalizeRootUpdate (op);
127
+ return success ();
128
+ }
129
+ };
130
+
131
+ class ExternalNameConversionPass
132
+ : public fir::ExternalNameConversionBase<ExternalNameConversionPass> {
133
+ public:
134
+ mlir::ModuleOp getModule () { return getOperation (); }
135
+ void runOnOperation () override ;
136
+ };
137
+ } // namespace
138
+
139
+ void ExternalNameConversionPass::runOnOperation () {
140
+ auto op = getOperation ();
141
+ auto *context = &getContext ();
142
+
143
+ mlir::OwningRewritePatternList patterns (context);
144
+ patterns.insert <MangleNameOnCallOp, MangleNameOnCallOp, MangleNameOnFuncOp,
145
+ MangleNameForCommonBlock, MangleNameOnAddrOfOp,
146
+ MangleNameOnEmboxProcOp>(context);
147
+
148
+ ConversionTarget target (*context);
149
+ target.addLegalDialect <fir::FIROpsDialect, LLVM::LLVMDialect,
150
+ acc::OpenACCDialect, omp::OpenMPDialect>();
151
+
152
+ target.addDynamicallyLegalOp <fir::CallOp>([](fir::CallOp op) {
153
+ if (op.callee ().hasValue ())
154
+ return !fir::NameUniquer::needExternalNameMangling (
155
+ op.callee ().getValue ().getRootReference ());
156
+ return true ;
157
+ });
158
+
159
+ target.addDynamicallyLegalOp <mlir::FuncOp>([](mlir::FuncOp op) {
160
+ return !fir::NameUniquer::needExternalNameMangling (op.sym_name ());
161
+ });
162
+
163
+ target.addDynamicallyLegalOp <fir::GlobalOp>([](fir::GlobalOp op) {
164
+ return !fir::NameUniquer::needExternalNameMangling (
165
+ op.symref ().getRootReference ());
166
+ });
167
+
168
+ target.addDynamicallyLegalOp <fir::AddrOfOp>([](fir::AddrOfOp op) {
169
+ return !fir::NameUniquer::needExternalNameMangling (
170
+ op.symbol ().getRootReference ());
171
+ });
172
+
173
+ target.addDynamicallyLegalOp <fir::EmboxProcOp>([](fir::EmboxProcOp op) {
174
+ return !fir::NameUniquer::needExternalNameMangling (
175
+ op.funcname ().getRootReference ());
176
+ });
177
+
178
+ if (failed (applyPartialConversion (op, target, std::move (patterns))))
179
+ signalPassFailure ();
180
+ }
181
+
182
+ std::unique_ptr<mlir::Pass> fir::createExternalNameConversionPass () {
183
+ return std::make_unique<ExternalNameConversionPass>();
184
+ }
0 commit comments