11
11
// / This pass populates some debug information for the module and functions.
12
12
// ===----------------------------------------------------------------------===//
13
13
14
+ #include " flang/Common/Version.h"
14
15
#include " flang/Optimizer/Builder/FIRBuilder.h"
15
16
#include " flang/Optimizer/Builder/Todo.h"
16
17
#include " flang/Optimizer/Dialect/FIRDialect.h"
17
18
#include " flang/Optimizer/Dialect/FIROps.h"
18
19
#include " flang/Optimizer/Dialect/FIRType.h"
19
20
#include " flang/Optimizer/Dialect/Support/FIRContext.h"
21
+ #include " flang/Optimizer/Support/InternalNames.h"
20
22
#include " flang/Optimizer/Transforms/Passes.h"
21
23
#include " mlir/Dialect/Func/IR/FuncOps.h"
22
24
#include " mlir/Dialect/LLVMIR/LLVMDialect.h"
28
30
#include " mlir/Transforms/RegionUtils.h"
29
31
#include " llvm/BinaryFormat/Dwarf.h"
30
32
#include " llvm/Support/Debug.h"
33
+ #include " llvm/Support/FileSystem.h"
31
34
#include " llvm/Support/Path.h"
32
35
#include " llvm/Support/raw_ostream.h"
33
36
34
37
namespace fir {
35
38
#define GEN_PASS_DEF_ADDDEBUGINFO
36
- #define GEN_PASS_DECL_ADDDEBUGINFO
37
39
#include " flang/Optimizer/Transforms/Passes.h.inc"
38
40
} // namespace fir
39
41
@@ -43,6 +45,7 @@ namespace {
43
45
44
46
class AddDebugInfoPass : public fir ::impl::AddDebugInfoBase<AddDebugInfoPass> {
45
47
public:
48
+ AddDebugInfoPass (fir::AddDebugInfoOptions options) : Base(options) {}
46
49
void runOnOperation () override ;
47
50
};
48
51
@@ -52,21 +55,40 @@ void AddDebugInfoPass::runOnOperation() {
52
55
mlir::ModuleOp module = getOperation ();
53
56
mlir::MLIRContext *context = &getContext ();
54
57
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
+ }
58
83
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 ());
66
88
mlir::LLVM::DICompileUnitAttr cuAttr = mlir::LLVM::DICompileUnitAttr::get (
67
89
mlir::DistinctAttr::create (mlir::UnitAttr::get (context)),
68
90
llvm::dwarf::getLanguage (" DW_LANG_Fortran95" ), fileAttr, producer,
69
- /* isOptimized= */ false , mlir::LLVM::DIEmissionKind::LineTablesOnly );
91
+ isOptimized, debugLevel );
70
92
71
93
module.walk ([&](mlir::func::FuncOp funcOp) {
72
94
mlir::Location l = funcOp->getLoc ();
@@ -75,43 +97,49 @@ void AddDebugInfoPass::runOnOperation() {
75
97
if (l.dyn_cast <mlir::FusedLoc>())
76
98
return ;
77
99
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
+ }
84
108
85
109
mlir::StringAttr funcName =
86
110
mlir::StringAttr::get (context, funcOp.getName ());
87
111
mlir::LLVM::DIBasicTypeAttr bT = mlir::LLVM::DIBasicTypeAttr::get (
88
112
context, llvm::dwarf::DW_TAG_base_type, " void" , /* sizeInBits=*/ 0 ,
89
113
/* encoding=*/ 1 );
114
+ // FIXME: Provide proper type for subroutine
90
115
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);
95
119
96
120
// Only definitions need a distinct identifier and a compilation unit.
97
121
mlir::DistinctAttr id;
98
122
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;
100
127
if (!funcOp.isExternal ()) {
101
128
id = mlir::DistinctAttr::create (mlir::UnitAttr::get (context));
102
129
compilationUnit = cuAttr;
103
130
subprogramFlags =
104
131
subprogramFlags | mlir::LLVM::DISubprogramFlags::Definition;
105
132
}
133
+ // FIXME: Provide proper line and scopeline.
106
134
auto spAttr = mlir::LLVM::DISubprogramAttr::get (
107
135
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);
111
138
funcOp->setLoc (builder.getFusedLoc ({funcOp->getLoc ()}, spAttr));
112
139
});
113
140
}
114
141
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);
117
145
}
0 commit comments