@@ -66,6 +66,9 @@ class AddDebugInfoPass : public fir::impl::AddDebugInfoBase<AddDebugInfoPass> {
6666 void handleGlobalOp (fir::GlobalOp glocalOp, mlir::LLVM::DIFileAttr fileAttr,
6767 mlir::LLVM::DIScopeAttr scope,
6868 mlir::SymbolTable *symbolTable);
69+ void handleFuncOp (mlir::func::FuncOp funcOp, mlir::LLVM::DIFileAttr fileAttr,
70+ mlir::LLVM::DICompileUnitAttr cuAttr,
71+ mlir::SymbolTable *symbolTable);
6972};
7073
7174static uint32_t getLineFromLoc (mlir::Location loc) {
@@ -204,11 +207,112 @@ void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
204207 globalOp->setLoc (builder.getFusedLoc ({globalOp->getLoc ()}, gvAttr));
205208}
206209
210+ void AddDebugInfoPass::handleFuncOp (mlir::func::FuncOp funcOp,
211+ mlir::LLVM::DIFileAttr fileAttr,
212+ mlir::LLVM::DICompileUnitAttr cuAttr,
213+ mlir::SymbolTable *symbolTable) {
214+ mlir::Location l = funcOp->getLoc ();
215+ // If fused location has already been created then nothing to do
216+ // Otherwise, create a fused location.
217+ if (debugInfoIsAlreadySet (l))
218+ return ;
219+
220+ mlir::ModuleOp module = getOperation ();
221+ mlir::MLIRContext *context = &getContext ();
222+ mlir::OpBuilder builder (context);
223+ llvm::StringRef fileName (fileAttr.getName ());
224+ llvm::StringRef filePath (fileAttr.getDirectory ());
225+ unsigned int CC = (funcOp.getName () == fir::NameUniquer::doProgramEntry ())
226+ ? llvm::dwarf::getCallingConvention (" DW_CC_program" )
227+ : llvm::dwarf::getCallingConvention (" DW_CC_normal" );
228+
229+ if (auto funcLoc = mlir::dyn_cast<mlir::FileLineColLoc>(l)) {
230+ fileName = llvm::sys::path::filename (funcLoc.getFilename ().getValue ());
231+ filePath = llvm::sys::path::parent_path (funcLoc.getFilename ().getValue ());
232+ }
233+
234+ mlir::StringAttr fullName = mlir::StringAttr::get (context, funcOp.getName ());
235+ mlir::Attribute attr = funcOp->getAttr (fir::getInternalFuncNameAttrName ());
236+ mlir::StringAttr funcName =
237+ (attr) ? mlir::cast<mlir::StringAttr>(attr)
238+ : mlir::StringAttr::get (context, funcOp.getName ());
239+
240+ auto result = fir::NameUniquer::deconstruct (funcName);
241+ funcName = mlir::StringAttr::get (context, result.second .name );
242+
243+ llvm::SmallVector<mlir::LLVM::DITypeAttr> types;
244+ fir::DebugTypeGenerator typeGen (module );
245+ for (auto resTy : funcOp.getResultTypes ()) {
246+ auto tyAttr = typeGen.convertType (resTy, fileAttr, cuAttr, funcOp.getLoc ());
247+ types.push_back (tyAttr);
248+ }
249+ for (auto inTy : funcOp.getArgumentTypes ()) {
250+ auto tyAttr = typeGen.convertType (fir::unwrapRefType (inTy), fileAttr,
251+ cuAttr, funcOp.getLoc ());
252+ types.push_back (tyAttr);
253+ }
254+
255+ mlir::LLVM::DISubroutineTypeAttr subTypeAttr =
256+ mlir::LLVM::DISubroutineTypeAttr::get (context, CC, types);
257+ mlir::LLVM::DIFileAttr funcFileAttr =
258+ mlir::LLVM::DIFileAttr::get (context, fileName, filePath);
259+
260+ // Only definitions need a distinct identifier and a compilation unit.
261+ mlir::DistinctAttr id;
262+ mlir::LLVM::DIScopeAttr Scope = fileAttr;
263+ mlir::LLVM::DICompileUnitAttr compilationUnit;
264+ mlir::LLVM::DISubprogramFlags subprogramFlags =
265+ mlir::LLVM::DISubprogramFlags{};
266+ if (isOptimized)
267+ subprogramFlags = mlir::LLVM::DISubprogramFlags::Optimized;
268+ if (!funcOp.isExternal ()) {
269+ id = mlir::DistinctAttr::create (mlir::UnitAttr::get (context));
270+ compilationUnit = cuAttr;
271+ subprogramFlags =
272+ subprogramFlags | mlir::LLVM::DISubprogramFlags::Definition;
273+ }
274+ unsigned line = getLineFromLoc (l);
275+ if (fir::isInternalProcedure (funcOp)) {
276+ // For contained functions, the scope is the parent subroutine.
277+ mlir::SymbolRefAttr sym = mlir::cast<mlir::SymbolRefAttr>(
278+ funcOp->getAttr (fir::getHostSymbolAttrName ()));
279+ if (sym) {
280+ if (auto func =
281+ symbolTable->lookup <mlir::func::FuncOp>(sym.getLeafReference ())) {
282+ // Make sure that parent is processed.
283+ handleFuncOp (func, fileAttr, cuAttr, symbolTable);
284+ if (auto fusedLoc =
285+ mlir::dyn_cast_if_present<mlir::FusedLoc>(func.getLoc ())) {
286+ if (auto spAttr =
287+ mlir::dyn_cast_if_present<mlir::LLVM::DISubprogramAttr>(
288+ fusedLoc.getMetadata ()))
289+ Scope = spAttr;
290+ }
291+ }
292+ }
293+ } else if (!result.second .modules .empty ()) {
294+ Scope = getOrCreateModuleAttr (result.second .modules [0 ], fileAttr, cuAttr,
295+ line - 1 , false );
296+ }
297+
298+ auto spAttr = mlir::LLVM::DISubprogramAttr::get (
299+ context, id, compilationUnit, Scope, funcName, fullName, funcFileAttr,
300+ line, line, subprogramFlags, subTypeAttr);
301+ funcOp->setLoc (builder.getFusedLoc ({funcOp->getLoc ()}, spAttr));
302+
303+ // Don't process variables if user asked for line tables only.
304+ if (debugLevel == mlir::LLVM::DIEmissionKind::LineTablesOnly)
305+ return ;
306+
307+ funcOp.walk ([&](fir::cg::XDeclareOp declOp) {
308+ handleDeclareOp (declOp, fileAttr, spAttr, typeGen, symbolTable);
309+ });
310+ }
311+
207312void AddDebugInfoPass::runOnOperation () {
208313 mlir::ModuleOp module = getOperation ();
209314 mlir::MLIRContext *context = &getContext ();
210315 mlir::SymbolTable symbolTable (module );
211- mlir::OpBuilder builder (context);
212316 llvm::StringRef fileName;
213317 std::string filePath;
214318 // We need 2 type of file paths here.
@@ -245,80 +349,7 @@ void AddDebugInfoPass::runOnOperation() {
245349 isOptimized, debugLevel);
246350
247351 module .walk ([&](mlir::func::FuncOp funcOp) {
248- mlir::Location l = funcOp->getLoc ();
249- // If fused location has already been created then nothing to do
250- // Otherwise, create a fused location.
251- if (debugInfoIsAlreadySet (l))
252- return ;
253-
254- unsigned int CC = (funcOp.getName () == fir::NameUniquer::doProgramEntry ())
255- ? llvm::dwarf::getCallingConvention (" DW_CC_program" )
256- : llvm::dwarf::getCallingConvention (" DW_CC_normal" );
257-
258- if (auto funcLoc = mlir::dyn_cast<mlir::FileLineColLoc>(l)) {
259- fileName = llvm::sys::path::filename (funcLoc.getFilename ().getValue ());
260- filePath = llvm::sys::path::parent_path (funcLoc.getFilename ().getValue ());
261- }
262-
263- mlir::StringAttr fullName =
264- mlir::StringAttr::get (context, funcOp.getName ());
265- mlir::Attribute attr = funcOp->getAttr (fir::getInternalFuncNameAttrName ());
266- mlir::StringAttr funcName =
267- (attr) ? mlir::cast<mlir::StringAttr>(attr)
268- : mlir::StringAttr::get (context, funcOp.getName ());
269-
270- auto result = fir::NameUniquer::deconstruct (funcName);
271- funcName = mlir::StringAttr::get (context, result.second .name );
272-
273- llvm::SmallVector<mlir::LLVM::DITypeAttr> types;
274- fir::DebugTypeGenerator typeGen (module );
275- for (auto resTy : funcOp.getResultTypes ()) {
276- auto tyAttr =
277- typeGen.convertType (resTy, fileAttr, cuAttr, funcOp.getLoc ());
278- types.push_back (tyAttr);
279- }
280- for (auto inTy : funcOp.getArgumentTypes ()) {
281- auto tyAttr = typeGen.convertType (fir::unwrapRefType (inTy), fileAttr,
282- cuAttr, funcOp.getLoc ());
283- types.push_back (tyAttr);
284- }
285-
286- mlir::LLVM::DISubroutineTypeAttr subTypeAttr =
287- mlir::LLVM::DISubroutineTypeAttr::get (context, CC, types);
288- mlir::LLVM::DIFileAttr funcFileAttr =
289- mlir::LLVM::DIFileAttr::get (context, fileName, filePath);
290-
291- // Only definitions need a distinct identifier and a compilation unit.
292- mlir::DistinctAttr id;
293- mlir::LLVM::DIScopeAttr Scope = fileAttr;
294- mlir::LLVM::DICompileUnitAttr compilationUnit;
295- mlir::LLVM::DISubprogramFlags subprogramFlags =
296- mlir::LLVM::DISubprogramFlags{};
297- if (isOptimized)
298- subprogramFlags = mlir::LLVM::DISubprogramFlags::Optimized;
299- if (!funcOp.isExternal ()) {
300- id = mlir::DistinctAttr::create (mlir::UnitAttr::get (context));
301- compilationUnit = cuAttr;
302- subprogramFlags =
303- subprogramFlags | mlir::LLVM::DISubprogramFlags::Definition;
304- }
305- unsigned line = getLineFromLoc (l);
306- if (!result.second .modules .empty ())
307- Scope = getOrCreateModuleAttr (result.second .modules [0 ], fileAttr, cuAttr,
308- line - 1 , false );
309-
310- auto spAttr = mlir::LLVM::DISubprogramAttr::get (
311- context, id, compilationUnit, Scope, funcName, fullName, funcFileAttr,
312- line, line, subprogramFlags, subTypeAttr);
313- funcOp->setLoc (builder.getFusedLoc ({funcOp->getLoc ()}, spAttr));
314-
315- // Don't process variables if user asked for line tables only.
316- if (debugLevel == mlir::LLVM::DIEmissionKind::LineTablesOnly)
317- return ;
318-
319- funcOp.walk ([&](fir::cg::XDeclareOp declOp) {
320- handleDeclareOp (declOp, fileAttr, spAttr, typeGen, &symbolTable);
321- });
352+ handleFuncOp (funcOp, fileAttr, cuAttr, &symbolTable);
322353 });
323354 // Process any global which was not processed through DeclareOp.
324355 if (debugLevel == mlir::LLVM::DIEmissionKind::Full) {
0 commit comments