@@ -49,7 +49,8 @@ class AddDebugInfoPass : public fir::impl::AddDebugInfoBase<AddDebugInfoPass> {
49
49
void handleDeclareOp (fir::cg::XDeclareOp declOp,
50
50
mlir::LLVM::DIFileAttr fileAttr,
51
51
mlir::LLVM::DIScopeAttr scopeAttr,
52
- fir::DebugTypeGenerator &typeGen);
52
+ fir::DebugTypeGenerator &typeGen,
53
+ mlir::SymbolTable *symbolTable);
53
54
54
55
public:
55
56
AddDebugInfoPass (fir::AddDebugInfoOptions options) : Base(options) {}
@@ -63,7 +64,8 @@ class AddDebugInfoPass : public fir::impl::AddDebugInfoBase<AddDebugInfoPass> {
63
64
mlir::LLVM::DIScopeAttr scope, unsigned line, bool decl);
64
65
65
66
void handleGlobalOp (fir::GlobalOp glocalOp, mlir::LLVM::DIFileAttr fileAttr,
66
- mlir::LLVM::DIScopeAttr scope);
67
+ mlir::LLVM::DIScopeAttr scope,
68
+ mlir::SymbolTable *symbolTable);
67
69
};
68
70
69
71
static uint32_t getLineFromLoc (mlir::Location loc) {
@@ -73,19 +75,32 @@ static uint32_t getLineFromLoc(mlir::Location loc) {
73
75
return line;
74
76
}
75
77
78
+ bool debugInfoIsAlreadySet (mlir::Location loc) {
79
+ if (mlir::isa<mlir::FusedLoc>(loc))
80
+ return true ;
81
+ return false ;
82
+ }
83
+
76
84
} // namespace
77
85
78
86
void AddDebugInfoPass::handleDeclareOp (fir::cg::XDeclareOp declOp,
79
87
mlir::LLVM::DIFileAttr fileAttr,
80
88
mlir::LLVM::DIScopeAttr scopeAttr,
81
- fir::DebugTypeGenerator &typeGen) {
89
+ fir::DebugTypeGenerator &typeGen,
90
+ mlir::SymbolTable *symbolTable) {
82
91
mlir::MLIRContext *context = &getContext ();
83
92
mlir::OpBuilder builder (context);
84
93
auto result = fir::NameUniquer::deconstruct (declOp.getUniqName ());
85
94
86
95
if (result.first != fir::NameUniquer::NameKind::VARIABLE)
87
96
return ;
88
97
98
+ // If this DeclareOp actually represents a global then treat it as such.
99
+ if (auto global = symbolTable->lookup <fir::GlobalOp>(declOp.getUniqName ())) {
100
+ handleGlobalOp (global, fileAttr, scopeAttr, symbolTable);
101
+ return ;
102
+ }
103
+
89
104
// Only accept local variables.
90
105
if (result.second .procs .empty ())
91
106
return ;
@@ -138,7 +153,10 @@ mlir::LLVM::DIModuleAttr AddDebugInfoPass::getOrCreateModuleAttr(
138
153
139
154
void AddDebugInfoPass::handleGlobalOp (fir::GlobalOp globalOp,
140
155
mlir::LLVM::DIFileAttr fileAttr,
141
- mlir::LLVM::DIScopeAttr scope) {
156
+ mlir::LLVM::DIScopeAttr scope,
157
+ mlir::SymbolTable *symbolTable) {
158
+ if (debugInfoIsAlreadySet (globalOp.getLoc ()))
159
+ return ;
142
160
mlir::ModuleOp module = getOperation ();
143
161
mlir::MLIRContext *context = &getContext ();
144
162
fir::DebugTypeGenerator typeGen (module );
@@ -163,12 +181,19 @@ void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
163
181
// declared. We are using a best guess of line - 1 where line is the source
164
182
// line of the first member of the module that we encounter.
165
183
166
- if (result.second .modules .empty ())
167
- return ;
184
+ if (result.second .procs .empty ()) {
185
+ // Only look for module if this variable is not part of a function.
186
+ if (result.second .modules .empty ())
187
+ return ;
168
188
169
- scope = getOrCreateModuleAttr (result.second .modules [0 ], fileAttr, scope,
170
- line - 1 , !globalOp.isInitialized ());
189
+ // Modules are generated at compile unit scope
190
+ if (mlir::LLVM::DISubprogramAttr sp =
191
+ mlir::dyn_cast_if_present<mlir::LLVM::DISubprogramAttr>(scope))
192
+ scope = sp.getCompileUnit ();
171
193
194
+ scope = getOrCreateModuleAttr (result.second .modules [0 ], fileAttr, scope,
195
+ line - 1 , !globalOp.isInitialized ());
196
+ }
172
197
mlir::LLVM::DITypeAttr diType = typeGen.convertType (
173
198
globalOp.getType (), fileAttr, scope, globalOp.getLoc ());
174
199
auto gvAttr = mlir::LLVM::DIGlobalVariableAttr::get (
@@ -182,6 +207,7 @@ void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
182
207
void AddDebugInfoPass::runOnOperation () {
183
208
mlir::ModuleOp module = getOperation ();
184
209
mlir::MLIRContext *context = &getContext ();
210
+ mlir::SymbolTable symbolTable (module );
185
211
mlir::OpBuilder builder (context);
186
212
llvm::StringRef fileName;
187
213
std::string filePath;
@@ -218,17 +244,11 @@ void AddDebugInfoPass::runOnOperation() {
218
244
llvm::dwarf::getLanguage (" DW_LANG_Fortran95" ), fileAttr, producer,
219
245
isOptimized, debugLevel);
220
246
221
- if (debugLevel == mlir::LLVM::DIEmissionKind::Full) {
222
- // Process 'GlobalOp' only if full debug info is requested.
223
- for (auto globalOp : module .getOps <fir::GlobalOp>())
224
- handleGlobalOp (globalOp, fileAttr, cuAttr);
225
- }
226
-
227
247
module .walk ([&](mlir::func::FuncOp funcOp) {
228
248
mlir::Location l = funcOp->getLoc ();
229
249
// If fused location has already been created then nothing to do
230
250
// Otherwise, create a fused location.
231
- if (mlir::dyn_cast<mlir::FusedLoc> (l))
251
+ if (debugInfoIsAlreadySet (l))
232
252
return ;
233
253
234
254
unsigned int CC = (funcOp.getName () == fir::NameUniquer::doProgramEntry ())
@@ -293,9 +313,15 @@ void AddDebugInfoPass::runOnOperation() {
293
313
return ;
294
314
295
315
funcOp.walk ([&](fir::cg::XDeclareOp declOp) {
296
- handleDeclareOp (declOp, fileAttr, spAttr, typeGen);
316
+ handleDeclareOp (declOp, fileAttr, spAttr, typeGen, &symbolTable );
297
317
});
298
318
});
319
+ // Process any global which was not processed through DeclareOp.
320
+ if (debugLevel == mlir::LLVM::DIEmissionKind::Full) {
321
+ // Process 'GlobalOp' only if full debug info is requested.
322
+ for (auto globalOp : module .getOps <fir::GlobalOp>())
323
+ handleGlobalOp (globalOp, fileAttr, cuAttr, &symbolTable);
324
+ }
299
325
}
300
326
301
327
std::unique_ptr<mlir::Pass>
0 commit comments