[flang-commits] [flang] [flang] Add debug information for module variables. (PR #91582)
via flang-commits
flang-commits at lists.llvm.org
Thu May 16 02:15:25 PDT 2024
================
@@ -99,6 +109,68 @@ void AddDebugInfoPass::handleDeclareOp(fir::cg::XDeclareOp declOp,
declOp->setLoc(builder.getFusedLoc({declOp->getLoc()}, localVarAttr));
}
+// The `module` does not have a first class representation in the `FIR`. We
+// extract information about it from the name of the identifiers and keep a
+// map to avoid duplication.
+mlir::LLVM::DIModuleAttr AddDebugInfoPass::getOrCreateModuleAttr(
+ const std::string &name, mlir::LLVM::DIFileAttr fileAttr,
+ mlir::LLVM::DIScopeAttr scope, unsigned line, bool decl) {
+ mlir::MLIRContext *context = &getContext();
+ mlir::LLVM::DIModuleAttr modAttr;
+ if (auto iter{moduleMap.find(name)}; iter != moduleMap.end())
+ modAttr = iter->getValue();
+ else {
+ modAttr = mlir::LLVM::DIModuleAttr::get(
+ context, fileAttr, scope, mlir::StringAttr::get(context, name),
+ mlir::StringAttr(), mlir::StringAttr(), mlir::StringAttr(), line, decl);
+ moduleMap[name] = modAttr;
+ }
+ return modAttr;
+}
+
+void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
+ mlir::LLVM::DIFileAttr fileAttr,
+ mlir::LLVM::DIScopeAttr scope) {
+ mlir::ModuleOp module = getOperation();
+ mlir::MLIRContext *context = &getContext();
+ fir::DebugTypeGenerator typeGen(module);
+ mlir::OpBuilder builder(context);
+
+ auto result = fir::NameUniquer::deconstruct(globalOp.getSymName());
+ if (result.first != fir::NameUniquer::NameKind::VARIABLE)
+ return;
+
+ unsigned line = getLineFromLoc(globalOp.getLoc());
+
+ // DWARF5 says following about the fortran modules:
+ // A Fortran 90 module may also be represented by a module entry
+ // (but no declaration attribute is warranted because Fortran has no concept
+ // of a corresponding module body).
+ // But in practice, compilers use declaration attribute with a module in cases
+ // where module was defined in another source file (only being used in this
+ // one). The hasInitializationBody() seems to provide the right information
+ // but inverted. It is true where module is actually defined but false where
+ // it is used.
+ // FIXME: Currently we don't have the line number on which a module was
+ // declared. We are using a best guess of line - 1 where line is the source
+ // line of the first member of the module that we encounter.
+
+ if (result.second.modules.empty())
+ return;
+
+ scope = getOrCreateModuleAttr(result.second.modules[0], fileAttr, scope,
+ line - 1, !globalOp.hasInitializationBody());
----------------
jeanPerier wrote:
You should use `globalOp.isInitialized()` here and below. In some cases, the initial value is defined as an attribute, not with operations inside the body.
https://github.com/llvm/llvm-project/pull/91582
More information about the flang-commits
mailing list