1 //===- AddDebugFoundation.cpp -- add basic debug linetable info -----------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 //===----------------------------------------------------------------------===//
11 /// This pass populates some debug information for the module and functions.
12 //===----------------------------------------------------------------------===//
14 #include "flang/Optimizer/Builder/FIRBuilder.h"
15 #include "flang/Optimizer/Builder/Todo.h"
16 #include "flang/Optimizer/Dialect/FIRDialect.h"
17 #include "flang/Optimizer/Dialect/FIROps.h"
18 #include "flang/Optimizer/Dialect/FIRType.h"
19 #include "flang/Optimizer/Dialect/Support/FIRContext.h"
20 #include "flang/Optimizer/Transforms/Passes.h"
21 #include "mlir/Dialect/Func/IR/FuncOps.h"
22 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
23 #include "mlir/IR/Matchers.h"
24 #include "mlir/IR/TypeUtilities.h"
25 #include "mlir/Pass/Pass.h"
26 #include "mlir/Transforms/DialectConversion.h"
27 #include "mlir/Transforms/GreedyPatternRewriteDriver.h"
28 #include "mlir/Transforms/RegionUtils.h"
29 #include "llvm/BinaryFormat/Dwarf.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/Path.h"
32 #include "llvm/Support/raw_ostream.h"
35 #define GEN_PASS_DEF_ADDDEBUGFOUNDATION
36 #define GEN_PASS_DECL_ADDDEBUGFOUNDATION
37 #include "flang/Optimizer/Transforms/Passes.h.inc"
40 #define DEBUG_TYPE "flang-add-debug-foundation"
44 class AddDebugFoundationPass
45 : public fir::impl::AddDebugFoundationBase
<AddDebugFoundationPass
> {
47 void runOnOperation() override
;
52 void AddDebugFoundationPass::runOnOperation() {
53 mlir::ModuleOp module
= getOperation();
54 mlir::MLIRContext
*context
= &getContext();
55 mlir::OpBuilder
builder(context
);
56 std::string
inputFilePath("-");
57 if (auto fileLoc
= module
.getLoc().dyn_cast
<mlir::FileLineColLoc
>())
58 inputFilePath
= fileLoc
.getFilename().getValue();
60 auto getFileAttr
= [context
](llvm::StringRef path
) -> mlir::LLVM::DIFileAttr
{
61 return mlir::LLVM::DIFileAttr::get(context
, llvm::sys::path::filename(path
),
62 llvm::sys::path::parent_path(path
));
65 mlir::LLVM::DIFileAttr fileAttr
= getFileAttr(inputFilePath
);
66 mlir::StringAttr producer
= mlir::StringAttr::get(context
, "Flang");
67 mlir::LLVM::DICompileUnitAttr cuAttr
= mlir::LLVM::DICompileUnitAttr::get(
68 context
, llvm::dwarf::getLanguage("DW_LANG_Fortran95"), fileAttr
,
69 producer
, /*isOptimized=*/false,
70 mlir::LLVM::DIEmissionKind::LineTablesOnly
);
72 module
.walk([&](mlir::func::FuncOp funcOp
) {
73 mlir::Location l
= funcOp
->getLoc();
74 // If fused location has already been created then nothing to do
75 // Otherwise, create a fused location.
76 if (l
.dyn_cast
<mlir::FusedLoc
>())
79 llvm::StringRef funcFilePath
;
80 if (l
.dyn_cast
<mlir::FileLineColLoc
>())
82 l
.dyn_cast
<mlir::FileLineColLoc
>().getFilename().getValue();
84 funcFilePath
= inputFilePath
;
86 mlir::StringAttr funcName
=
87 mlir::StringAttr::get(context
, funcOp
.getName());
88 mlir::LLVM::DIBasicTypeAttr bT
= mlir::LLVM::DIBasicTypeAttr::get(
89 context
, llvm::dwarf::DW_TAG_base_type
, "void", /*sizeInBits=*/0,
91 mlir::LLVM::DISubroutineTypeAttr subTypeAttr
=
92 mlir::LLVM::DISubroutineTypeAttr::get(
93 context
, llvm::dwarf::getCallingConvention("DW_CC_normal"),
95 mlir::LLVM::DIFileAttr funcFileAttr
= getFileAttr(funcFilePath
);
96 mlir::LLVM::DISubprogramAttr spAttr
= mlir::LLVM::DISubprogramAttr::get(
97 context
, cuAttr
, fileAttr
, funcName
, funcName
, funcFileAttr
, /*line=*/1,
98 /*scopeline=*/1, mlir::LLVM::DISubprogramFlags::Definition
,
100 funcOp
->setLoc(builder
.getFusedLoc({funcOp
->getLoc()}, spAttr
));
104 std::unique_ptr
<mlir::Pass
> fir::createAddDebugFoundationPass() {
105 return std::make_unique
<AddDebugFoundationPass
>();