@@ -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) {
@@ -207,11 +210,113 @@ void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
207210 globalOp->setLoc (builder.getFusedLoc ({globalOp->getLoc ()}, gvAttr));
208211}
209212
213+ void AddDebugInfoPass::handleFuncOp (mlir::func::FuncOp funcOp,
214+ mlir::LLVM::DIFileAttr fileAttr,
215+ mlir::LLVM::DICompileUnitAttr cuAttr,
216+ mlir::SymbolTable *symbolTable) {
217+ mlir::Location l = funcOp->getLoc ();
218+ // If fused location has already been created then nothing to do
219+ // Otherwise, create a fused location.
220+ if (debugInfoIsAlreadySet (l))
221+ return ;
222+
223+ mlir::ModuleOp module = getOperation ();
224+ mlir::MLIRContext *context = &getContext ();
225+ mlir::OpBuilder builder (context);
226+ llvm::StringRef fileName (fileAttr.getName ());
227+ llvm::StringRef filePath (fileAttr.getDirectory ());
228+ unsigned int CC = (funcOp.getName () == fir::NameUniquer::doProgramEntry ())
229+ ? llvm::dwarf::getCallingConvention (" DW_CC_program" )
230+ : llvm::dwarf::getCallingConvention (" DW_CC_normal" );
231+
232+ if (auto funcLoc = mlir::dyn_cast<mlir::FileLineColLoc>(l)) {
233+ fileName = llvm::sys::path::filename (funcLoc.getFilename ().getValue ());
234+ filePath = llvm::sys::path::parent_path (funcLoc.getFilename ().getValue ());
235+ }
236+
237+ mlir::StringAttr fullName =
238+ mlir::StringAttr::get (context, funcOp.getName ());
239+ mlir::Attribute attr = funcOp->getAttr (fir::getInternalFuncNameAttrName ());
240+ mlir::StringAttr funcName =
241+ (attr) ? mlir::cast<mlir::StringAttr>(attr)
242+ : mlir::StringAttr::get (context, funcOp.getName ());
243+
244+ auto result = fir::NameUniquer::deconstruct (funcName);
245+ funcName = mlir::StringAttr::get (context, result.second .name );
246+
247+ llvm::SmallVector<mlir::LLVM::DITypeAttr> types;
248+ fir::DebugTypeGenerator typeGen (module );
249+ for (auto resTy : funcOp.getResultTypes ()) {
250+ auto tyAttr = typeGen.convertType (resTy, fileAttr, cuAttr, funcOp.getLoc ());
251+ types.push_back (tyAttr);
252+ }
253+ for (auto inTy : funcOp.getArgumentTypes ()) {
254+ auto tyAttr = typeGen.convertType (fir::unwrapRefType (inTy), fileAttr,
255+ cuAttr, funcOp.getLoc ());
256+ types.push_back (tyAttr);
257+ }
258+
259+ mlir::LLVM::DISubroutineTypeAttr subTypeAttr =
260+ mlir::LLVM::DISubroutineTypeAttr::get (context, CC, types);
261+ mlir::LLVM::DIFileAttr funcFileAttr =
262+ mlir::LLVM::DIFileAttr::get (context, fileName, filePath);
263+
264+ // Only definitions need a distinct identifier and a compilation unit.
265+ mlir::DistinctAttr id;
266+ mlir::LLVM::DIScopeAttr Scope = fileAttr;
267+ mlir::LLVM::DICompileUnitAttr compilationUnit;
268+ mlir::LLVM::DISubprogramFlags subprogramFlags =
269+ mlir::LLVM::DISubprogramFlags{};
270+ if (isOptimized)
271+ subprogramFlags = mlir::LLVM::DISubprogramFlags::Optimized;
272+ if (!funcOp.isExternal ()) {
273+ id = mlir::DistinctAttr::create (mlir::UnitAttr::get (context));
274+ compilationUnit = cuAttr;
275+ subprogramFlags =
276+ subprogramFlags | mlir::LLVM::DISubprogramFlags::Definition;
277+ }
278+ unsigned line = getLineFromLoc (l);
279+ if (fir::isInternalProcedure (funcOp)) {
280+ // For contained functions, the scope is the parent subroutine.
281+ mlir::SymbolRefAttr sym = mlir::cast<mlir::SymbolRefAttr>(
282+ funcOp->getAttr (fir::getHostSymbolAttrName ()));
283+ if (sym) {
284+ if (auto func =
285+ symbolTable->lookup <mlir::func::FuncOp>(sym.getLeafReference ())) {
286+ // Make sure that parent is processed.
287+ handleFuncOp (func, fileAttr, cuAttr, symbolTable);
288+ if (auto fusedLoc =
289+ mlir::dyn_cast_if_present<mlir::FusedLoc>(func.getLoc ())) {
290+ if (auto spAttr =
291+ mlir::dyn_cast_if_present<mlir::LLVM::DISubprogramAttr>(
292+ fusedLoc.getMetadata ()))
293+ Scope = spAttr;
294+ }
295+ }
296+ }
297+ } else if (!result.second .modules .empty ()) {
298+ Scope = getOrCreateModuleAttr (result.second .modules [0 ], fileAttr, cuAttr,
299+ line - 1 , false );
300+ }
301+
302+ auto spAttr = mlir::LLVM::DISubprogramAttr::get (
303+ context, id, compilationUnit, Scope, funcName, fullName, funcFileAttr,
304+ line, line, subprogramFlags, subTypeAttr);
305+ funcOp->setLoc (builder.getFusedLoc ({funcOp->getLoc ()}, spAttr));
306+
307+ // Don't process variables if user asked for line tables only.
308+ if (debugLevel == mlir::LLVM::DIEmissionKind::LineTablesOnly)
309+ return ;
310+
311+ funcOp.walk ([&](fir::cg::XDeclareOp declOp) {
312+ handleDeclareOp (declOp, fileAttr, spAttr, typeGen, symbolTable);
313+ });
314+ }
315+
210316void AddDebugInfoPass::runOnOperation () {
211317 mlir::ModuleOp module = getOperation ();
212318 mlir::MLIRContext *context = &getContext ();
213319 mlir::SymbolTable symbolTable (module );
214- mlir::OpBuilder builder (context);
215320 llvm::StringRef fileName;
216321 std::string filePath;
217322 // We need 2 type of file paths here.
@@ -248,100 +353,7 @@ void AddDebugInfoPass::runOnOperation() {
248353 isOptimized, debugLevel);
249354
250355 module .walk ([&](mlir::func::FuncOp funcOp) {
251- mlir::Location l = funcOp->getLoc ();
252- // If fused location has already been created then nothing to do
253- // Otherwise, create a fused location.
254- if (debugInfoIsAlreadySet (l))
255- return ;
256-
257- unsigned int CC = (funcOp.getName () == fir::NameUniquer::doProgramEntry ())
258- ? llvm::dwarf::getCallingConvention (" DW_CC_program" )
259- : llvm::dwarf::getCallingConvention (" DW_CC_normal" );
260-
261- if (auto funcLoc = mlir::dyn_cast<mlir::FileLineColLoc>(l)) {
262- fileName = llvm::sys::path::filename (funcLoc.getFilename ().getValue ());
263- filePath = llvm::sys::path::parent_path (funcLoc.getFilename ().getValue ());
264- }
265-
266- mlir::StringAttr fullName =
267- mlir::StringAttr::get (context, funcOp.getName ());
268- mlir::Attribute attr = funcOp->getAttr (fir::getInternalFuncNameAttrName ());
269- mlir::StringAttr funcName =
270- (attr) ? mlir::cast<mlir::StringAttr>(attr)
271- : mlir::StringAttr::get (context, funcOp.getName ());
272-
273- auto result = fir::NameUniquer::deconstruct (funcName);
274- funcName = mlir::StringAttr::get (context, result.second .name );
275-
276- llvm::SmallVector<mlir::LLVM::DITypeAttr> types;
277- fir::DebugTypeGenerator typeGen (module );
278- for (auto resTy : funcOp.getResultTypes ()) {
279- auto tyAttr =
280- typeGen.convertType (resTy, fileAttr, cuAttr, funcOp.getLoc ());
281- types.push_back (tyAttr);
282- }
283- for (auto inTy : funcOp.getArgumentTypes ()) {
284- auto tyAttr = typeGen.convertType (fir::unwrapRefType (inTy), fileAttr,
285- cuAttr, funcOp.getLoc ());
286- types.push_back (tyAttr);
287- }
288-
289- mlir::LLVM::DISubroutineTypeAttr subTypeAttr =
290- mlir::LLVM::DISubroutineTypeAttr::get (context, CC, types);
291- mlir::LLVM::DIFileAttr funcFileAttr =
292- mlir::LLVM::DIFileAttr::get (context, fileName, filePath);
293-
294- // Only definitions need a distinct identifier and a compilation unit.
295- mlir::DistinctAttr id;
296- mlir::LLVM::DIScopeAttr Scope = fileAttr;
297- mlir::LLVM::DICompileUnitAttr compilationUnit;
298- mlir::LLVM::DISubprogramFlags subprogramFlags =
299- mlir::LLVM::DISubprogramFlags{};
300- if (isOptimized)
301- subprogramFlags = mlir::LLVM::DISubprogramFlags::Optimized;
302- if (!funcOp.isExternal ()) {
303- id = mlir::DistinctAttr::create (mlir::UnitAttr::get (context));
304- compilationUnit = cuAttr;
305- subprogramFlags =
306- subprogramFlags | mlir::LLVM::DISubprogramFlags::Definition;
307- }
308- unsigned line = getLineFromLoc (l);
309- if (fir::isInternalProcedure (funcOp)) {
310- // For contained functions, the scope is the parent subroutine.
311- mlir::SymbolRefAttr sym = mlir::cast<mlir::SymbolRefAttr>(
312- funcOp->getAttr (fir::getHostSymbolAttrName ()));
313- if (sym) {
314- if (auto func = symbolTable.lookup <mlir::func::FuncOp>(
315- sym.getLeafReference ())) {
316- // FIXME: Can there be situation where we process contained function
317- // before the parent?
318- if (debugInfoIsAlreadySet (func.getLoc ())) {
319- if (auto fusedLoc = mlir::cast<mlir::FusedLoc>(func.getLoc ())) {
320- if (auto spAttr =
321- mlir::dyn_cast_if_present<mlir::LLVM::DISubprogramAttr>(
322- fusedLoc.getMetadata ()))
323- Scope = spAttr;
324- }
325- }
326- }
327- }
328- } else if (!result.second .modules .empty ()) {
329- Scope = getOrCreateModuleAttr (result.second .modules [0 ], fileAttr, cuAttr,
330- line - 1 , false );
331- }
332-
333- auto spAttr = mlir::LLVM::DISubprogramAttr::get (
334- context, id, compilationUnit, Scope, funcName, fullName, funcFileAttr,
335- line, line, subprogramFlags, subTypeAttr);
336- funcOp->setLoc (builder.getFusedLoc ({funcOp->getLoc ()}, spAttr));
337-
338- // Don't process variables if user asked for line tables only.
339- if (debugLevel == mlir::LLVM::DIEmissionKind::LineTablesOnly)
340- return ;
341-
342- funcOp.walk ([&](fir::cg::XDeclareOp declOp) {
343- handleDeclareOp (declOp, fileAttr, spAttr, typeGen, &symbolTable);
344- });
356+ handleFuncOp (funcOp, fileAttr, cuAttr, &symbolTable);
345357 });
346358 // Process any global which was not processed through DeclareOp.
347359 if (debugLevel == mlir::LLVM::DIEmissionKind::Full) {
0 commit comments