1111// / This pass populates some debug information for the module and functions.
1212// ===----------------------------------------------------------------------===//
1313
14+ #include " flang/Common/Version.h"
1415#include " flang/Optimizer/Builder/FIRBuilder.h"
1516#include " flang/Optimizer/Builder/Todo.h"
1617#include " flang/Optimizer/Dialect/FIRDialect.h"
1718#include " flang/Optimizer/Dialect/FIROps.h"
1819#include " flang/Optimizer/Dialect/FIRType.h"
1920#include " flang/Optimizer/Dialect/Support/FIRContext.h"
21+ #include " flang/Optimizer/Support/InternalNames.h"
2022#include " flang/Optimizer/Transforms/Passes.h"
2123#include " mlir/Dialect/Func/IR/FuncOps.h"
2224#include " mlir/Dialect/LLVMIR/LLVMDialect.h"
2830#include " mlir/Transforms/RegionUtils.h"
2931#include " llvm/BinaryFormat/Dwarf.h"
3032#include " llvm/Support/Debug.h"
33+ #include " llvm/Support/FileSystem.h"
3134#include " llvm/Support/Path.h"
3235#include " llvm/Support/raw_ostream.h"
3336
3437namespace fir {
3538#define GEN_PASS_DEF_ADDDEBUGINFO
36- #define GEN_PASS_DECL_ADDDEBUGINFO
3739#include " flang/Optimizer/Transforms/Passes.h.inc"
3840} // namespace fir
3941
@@ -43,6 +45,7 @@ namespace {
4345
4446class AddDebugInfoPass : public fir ::impl::AddDebugInfoBase<AddDebugInfoPass> {
4547public:
48+ AddDebugInfoPass (fir::AddDebugInfoOptions options) : Base(options) {}
4649 void runOnOperation () override ;
4750};
4851
@@ -52,21 +55,40 @@ void AddDebugInfoPass::runOnOperation() {
5255 mlir::ModuleOp module = getOperation ();
5356 mlir::MLIRContext *context = &getContext ();
5457 mlir::OpBuilder builder (context);
55- std::string inputFilePath (" -" );
56- if (auto fileLoc = module .getLoc ().dyn_cast <mlir::FileLineColLoc>())
57- inputFilePath = fileLoc.getFilename ().getValue ();
58+ llvm::StringRef fileName;
59+ std::string filePath;
60+ // We need 2 type of file paths here.
61+ // 1. Name of the file as was presented to compiler. This can be absolute
62+ // or relative to 2.
63+ // 2. Current working directory
64+ //
65+ // We are also dealing with 2 different situations below. One is normal
66+ // compilation where we will have a value in 'inputFilename' and we can
67+ // obtain the current directory using 'current_path'.
68+ // The 2nd case is when this pass is invoked directly from 'fir-opt' tool.
69+ // In that case, 'inputFilename' may be empty. Location embedded in the
70+ // module will be used to get file name and its directory.
71+ if (inputFilename.empty ()) {
72+ if (auto fileLoc = module .getLoc ().dyn_cast <mlir::FileLineColLoc>()) {
73+ fileName = llvm::sys::path::filename (fileLoc.getFilename ().getValue ());
74+ filePath = llvm::sys::path::parent_path (fileLoc.getFilename ().getValue ());
75+ } else
76+ fileName = " -" ;
77+ } else {
78+ fileName = inputFilename;
79+ llvm::SmallString<256 > cwd;
80+ if (!llvm::sys::fs::current_path (cwd))
81+ filePath = cwd.str ();
82+ }
5883
59- auto getFileAttr = [context](llvm::StringRef path) -> mlir::LLVM ::DIFileAttr {
60- return mlir::LLVM::DIFileAttr::get (context, llvm::sys::path::filename (path),
61- llvm::sys::path::parent_path (path));
62- };
63-
64- mlir::LLVM ::DIFileAttr fileAttr = getFileAttr (inputFilePath);
65- mlir::StringAttr producer = mlir::StringAttr::get (context, " Flang" );
84+ mlir::LLVM ::DIFileAttr fileAttr =
85+ mlir::LLVM::DIFileAttr::get (context, fileName, filePath);
86+ mlir::StringAttr producer =
87+ mlir::StringAttr::get (context, Fortran::common::getFlangFullVersion ());
6688 mlir::LLVM ::DICompileUnitAttr cuAttr = mlir::LLVM::DICompileUnitAttr::get (
6789 mlir::DistinctAttr::create (mlir::UnitAttr::get (context)),
6890 llvm::dwarf::getLanguage (" DW_LANG_Fortran95" ), fileAttr, producer,
69- /* isOptimized= */ false , mlir:: LLVM ::DIEmissionKind::LineTablesOnly );
91+ isOptimized, debugLevel );
7092
7193 module .walk ([&](mlir::func::FuncOp funcOp) {
7294 mlir::Location l = funcOp->getLoc ();
@@ -75,43 +97,49 @@ void AddDebugInfoPass::runOnOperation() {
7597 if (l.dyn_cast <mlir::FusedLoc>())
7698 return ;
7799
78- llvm::StringRef funcFilePath;
79- if (l.dyn_cast <mlir::FileLineColLoc>())
80- funcFilePath =
81- l.dyn_cast <mlir::FileLineColLoc>().getFilename ().getValue ();
82- else
83- funcFilePath = inputFilePath;
100+ unsigned int CC = (funcOp.getName () == fir::NameUniquer::doProgramEntry ())
101+ ? llvm::dwarf::getCallingConvention (" DW_CC_program" )
102+ : llvm::dwarf::getCallingConvention (" DW_CC_normal" );
103+
104+ if (auto funcLoc = l.dyn_cast <mlir::FileLineColLoc>()) {
105+ fileName = llvm::sys::path::filename (funcLoc.getFilename ().getValue ());
106+ filePath = llvm::sys::path::parent_path (funcLoc.getFilename ().getValue ());
107+ }
84108
85109 mlir::StringAttr funcName =
86110 mlir::StringAttr::get (context, funcOp.getName ());
87111 mlir::LLVM ::DIBasicTypeAttr bT = mlir::LLVM::DIBasicTypeAttr::get (
88112 context, llvm::dwarf::DW_TAG_base_type, " void" , /* sizeInBits=*/ 0 ,
89113 /* encoding=*/ 1 );
114+ // FIXME: Provide proper type for subroutine
90115 mlir::LLVM ::DISubroutineTypeAttr subTypeAttr =
91- mlir::LLVM::DISubroutineTypeAttr::get (
92- context, llvm::dwarf::getCallingConvention (" DW_CC_normal" ),
93- {bT, bT});
94- mlir::LLVM ::DIFileAttr funcFileAttr = getFileAttr (funcFilePath);
116+ mlir::LLVM::DISubroutineTypeAttr::get (context, CC , {bT, bT});
117+ mlir::LLVM ::DIFileAttr funcFileAttr =
118+ mlir::LLVM::DIFileAttr::get (context, fileName, filePath);
95119
96120 // Only definitions need a distinct identifier and a compilation unit.
97121 mlir::DistinctAttr id;
98122 mlir::LLVM ::DICompileUnitAttr compilationUnit;
99- auto subprogramFlags = mlir::LLVM ::DISubprogramFlags::Optimized;
123+ mlir::LLVM ::DISubprogramFlags subprogramFlags =
124+ mlir::LLVM ::DISubprogramFlags{};
125+ if (isOptimized)
126+ subprogramFlags = mlir::LLVM ::DISubprogramFlags::Optimized;
100127 if (!funcOp.isExternal ()) {
101128 id = mlir::DistinctAttr::create (mlir::UnitAttr::get (context));
102129 compilationUnit = cuAttr;
103130 subprogramFlags =
104131 subprogramFlags | mlir::LLVM ::DISubprogramFlags::Definition;
105132 }
133+ // FIXME: Provide proper line and scopeline.
106134 auto spAttr = mlir::LLVM::DISubprogramAttr::get (
107135 context, id, compilationUnit, fileAttr, funcName, funcName,
108- funcFileAttr,
109- /* line=*/ 1 ,
110- /* scopeline=*/ 1 , subprogramFlags, subTypeAttr);
136+ funcFileAttr, /* line=*/ 1 , /* scopeline=*/ 1 , subprogramFlags,
137+ subTypeAttr);
111138 funcOp->setLoc (builder.getFusedLoc ({funcOp->getLoc ()}, spAttr));
112139 });
113140}
114141
115- std::unique_ptr<mlir::Pass> fir::createAddDebugInfoPass () {
116- return std::make_unique<AddDebugInfoPass>();
142+ std::unique_ptr<mlir::Pass>
143+ fir::createAddDebugInfoPass (fir::AddDebugInfoOptions options) {
144+ return std::make_unique<AddDebugInfoPass>(options);
117145}
0 commit comments