diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp index 6ff2c20d74453..f19646f7bd334 100644 --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -2996,11 +2996,13 @@ struct GlobalOpConversion : public fir::FIROpConversion { llvm::SmallVector dbgExprs; if (auto fusedLoc = mlir::dyn_cast(global.getLoc())) { - if (auto gvAttr = - mlir::dyn_cast_or_null( - fusedLoc.getMetadata())) { - dbgExprs.push_back(mlir::LLVM::DIGlobalVariableExpressionAttr::get( - global.getContext(), gvAttr, mlir::LLVM::DIExpressionAttr())); + if (auto gvExprAttr = mlir::dyn_cast_if_present( + fusedLoc.getMetadata())) { + for (auto attr : gvExprAttr.getAsRange()) + if (auto dbgAttr = + mlir::dyn_cast( + attr)) + dbgExprs.push_back(dbgAttr); } } diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp index a8e9d198ccb97..16404fcda57b4 100644 --- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp +++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp @@ -59,10 +59,19 @@ class AddDebugInfoPass : public fir::impl::AddDebugInfoBase { private: llvm::StringMap moduleMap; + llvm::StringMap commonBlockMap; + // List of GlobalVariableExpressionAttr that are attached to a given global + // that represents the storage for common block. + llvm::DenseMap> + globalToGlobalExprsMap; mlir::LLVM::DIModuleAttr getOrCreateModuleAttr( const std::string &name, mlir::LLVM::DIFileAttr fileAttr, mlir::LLVM::DIScopeAttr scope, unsigned line, bool decl); + mlir::LLVM::DICommonBlockAttr + getOrCreateCommonBlockAttr(llvm::StringRef name, + mlir::LLVM::DIFileAttr fileAttr, + mlir::LLVM::DIScopeAttr scope, unsigned line); void handleGlobalOp(fir::GlobalOp glocalOp, mlir::LLVM::DIFileAttr fileAttr, mlir::LLVM::DIScopeAttr scope, @@ -73,6 +82,12 @@ class AddDebugInfoPass : public fir::impl::AddDebugInfoBase { mlir::LLVM::DICompileUnitAttr cuAttr, fir::DebugTypeGenerator &typeGen, mlir::SymbolTable *symbolTable); + bool createCommonBlockGlobal(fir::cg::XDeclareOp declOp, + const std::string &name, + mlir::LLVM::DIFileAttr fileAttr, + mlir::LLVM::DIScopeAttr scopeAttr, + fir::DebugTypeGenerator &typeGen, + mlir::SymbolTable *symbolTable); std::optional getModuleAttrFromGlobalOp(fir::GlobalOp globalOp, mlir::LLVM::DIFileAttr fileAttr, @@ -90,6 +105,67 @@ bool debugInfoIsAlreadySet(mlir::Location loc) { } // namespace +bool AddDebugInfoPass::createCommonBlockGlobal( + fir::cg::XDeclareOp declOp, const std::string &name, + mlir::LLVM::DIFileAttr fileAttr, mlir::LLVM::DIScopeAttr scopeAttr, + fir::DebugTypeGenerator &typeGen, mlir::SymbolTable *symbolTable) { + mlir::MLIRContext *context = &getContext(); + mlir::OpBuilder builder(context); + std::optional optint; + mlir::Operation *op = declOp.getMemref().getDefiningOp(); + + if (auto conOp = mlir::dyn_cast_if_present(op)) + op = conOp.getValue().getDefiningOp(); + + if (auto cordOp = mlir::dyn_cast_if_present(op)) { + optint = fir::getIntIfConstant(cordOp.getOperand(1)); + if (!optint) + return false; + op = cordOp.getRef().getDefiningOp(); + if (auto conOp2 = mlir::dyn_cast_if_present(op)) + op = conOp2.getValue().getDefiningOp(); + + if (auto addrOfOp = mlir::dyn_cast_if_present(op)) { + mlir::SymbolRefAttr sym = addrOfOp.getSymbol(); + if (auto global = + symbolTable->lookup(sym.getRootReference())) { + + unsigned line = getLineFromLoc(global.getLoc()); + llvm::StringRef commonName(sym.getRootReference()); + // FIXME: We are trying to extract the name of the common block from the + // name of the global. As part of mangling, GetCommonBlockObjectName can + // add a trailing _ in the name of that global. The demangle function + // does not seem to handle such cases. So the following hack is used to + // remove the trailing '_'. + if (commonName != Fortran::common::blankCommonObjectName && + commonName.back() == '_') + commonName = commonName.drop_back(); + mlir::LLVM::DICommonBlockAttr commonBlock = + getOrCreateCommonBlockAttr(commonName, fileAttr, scopeAttr, line); + mlir::LLVM::DITypeAttr diType = typeGen.convertType( + fir::unwrapRefType(declOp.getType()), fileAttr, scopeAttr, declOp); + line = getLineFromLoc(declOp.getLoc()); + auto gvAttr = mlir::LLVM::DIGlobalVariableAttr::get( + context, commonBlock, mlir::StringAttr::get(context, name), + declOp.getUniqName(), fileAttr, line, diType, + /*isLocalToUnit*/ false, /*isDefinition*/ true, /* alignInBits*/ 0); + mlir::LLVM::DIExpressionAttr expr; + if (*optint != 0) { + llvm::SmallVector ops; + ops.push_back(mlir::LLVM::DIExpressionElemAttr::get( + context, llvm::dwarf::DW_OP_plus_uconst, *optint)); + expr = mlir::LLVM::DIExpressionAttr::get(context, ops); + } + auto dbgExpr = mlir::LLVM::DIGlobalVariableExpressionAttr::get( + global.getContext(), gvAttr, expr); + globalToGlobalExprsMap[global].push_back(dbgExpr); + return true; + } + } + } + return false; +} + void AddDebugInfoPass::handleDeclareOp(fir::cg::XDeclareOp declOp, mlir::LLVM::DIFileAttr fileAttr, mlir::LLVM::DIScopeAttr scopeAttr, @@ -101,6 +177,11 @@ void AddDebugInfoPass::handleDeclareOp(fir::cg::XDeclareOp declOp, if (result.first != fir::NameUniquer::NameKind::VARIABLE) return; + + if (createCommonBlockGlobal(declOp, result.second.name, fileAttr, scopeAttr, + typeGen, symbolTable)) + return; + // If this DeclareOp actually represents a global then treat it as such. if (auto global = symbolTable->lookup(declOp.getUniqName())) { handleGlobalOp(global, fileAttr, scopeAttr, typeGen, symbolTable, declOp); @@ -136,6 +217,22 @@ void AddDebugInfoPass::handleDeclareOp(fir::cg::XDeclareOp declOp, declOp->setLoc(builder.getFusedLoc({declOp->getLoc()}, localVarAttr)); } +mlir::LLVM::DICommonBlockAttr AddDebugInfoPass::getOrCreateCommonBlockAttr( + llvm::StringRef name, mlir::LLVM::DIFileAttr fileAttr, + mlir::LLVM::DIScopeAttr scope, unsigned line) { + mlir::MLIRContext *context = &getContext(); + mlir::LLVM::DICommonBlockAttr cbAttr; + if (auto iter{commonBlockMap.find(name)}; iter != commonBlockMap.end()) { + cbAttr = iter->getValue(); + } else { + cbAttr = mlir::LLVM::DICommonBlockAttr::get( + context, scope, nullptr, mlir::StringAttr::get(context, name), fileAttr, + line); + commonBlockMap[name] = cbAttr; + } + return cbAttr; +} + // 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. @@ -227,7 +324,10 @@ void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp, mlir::StringAttr::get(context, globalOp.getName()), fileAttr, line, diType, /*isLocalToUnit*/ false, /*isDefinition*/ globalOp.isInitialized(), /* alignInBits*/ 0); - globalOp->setLoc(builder.getFusedLoc({globalOp->getLoc()}, gvAttr)); + auto dbgExpr = mlir::LLVM::DIGlobalVariableExpressionAttr::get( + globalOp.getContext(), gvAttr, nullptr); + auto arrayAttr = mlir::ArrayAttr::get(context, {dbgExpr}); + globalOp->setLoc(builder.getFusedLoc({globalOp.getLoc()}, arrayAttr)); } void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp, @@ -409,6 +509,11 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp, if (&funcOp.front() == declOp->getBlock()) handleDeclareOp(declOp, fileAttr, spAttr, typeGen, symbolTable); }); + // commonBlockMap ensures that we don't create multiple DICommonBlockAttr of + // the same name in one function. But it is ok (rather required) to create + // them in different functions if common block of the same name has been used + // there. + commonBlockMap.clear(); } void AddDebugInfoPass::runOnOperation() { @@ -461,6 +566,13 @@ void AddDebugInfoPass::runOnOperation() { module.walk([&](mlir::func::FuncOp funcOp) { handleFuncOp(funcOp, fileAttr, cuAttr, typeGen, &symbolTable); }); + mlir::OpBuilder builder(context); + // We have processed all function. Attach common block variables to the + // global that represent the storage. + for (auto [global, exprs] : globalToGlobalExprsMap) { + auto arrayAttr = mlir::ArrayAttr::get(context, exprs); + global->setLoc(builder.getFusedLoc({global.getLoc()}, arrayAttr)); + } // Process any global which was not processed through DeclareOp. if (debugLevel == mlir::LLVM::DIEmissionKind::Full) { // Process 'GlobalOp' only if full debug info is requested. diff --git a/flang/test/Integration/debug-common-block-1.f90 b/flang/test/Integration/debug-common-block-1.f90 new file mode 100644 index 0000000000000..18217637be0fa --- /dev/null +++ b/flang/test/Integration/debug-common-block-1.f90 @@ -0,0 +1,138 @@ +! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s + +subroutine f1 + real(kind=4) :: x, y, xa, ya + common // x, y + common /a/ xa, ya + x = 1.1 + y = 2.2 + xa = 3.3 + ya = 4.4 + print *, x, y, xa, ya +end subroutine +! CHECK-DAG: ![[XF1:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "x", linkageName: "_QFf1Ex", scope: ![[CBF1:[0-9]+]], file: !5, line: [[@LINE-9]], type: ![[REAL:[0-9]+]]{{.*}}) +! CHECK-DAG: ![[EXPXF1:[0-9]+]] = !DIGlobalVariableExpression(var: ![[XF1]], expr: !DIExpression()) +! CHECK-DAG: ![[YF1:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "y", linkageName: "_QFf1Ey", scope: ![[CBF1]], file: !{{[0-9]+}}, line: [[@LINE-11]], type: ![[REAL]]{{.*}}) +! CHECK-DAG: ![[EXPYF1:[0-9]+]] = !DIGlobalVariableExpression(var: ![[YF1]], expr: !DIExpression(DW_OP_plus_uconst, 4)) +! CHECK-DAG: ![[XAF1:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "xa", linkageName: "_QFf1Exa", scope: ![[CBAF1:[0-9]+]], file: !{{[0-9]+}}, line: [[@LINE-13]], type: ![[REAL]]{{.*}}) +! CHECK-DAG: ![[EXPXAF1:[0-9]+]] = !DIGlobalVariableExpression(var: ![[XAF1]], expr: !DIExpression()) +! CHECK-DAG: ![[YAF1:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "ya", linkageName: "_QFf1Eya", scope: ![[CBAF1]], file: !{{[0-9]+}}, line: [[@LINE-15]], type: ![[REAL]]{{.*}}) +! CHECK-DAG: ![[EXPYAF1:[0-9]+]] = !DIGlobalVariableExpression(var: ![[YAF1]], expr: !DIExpression(DW_OP_plus_uconst, 4)) + + +subroutine f2 + real(kind=4) :: x, y, z, xa, ya, za + common // x, y, z + common /a/ xa, ya, za + print *, x, y, z, xa, ya, za +end subroutine +! CHECK-DAG: ![[XF2:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "x", linkageName: "_QFf2Ex", scope: ![[CBF2:[0-9]+]], file: !{{[0-9]+}}, line: [[@LINE-5]], type: ![[REAL]]{{.*}}) +! CHECK-DAG: ![[EXPXF2:[0-9]+]] = !DIGlobalVariableExpression(var: ![[XF2]], expr: !DIExpression()) +! CHECK-DAG: ![[YF2:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "y", linkageName: "_QFf2Ey", scope: ![[CBF2]], file: !{{[0-9]+}}, line: [[@LINE-7]], type: ![[REAL]]{{.*}}) +! CHECK-DAG: ![[EXPYF2:[0-9]+]] = !DIGlobalVariableExpression(var: ![[YF2]], expr: !DIExpression(DW_OP_plus_uconst, 4)) +! CHECK-DAG: ![[ZF2:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "z", linkageName: "_QFf2Ez", scope: ![[CBF2]], file: !{{[0-9]+}}, line: [[@LINE-9]], type: ![[REAL]]{{.*}}) +! CHECK-DAG: ![[EXPZF2:[0-9]+]] = !DIGlobalVariableExpression(var: ![[ZF2]], expr: !DIExpression(DW_OP_plus_uconst, 8)) +! CHECK-DAG: ![[XAF2:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "xa", linkageName: "_QFf2Exa", scope: ![[CBAF2:[0-9]+]], file: !{{[0-9]+}}, line: [[@LINE-11]], type: ![[REAL]]{{.*}}) +! CHECK-DAG: ![[EXPXAF2:[0-9]+]] = !DIGlobalVariableExpression(var: ![[XAF2]], expr: !DIExpression()) +! CHECK-DAG: ![[YAF2:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "ya", linkageName: "_QFf2Eya", scope: ![[CBAF2]], file: !{{[0-9]+}}, line: [[@LINE-13]], type: ![[REAL]]{{.*}}) +! CHECK-DAG: ![[EXPYAF2:[0-9]+]] = !DIGlobalVariableExpression(var: ![[YAF2]], expr: !DIExpression(DW_OP_plus_uconst, 4)) +! CHECK-DAG: ![[ZAF2:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "za", linkageName: "_QFf2Eza", scope: ![[CBAF2]], file: !{{[0-9]+}}, line: [[@LINE-15]], type: ![[REAL]]{{.*}}) +! CHECK-DAG: ![[EXPZAF2:[0-9]+]] = !DIGlobalVariableExpression(var: ![[ZAF2]], expr: !DIExpression(DW_OP_plus_uconst, 8)) + +subroutine f3 + integer(kind=4) :: x = 42, xa = 42 + common // x + common /a/ xa + print *, x + print *, xa +end subroutine +! CHECK-DAG: ![[XF3:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "x", linkageName: "_QFf3Ex", scope: ![[CBF3:[0-9]+]], file: !{{[0-9]+}}, line: [[@LINE-6]], type: ![[INT:[0-9]+]]{{.*}}) +! CHECK-DAG: ![[EXPXF3:[0-9]+]] = !DIGlobalVariableExpression(var: ![[XF3]], expr: !DIExpression()) +! CHECK-DAG: ![[XAF3:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "xa", linkageName: "_QFf3Exa", scope: ![[CBAF3:[0-9]+]], file: !{{[0-9]+}}, line: [[@LINE-8]], type: ![[INT]]{{.*}}) +! CHECK-DAG: ![[EXPXAF3:[0-9]+]] = !DIGlobalVariableExpression(var: ![[XAF3]], expr: !DIExpression()) + +program test + real(kind=4) :: v1, v2, v3, va1, va2, va3 + common // v1, v2, v3 + common /a/ va1, va2, va3 + call f1() + call f2() + call f3() + print *, v1, va1, va3 +END +! CHECK-DAG: ![[V1:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "v1", linkageName: "_QFEv1", scope: ![[CBM:[0-9]+]], file: !{{[0-9]+}}, line: [[@LINE-8]], type: ![[REAL]]{{.*}}) +! CHECK-DAG: ![[EXPV1:[0-9]+]] = !DIGlobalVariableExpression(var: ![[V1]], expr: !DIExpression()) +! CHECK-DAG: ![[V2:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "v2", linkageName: "_QFEv2", scope: ![[CBM]], file: !{{[0-9]+}}, line: [[@LINE-10]], type: ![[REAL]]{{.*}}) +! CHECK-DAG: ![[EXPV2:[0-9]+]] = !DIGlobalVariableExpression(var: ![[V2]], expr: !DIExpression(DW_OP_plus_uconst, 4)) +! CHECK-DAG: ![[V3:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "v3", linkageName: "_QFEv3", scope: ![[CBM]], file: !{{[0-9]+}}, line: [[@LINE-12]], type: ![[REAL]]{{.*}}) +! CHECK-DAG: ![[EXPV3:[0-9]+]] = !DIGlobalVariableExpression(var: ![[V3]], expr: !DIExpression(DW_OP_plus_uconst, 8)) +! CHECK-DAG: ![[VA1:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "va1", linkageName: "_QFEva1", scope: ![[CBAM:[0-9]+]], file: !{{[0-9]+}}, line: [[@LINE-14]], type: ![[REAL]]{{.*}}) +! CHECK-DAG: ![[EXPVA1:[0-9]+]] = !DIGlobalVariableExpression(var: ![[VA1]], expr: !DIExpression()) +! CHECK-DAG: ![[VA2:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "va2", linkageName: "_QFEva2", scope: ![[CBAM]], file: !{{[0-9]+}}, line: [[@LINE-16]], type: ![[REAL]]{{.*}}) +! CHECK-DAG: ![[EXPVA2:[0-9]+]] = !DIGlobalVariableExpression(var: ![[VA2]], expr: !DIExpression(DW_OP_plus_uconst, 4)) +! CHECK-DAG: ![[VA3:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "va3", linkageName: "_QFEva3", scope: ![[CBAM]], file: !{{[0-9]+}}, line: [[@LINE-18]], type: ![[REAL]]{{.*}}) +! CHECK-DAG: ![[EXPVA3:[0-9]+]] = !DIGlobalVariableExpression(var: ![[VA3]], expr: !DIExpression(DW_OP_plus_uconst, 8)) + + +! CHECK-DAG: ![[REAL]] = !DIBasicType(name: "real", size: 32, encoding: DW_ATE_float) +! CHECK-DAG: ![[INT]] = !DIBasicType(name: "integer", size: 32, encoding: DW_ATE_signed) + +! CHECK-DAG: ![[F1:[0-9]+]] = {{.*}}!DISubprogram(name: "f1"{{.*}}) +! CHECK-DAG: ![[CBF1]] = !DICommonBlock(scope: ![[F1]], declaration: null, name: "__BLNK__"{{.*}}) +! CHECK-DAG: ![[CBAF1]] = !DICommonBlock(scope: ![[F1]], declaration: null, name: "a"{{.*}}) + +! CHECK-DAG: ![[F2:[0-9]+]] = {{.*}}!DISubprogram(name: "f2"{{.*}}) +! CHECK-DAG: ![[CBF2]] = !DICommonBlock(scope: ![[F2]], declaration: null, name: "__BLNK__"{{.*}}) +! CHECK-DAG: ![[CBAF2]] = !DICommonBlock(scope: ![[F2]], declaration: null, name: "a"{{.*}}) + +! CHECK-DAG: ![[F3:[0-9]+]] = {{.*}}!DISubprogram(name: "f3"{{.*}}) +! CHECK-DAG: ![[CBF3]] = !DICommonBlock(scope: ![[F3]], declaration: null, name: "__BLNK__"{{.*}}) +! CHECK-DAG: ![[CBAF3]] = !DICommonBlock(scope: ![[F3]], declaration: null, name: "a"{{.*}}) + +! CHECK-DAG: ![[MAIN:[0-9]+]] = {{.*}}!DISubprogram(name: "test"{{.*}}) +! CHECK-DAG: ![[CBM]] = !DICommonBlock(scope: ![[MAIN]], declaration: null, name: "__BLNK__"{{.*}}) +! CHECK-DAG: ![[CBAM]] = !DICommonBlock(scope: ![[MAIN]], declaration: null, name: "a"{{.*}}) + +! Using CHECK-DAG-SAME so that we are not dependent on order of variable in these lists. +! CHECK-DAG: @__BLNK__ = global{{.*}} +! CHECK-DAG-SAME: !dbg ![[EXPXF1]] +! CHECK-DAG-SAME: !dbg ![[EXPYF1]] +! CHECK-DAG-SAME: !dbg ![[EXPXF2]] +! CHECK-DAG-SAME: !dbg ![[EXPYF2]] +! CHECK-DAG-SAME: !dbg ![[EXPZF2]] +! CHECK-DAG-SAME: !dbg ![[EXPXF3]] +! CHECK-DAG-SAME: !dbg ![[EXPV1]] +! CHECK-DAG-SAME: !dbg ![[EXPV2]] +! CHECK-DAG-SAME: !dbg ![[EXPV3]] + +! CHECK-DAG: @a_ = global{{.*}} +! CHECK-DAG-SAME: !dbg ![[EXPXAF1]] +! CHECK-DAG-SAME: !dbg ![[EXPYAF1]] +! CHECK-DAG-SAME: !dbg ![[EXPXAF2]] +! CHECK-DAG-SAME: !dbg ![[EXPYAF2]] +! CHECK-DAG-SAME: !dbg ![[EXPZAF2]] +! CHECK-DAG-SAME: !dbg ![[EXPXAF3]] +! CHECK-DAG-SAME: !dbg ![[EXPVA1]] +! CHECK-DAG-SAME: !dbg ![[EXPVA2]] +! CHECK-DAG-SAME: !dbg ![[EXPVA3]] + +! CHECK-DAG: !DICompileUnit({{.*}}, globals: ![[GLOBALS:[0-9]+]]) +! CHECK-DAG: ![[GLOBALS]] +! CHECK-DAG-SAME: ![[EXPXF1]] +! CHECK-DAG-SAME: ![[EXPYF1]] +! CHECK-DAG-SAME: ![[EXPXAF1]] +! CHECK-DAG-SAME: ![[EXPYAF1]] +! CHECK-DAG-SAME: ![[EXPXF2]] +! CHECK-DAG-SAME: ![[EXPYF2]] +! CHECK-DAG-SAME: ![[EXPZF2]] +! CHECK-DAG-SAME: ![[EXPXAF2]] +! CHECK-DAG-SAME: ![[EXPYAF2]] +! CHECK-DAG-SAME: ![[EXPZAF2]] +! CHECK-DAG-SAME: ![[EXPXF3]] +! CHECK-DAG-SAME: ![[EXPXAF3]] +! CHECK-DAG-SAME: ![[EXPV1]] +! CHECK-DAG-SAME: ![[EXPV2]] +! CHECK-DAG-SAME: ![[EXPV3]] +! CHECK-DAG-SAME: ![[EXPVA1]] +! CHECK-DAG-SAME: ![[EXPVA2]] +! CHECK-DAG-SAME: ![[EXPVA3]] diff --git a/flang/test/Transforms/debug-common-block.fir b/flang/test/Transforms/debug-common-block.fir new file mode 100644 index 0000000000000..481b26369a92c --- /dev/null +++ b/flang/test/Transforms/debug-common-block.fir @@ -0,0 +1,213 @@ +// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s + +module attributes {dlti.dl_spec = #dlti.dl_spec<>} { + fir.global @__BLNK__ {alignment = 4 : i64} : tuple> {} loc(#loc1) + fir.global @a_ {alignment = 4 : i64} : tuple> {} loc(#loc2) + func.func @f1() { + %c9_i32 = arith.constant 9 : i32 + %c6_i32 = arith.constant 6 : i32 + %cst = arith.constant 4.400000e+00 : f32 + %cst_0 = arith.constant 3.300000e+00 : f32 + %cst_1 = arith.constant 2.200000e+00 : f32 + %cst_2 = arith.constant 1.100000e+00 : f32 + %c4 = arith.constant 4 : index + %c0 = arith.constant 0 : index + %0 = fir.address_of(@__BLNK__) : !fir.ref>> + %1 = fir.convert %0 : (!fir.ref>>) -> !fir.ref> + %2 = fir.coordinate_of %1, %c0 : (!fir.ref>, index) -> !fir.ref + %3 = fir.convert %2 : (!fir.ref) -> !fir.ref + %4 = fircg.ext_declare %3 {uniq_name = "_QFf1Ex"} : (!fir.ref) -> !fir.ref loc(#loc4) + %5 = fir.address_of(@a_) : !fir.ref>> + %6 = fir.convert %5 : (!fir.ref>>) -> !fir.ref> + %7 = fir.coordinate_of %6, %c0 : (!fir.ref>, index) -> !fir.ref + %8 = fir.convert %7 : (!fir.ref) -> !fir.ref + %9 = fircg.ext_declare %8 {uniq_name = "_QFf1Exa"} : (!fir.ref) -> !fir.ref loc(#loc5) + %10 = fir.coordinate_of %1, %c4 : (!fir.ref>, index) -> !fir.ref + %11 = fir.convert %10 : (!fir.ref) -> !fir.ref + %12 = fircg.ext_declare %11 {uniq_name = "_QFf1Ey"} : (!fir.ref) -> !fir.ref loc(#loc6) + %13 = fir.coordinate_of %6, %c4 : (!fir.ref>, index) -> !fir.ref + %14 = fir.convert %13 : (!fir.ref) -> !fir.ref + %15 = fircg.ext_declare %14 {uniq_name = "_QFf1Eya"} : (!fir.ref) -> !fir.ref loc(#loc7) + return + } loc(#loc3) + func.func @f2() { + %c16_i32 = arith.constant 16 : i32 + %c6_i32 = arith.constant 6 : i32 + %c8 = arith.constant 8 : index + %c4 = arith.constant 4 : index + %c0 = arith.constant 0 : index + %0 = fir.address_of(@__BLNK__) : !fir.ref>> loc(#loc19) + %1 = fir.convert %0 : (!fir.ref>>) -> !fir.ref> + %2 = fir.coordinate_of %1, %c0 : (!fir.ref>, index) -> !fir.ref + %3 = fir.convert %2 : (!fir.ref) -> !fir.ref + %4 = fircg.ext_declare %3 {uniq_name = "_QFf2Ex"} : (!fir.ref) -> !fir.ref loc(#loc9) + %5 = fir.address_of(@a_) : !fir.ref>> + %6 = fir.convert %5 : (!fir.ref>>) -> !fir.ref> + %7 = fir.coordinate_of %6, %c0 : (!fir.ref>, index) -> !fir.ref + %8 = fir.convert %7 : (!fir.ref) -> !fir.ref + %9 = fircg.ext_declare %8 {uniq_name = "_QFf2Exa"} : (!fir.ref) -> !fir.ref loc(#loc10) + %10 = fir.coordinate_of %1, %c4 : (!fir.ref>, index) -> !fir.ref + %11 = fir.convert %10 : (!fir.ref) -> !fir.ref + %12 = fircg.ext_declare %11 {uniq_name = "_QFf2Ey"} : (!fir.ref) -> !fir.ref loc(#loc11) + %13 = fir.coordinate_of %6, %c4 : (!fir.ref>, index) -> !fir.ref + %14 = fir.convert %13 : (!fir.ref) -> !fir.ref + %15 = fircg.ext_declare %14 {uniq_name = "_QFf2Eya"} : (!fir.ref) -> !fir.ref loc(#loc12) + %16 = fir.coordinate_of %1, %c8 : (!fir.ref>, index) -> !fir.ref + %17 = fir.convert %16 : (!fir.ref) -> !fir.ref + %18 = fircg.ext_declare %17 {uniq_name = "_QFf2Ez"} : (!fir.ref) -> !fir.ref loc(#loc13) + %19 = fir.coordinate_of %6, %c8 : (!fir.ref>, index) -> !fir.ref + %20 = fir.convert %19 : (!fir.ref) -> !fir.ref + %21 = fircg.ext_declare %20 {uniq_name = "_QFf2Eza"} : (!fir.ref) -> !fir.ref loc(#loc14) + return + } loc(#loc8) + func.func @f3() { + %c24_i32 = arith.constant 24 : i32 + %c23_i32 = arith.constant 23 : i32 + %c6_i32 = arith.constant 6 : i32 + %c0 = arith.constant 0 : index + %0 = fir.address_of(@__BLNK__) : !fir.ref>> + %1 = fir.convert %0 : (!fir.ref>>) -> !fir.ref> + %2 = fir.coordinate_of %1, %c0 : (!fir.ref>, index) -> !fir.ref + %3 = fir.convert %2 : (!fir.ref) -> !fir.ref + %4 = fircg.ext_declare %3 {uniq_name = "_QFf3Ex"} : (!fir.ref) -> !fir.ref loc(#loc16) + %5 = fir.address_of(@a_) : !fir.ref>> + %6 = fir.convert %5 : (!fir.ref>>) -> !fir.ref> + %7 = fir.coordinate_of %6, %c0 : (!fir.ref>, index) -> !fir.ref + %8 = fir.convert %7 : (!fir.ref) -> !fir.ref + %9 = fircg.ext_declare %8 {uniq_name = "_QFf3Exa"} : (!fir.ref) -> !fir.ref loc(#loc17) + return + } loc(#loc15) + func.func @test() { + %c34_i32 = arith.constant 34 : i32 + %c6_i32 = arith.constant 6 : i32 + %c8 = arith.constant 8 : index + %c4 = arith.constant 4 : index + %c0 = arith.constant 0 : index + %0 = fir.address_of(@__BLNK__) : !fir.ref>> + %1 = fir.convert %0 : (!fir.ref>>) -> !fir.ref> + %2 = fir.coordinate_of %1, %c0 : (!fir.ref>, index) -> !fir.ref + %3 = fir.convert %2 : (!fir.ref) -> !fir.ref + %4 = fircg.ext_declare %3 {uniq_name = "_QFEv1"} : (!fir.ref) -> !fir.ref loc(#loc19) + %5 = fir.coordinate_of %1, %c4 : (!fir.ref>, index) -> !fir.ref + %6 = fir.convert %5 : (!fir.ref) -> !fir.ref + %7 = fircg.ext_declare %6 {uniq_name = "_QFEv2"} : (!fir.ref) -> !fir.ref loc(#loc20) + %8 = fir.coordinate_of %1, %c8 : (!fir.ref>, index) -> !fir.ref + %9 = fir.convert %8 : (!fir.ref) -> !fir.ref + %10 = fircg.ext_declare %9 {uniq_name = "_QFEv3"} : (!fir.ref) -> !fir.ref loc(#loc21) + %11 = fir.address_of(@a_) : !fir.ref>> + %12 = fir.convert %11 : (!fir.ref>>) -> !fir.ref> + %13 = fir.coordinate_of %12, %c0 : (!fir.ref>, index) -> !fir.ref + %14 = fir.convert %13 : (!fir.ref) -> !fir.ref + %15 = fircg.ext_declare %14 {uniq_name = "_QFEva1"} : (!fir.ref) -> !fir.ref loc(#loc22) + %16 = fir.coordinate_of %12, %c4 : (!fir.ref>, index) -> !fir.ref + %17 = fir.convert %16 : (!fir.ref) -> !fir.ref + %18 = fircg.ext_declare %17 {uniq_name = "_QFEva2"} : (!fir.ref) -> !fir.ref loc(#loc23) + %19 = fir.coordinate_of %12, %c8 : (!fir.ref>, index) -> !fir.ref + %20 = fir.convert %19 : (!fir.ref) -> !fir.ref + %21 = fircg.ext_declare %20 {uniq_name = "_QFEva3"} : (!fir.ref) -> !fir.ref loc(#loc24) + return + } loc(#loc18) +} + +#loc1 = loc(unknown) +#loc2 = loc(unknown) +#loc3 = loc("common.f90":10:1) +#loc4 = loc("common.f90":12:19) +#loc5 = loc("common.f90":12:25) +#loc6 = loc("common.f90":12:22) +#loc7 = loc("common.f90":12:29) +#loc8 = loc("common.f90":20:3) +#loc9 = loc("common.f90":22:3) +#loc10 = loc("common.f90":22:6) +#loc11 = loc("common.f90":22:9) +#loc12 = loc("common.f90":22:13) +#loc13 = loc("common.f90":22:16) +#loc14 = loc("common.f90":22:19) +#loc15 = loc("common.f90":32:18) +#loc16 = loc("common.f90":35:7) +#loc17 = loc("common.f90":35:10) +#loc18 = loc("common.f90":40:1) +#loc19 = loc("common.f90":43:19) +#loc20 = loc("common.f90":43:28) +#loc21 = loc("common.f90":43:22) +#loc22 = loc("common.f90":43:32) +#loc23 = loc("common.f90":43:25) +#loc24 = loc("common.f90":43:36) + + +// CHECK-DAG: #[[XF1:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[YF1:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[EXPXF1:.*]] = #llvm.di_global_variable_expression +// CHECK-DAG: #[[EXPYF1:.*]] = #llvm.di_global_variable_expression> +// CHECK-DAG: #[[XAF1:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[YAF1:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[EXPXAF1:.*]] = #llvm.di_global_variable_expression +// CHECK-DAG: #[[EXPYAF1:.*]] = #llvm.di_global_variable_expression> + +// CHECK-DAG: #[[XF2:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[YF2:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[ZF2:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[EXPXF2:.*]] = #llvm.di_global_variable_expression +// CHECK-DAG: #[[EXPYF2:.*]] = #llvm.di_global_variable_expression> +// CHECK-DAG: #[[EXPZF2:.*]] = #llvm.di_global_variable_expression> +// CHECK-DAG: #[[XAF2:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[YAF2:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[ZAF2:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[EXPXAF2:.*]] = #llvm.di_global_variable_expression +// CHECK-DAG: #[[EXPYAF2:.*]] = #llvm.di_global_variable_expression> +// CHECK-DAG: #[[EXPZAF2:.*]] = #llvm.di_global_variable_expression> + +// CHECK-DAG: #[[XF3:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[EXPXF3:.*]] = #llvm.di_global_variable_expression +// CHECK-DAG: #[[XAF3:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[EXPXAF3:.*]] = #llvm.di_global_variable_expression + +// CHECK-DAG: #[[V1:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[EXPV1:.*]] = #llvm.di_global_variable_expression +// CHECK-DAG: #[[V2:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[EXPV2:.*]] = #llvm.di_global_variable_expression> +// CHECK-DAG: #[[V3:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[EXPV3:.*]] = #llvm.di_global_variable_expression> +// CHECK-DAG: #[[VA1:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[EXPVA1:.*]] = #llvm.di_global_variable_expression +// CHECK-DAG: #[[VA2:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[EXPVA2:.*]] = #llvm.di_global_variable_expression> +// CHECK-DAG: #[[VA3:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[EXPVA3:.*]] = #llvm.di_global_variable_expression> + +// CHECK-DAG: #[[F1:.*]] = #llvm.di_subprogram<{{.*}}name = "f1"{{.*}}> +// CHECK-DAG: #[[F2:.*]] = #llvm.di_subprogram<{{.*}}name = "f2"{{.*}}> +// CHECK-DAG: #[[F3:.*]] = #llvm.di_subprogram<{{.*}}name = "f3"{{.*}}> +// CHECK-DAG: #[[TEST:.*]] = #llvm.di_subprogram<{{.*}}name = "test"{{.*}}> + +// CHECK-DAG: #[[CBF1]] = #llvm.di_common_block +// CHECK-DAG: #[[CBF2]] = #llvm.di_common_block +// CHECK-DAG: #[[CBF3]] = #llvm.di_common_block +// CHECK-DAG: #[[CBM]] = #llvm.di_common_block +// CHECK-DAG: #[[CBAF1]] = #llvm.di_common_block +// CHECK-DAG: #[[CBAF2]] = #llvm.di_common_block +// CHECK-DAG: #[[CBAF3]] = #llvm.di_common_block +// CHECK-DAG: #[[CBAM]] = #llvm.di_common_block + +// CHECK-DAG: fir.global @__BLNK__ {{.*}} loc(#[[LOC1:.*]]) +// CHECK-DAG: fir.global @a_ {{.*}} loc(#[[LOC2:.*]]) +// CHECK-DAG: #[[LOC1]] +// CHECK-DAG-SAME: #[[EXPXF1]] +// CHECK-DAG-SAME: #[[EXPYF1]] +// CHECK-DAG-SAME: #[[EXPXF2]] +// CHECK-DAG-SAME: #[[EXPYF2]] +// CHECK-DAG-SAME: #[[EXPZF2]] +// CHECK-DAG-SAME: #[[EXPXF3]] +// CHECK-DAG-SAME: #[[EXPV1]] +// CHECK-DAG-SAME: #[[EXPV2]] +// CHECK-DAG-SAME: #[[EXPV3]] +// CHECK-DAG: #[[LOC2]] +// CHECK-DAG-SAME: #[[EXPXAF1]] +// CHECK-DAG-SAME: #[[EXPYAF1]] +// CHECK-DAG-SAME: #[[EXPXAF2]] +// CHECK-DAG-SAME: #[[EXPYAF2]] +// CHECK-DAG-SAME: #[[EXPZAF2]] +// CHECK-DAG-SAME: #[[EXPXAF3]] +// CHECK-DAG-SAME: #[[EXPVA1]] +// CHECK-DAG-SAME: #[[EXPVA2]] +// CHECK-DAG-SAME: #[[EXPVA3]] diff --git a/flang/test/Transforms/debug-module-1.fir b/flang/test/Transforms/debug-module-1.fir index 71457d32b1596..ede996f053835 100644 --- a/flang/test/Transforms/debug-module-1.fir +++ b/flang/test/Transforms/debug-module-1.fir @@ -30,11 +30,13 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<>} { // CHECK-DAG: #[[MOD:.*]] = #llvm.di_module<{{.*}}scope = #[[CU]], name = "helper"{{.*}}> // CHECK-DAG: #[[LOC1:.*]] = loc("{{.*}}test.f90":12{{.*}}) // CHECK-DAG: #[[GLI:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[GLIE:.*]] = #llvm.di_global_variable_expression // CHECK-DAG: #[[LOC2:.*]] = loc("{{.*}}test.f90":15{{.*}}) // CHECK-DAG: #[[GLR:.*]] = #llvm.di_global_variable +// CHECK-DAG: #[[GLRE:.*]] = #llvm.di_global_variable_expression // CHECK-DAG: #[[LOC3:.*]] = loc("{{.*}}test.f90":20{{.*}}) // CHECK-DAG: #[[TEST:.*]] = #llvm.di_subprogram<{{.*}}compileUnit = #[[CU]], scope = #[[MOD]], name = "test", linkageName = "_QMhelperPtest"{{.*}}line = 20, scopeLine = 20{{.*}}> -// CHECK-DAG: loc(fused<#[[GLI]]>[#[[LOC1]]]) -// CHECK-DAG: loc(fused<#[[GLR]]>[#[[LOC2]]]) +// CHECK-DAG: loc(fused<[#[[GLIE]]]>[#[[LOC1]]]) +// CHECK-DAG: loc(fused<[#[[GLRE]]]>[#[[LOC2]]]) // CHECK-DAG: loc(fused<#[[TEST]]>[#[[LOC3]]]) diff --git a/flang/test/Transforms/debug-module-2.fir b/flang/test/Transforms/debug-module-2.fir index c8d618ce34b26..32a25e303751e 100644 --- a/flang/test/Transforms/debug-module-2.fir +++ b/flang/test/Transforms/debug-module-2.fir @@ -20,11 +20,13 @@ module { #di_module = #llvm.di_module #di_global_variable = #llvm.di_global_variable #di_global_variable1 = #llvm.di_global_variable +#di_global_variable_expression = #llvm.di_global_variable_expression +#di_global_variable_expression1 = #llvm.di_global_variable_expression #loc1 = loc("test.f90":12:11) #loc2 = loc("test.f90":15:8) -#loc3 = loc(fused<#di_global_variable>[#loc1]) -#loc4 = loc(fused<#di_global_variable1>[#loc2]) +#loc3 = loc(fused<[#di_global_variable_expression]>[#loc1]) +#loc4 = loc(fused<[#di_global_variable_expression1]>[#loc2]) // CHECK-DAG: #[[GLI:.*]] = #llvm.di_global_variable<{{.*}}name = "gli", linkageName = "_QMhelperEgli"{{.*}}>