Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[flang][debug] Fix issues with local variables. #98661

Merged
merged 2 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 42 additions & 16 deletions flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ class AddDebugInfoPass : public fir::impl::AddDebugInfoBase<AddDebugInfoPass> {
void handleDeclareOp(fir::cg::XDeclareOp declOp,
mlir::LLVM::DIFileAttr fileAttr,
mlir::LLVM::DIScopeAttr scopeAttr,
fir::DebugTypeGenerator &typeGen);
fir::DebugTypeGenerator &typeGen,
mlir::SymbolTable *symbolTable);

public:
AddDebugInfoPass(fir::AddDebugInfoOptions options) : Base(options) {}
Expand All @@ -63,7 +64,8 @@ class AddDebugInfoPass : public fir::impl::AddDebugInfoBase<AddDebugInfoPass> {
mlir::LLVM::DIScopeAttr scope, unsigned line, bool decl);

void handleGlobalOp(fir::GlobalOp glocalOp, mlir::LLVM::DIFileAttr fileAttr,
mlir::LLVM::DIScopeAttr scope);
mlir::LLVM::DIScopeAttr scope,
mlir::SymbolTable *symbolTable);
};

static uint32_t getLineFromLoc(mlir::Location loc) {
Expand All @@ -73,19 +75,32 @@ static uint32_t getLineFromLoc(mlir::Location loc) {
return line;
}

bool debugInfoIsAlreadySet(mlir::Location loc) {
if (mlir::isa<mlir::FusedLoc>(loc))
return true;
return false;
}

} // namespace

void AddDebugInfoPass::handleDeclareOp(fir::cg::XDeclareOp declOp,
mlir::LLVM::DIFileAttr fileAttr,
mlir::LLVM::DIScopeAttr scopeAttr,
fir::DebugTypeGenerator &typeGen) {
fir::DebugTypeGenerator &typeGen,
mlir::SymbolTable *symbolTable) {
mlir::MLIRContext *context = &getContext();
mlir::OpBuilder builder(context);
auto result = fir::NameUniquer::deconstruct(declOp.getUniqName());

if (result.first != fir::NameUniquer::NameKind::VARIABLE)
return;

// If this DeclareOp actually represents a global then treat it as such.
if (auto global = symbolTable->lookup<fir::GlobalOp>(declOp.getUniqName())) {
handleGlobalOp(global, fileAttr, scopeAttr, symbolTable);
return;
}

// Only accept local variables.
if (result.second.procs.empty())
return;
Expand Down Expand Up @@ -138,7 +153,10 @@ mlir::LLVM::DIModuleAttr AddDebugInfoPass::getOrCreateModuleAttr(

void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
mlir::LLVM::DIFileAttr fileAttr,
mlir::LLVM::DIScopeAttr scope) {
mlir::LLVM::DIScopeAttr scope,
mlir::SymbolTable *symbolTable) {
if (debugInfoIsAlreadySet(globalOp.getLoc()))
return;
mlir::ModuleOp module = getOperation();
mlir::MLIRContext *context = &getContext();
fir::DebugTypeGenerator typeGen(module);
Expand All @@ -163,12 +181,19 @@ void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
// 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;
if (result.second.procs.empty()) {
// Only look for module if this variable is not part of a function.
if (result.second.modules.empty())
return;

scope = getOrCreateModuleAttr(result.second.modules[0], fileAttr, scope,
line - 1, !globalOp.isInitialized());
// Modules are generated at compile unit scope
if (mlir::LLVM::DISubprogramAttr sp =
mlir::dyn_cast_if_present<mlir::LLVM::DISubprogramAttr>(scope))
scope = sp.getCompileUnit();

scope = getOrCreateModuleAttr(result.second.modules[0], fileAttr, scope,
line - 1, !globalOp.isInitialized());
}
mlir::LLVM::DITypeAttr diType = typeGen.convertType(
globalOp.getType(), fileAttr, scope, globalOp.getLoc());
auto gvAttr = mlir::LLVM::DIGlobalVariableAttr::get(
Expand All @@ -182,6 +207,7 @@ void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
void AddDebugInfoPass::runOnOperation() {
mlir::ModuleOp module = getOperation();
mlir::MLIRContext *context = &getContext();
mlir::SymbolTable symbolTable(module);
mlir::OpBuilder builder(context);
llvm::StringRef fileName;
std::string filePath;
Expand Down Expand Up @@ -218,17 +244,11 @@ void AddDebugInfoPass::runOnOperation() {
llvm::dwarf::getLanguage("DW_LANG_Fortran95"), fileAttr, producer,
isOptimized, debugLevel);

if (debugLevel == mlir::LLVM::DIEmissionKind::Full) {
// Process 'GlobalOp' only if full debug info is requested.
for (auto globalOp : module.getOps<fir::GlobalOp>())
handleGlobalOp(globalOp, fileAttr, cuAttr);
}

module.walk([&](mlir::func::FuncOp funcOp) {
mlir::Location l = funcOp->getLoc();
// If fused location has already been created then nothing to do
// Otherwise, create a fused location.
if (mlir::dyn_cast<mlir::FusedLoc>(l))
if (debugInfoIsAlreadySet(l))
return;

unsigned int CC = (funcOp.getName() == fir::NameUniquer::doProgramEntry())
Expand Down Expand Up @@ -293,9 +313,15 @@ void AddDebugInfoPass::runOnOperation() {
return;

funcOp.walk([&](fir::cg::XDeclareOp declOp) {
handleDeclareOp(declOp, fileAttr, spAttr, typeGen);
handleDeclareOp(declOp, fileAttr, spAttr, typeGen, &symbolTable);
});
});
// Process any global which was not processed through DeclareOp.
if (debugLevel == mlir::LLVM::DIEmissionKind::Full) {
// Process 'GlobalOp' only if full debug info is requested.
for (auto globalOp : module.getOps<fir::GlobalOp>())
handleGlobalOp(globalOp, fileAttr, cuAttr, &symbolTable);
}
}

std::unique_ptr<mlir::Pass>
Expand Down
3 changes: 0 additions & 3 deletions flang/test/Integration/debug-fixed-array-type-2.f90
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,17 @@ function fn1(a1, b1, c1) result (res)
! CHECK-DAG: ![[R1:.*]] = !DISubrange(count: 3, lowerBound: 1)
! CHECK-DAG: ![[SUB1:.*]] = !{![[R1]]}
! CHECK-DAG: ![[D1TY:.*]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[INT]], elements: ![[SUB1]])
! CHECK-DAG: !DILocalVariable(name: "d1"{{.*}}type: ![[D1TY]])

! CHECK-DAG: ![[R21:.*]] = !DISubrange(count: 2, lowerBound: 1)
! CHECK-DAG: ![[R22:.*]] = !DISubrange(count: 5, lowerBound: 1)
! CHECK-DAG: ![[SUB2:.*]] = !{![[R21]], ![[R22]]}
! CHECK-DAG: ![[D2TY:.*]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[INT]], elements: ![[SUB2]])
! CHECK-DAG: !DILocalVariable(name: "d2"{{.*}}type: ![[D2TY]])

! CHECK-DAG: ![[R31:.*]] = !DISubrange(count: 6, lowerBound: 1)
! CHECK-DAG: ![[R32:.*]] = !DISubrange(count: 8, lowerBound: 1)
! CHECK-DAG: ![[R33:.*]] = !DISubrange(count: 7, lowerBound: 1)
! CHECK-DAG: ![[SUB3:.*]] = !{![[R31]], ![[R32]], ![[R33]]}
! CHECK-DAG: ![[D3TY:.*]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[REAL]], elements: ![[SUB3]])
! CHECK-DAG: !DILocalVariable(name: "d3"{{.*}}type: ![[D3TY]])

! CHECK-DAG: !DILocalVariable(name: "a1", arg: 1{{.*}}type: ![[D1TY]])
! CHECK-DAG: !DILocalVariable(name: "b1", arg: 2{{.*}}type: ![[D2TY]])
Expand Down
52 changes: 52 additions & 0 deletions flang/test/Transforms/debug-local-global-storage-1.fir
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s

module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<i64, dense<64> : vector<2xi64>>, #dlti.dl_entry<!llvm.ptr<272>, dense<64> : vector<4xi64>>, #dlti.dl_entry<!llvm.ptr<271>, dense<32> : vector<4xi64>>, #dlti.dl_entry<!llvm.ptr<270>, dense<32> : vector<4xi64>>, #dlti.dl_entry<f128, dense<128> : vector<2xi64>>, #dlti.dl_entry<f80, dense<128> : vector<2xi64>>, #dlti.dl_entry<i128, dense<128> : vector<2xi64>>, #dlti.dl_entry<i8, dense<8> : vector<2xi64>>, #dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi64>>, #dlti.dl_entry<i1, dense<8> : vector<2xi64>>, #dlti.dl_entry<f16, dense<16> : vector<2xi64>>, #dlti.dl_entry<f64, dense<64> : vector<2xi64>>, #dlti.dl_entry<i32, dense<32> : vector<2xi64>>, #dlti.dl_entry<i16, dense<16> : vector<2xi64>>, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>, #dlti.dl_entry<"dlti.endianness", "little">>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"} {
func.func @_QMexamplePmod_sub() {
%c2 = arith.constant 2 : index
%1 = fir.address_of(@_QMexampleEmod_arr) : !fir.ref<!fir.array<2x2xi32>>
%2 = fircg.ext_declare %1(%c2, %c2) {uniq_name = "_QMexampleEmod_arr"} : (!fir.ref<!fir.array<2x2xi32>>, index, index) -> !fir.ref<!fir.array<2x2xi32>> loc(#loc4)
%3 = fir.address_of(@_QMexampleFmod_subEss) : !fir.ref<i32>
%4 = fircg.ext_declare %3 {uniq_name = "_QMexampleFmod_subEss"} : (!fir.ref<i32>) -> !fir.ref<i32> loc(#loc5)
return
} loc(#loc6)
func.func @_QQmain() attributes {fir.bindc_name = "test"} {
%c3 = arith.constant 3 : index
%c4 = arith.constant 4 : index
%1 = fir.address_of(@_QFEarr) : !fir.ref<!fir.array<3x4xi32>>
%2 = fircg.ext_declare %1(%c3, %c4) {uniq_name = "_QFEarr"} : (!fir.ref<!fir.array<3x4xi32>>, index, index) -> !fir.ref<!fir.array<3x4xi32>> loc(#loc2)
%3 = fir.address_of(@_QFEs) : !fir.ref<i32>
%4 = fircg.ext_declare %3 {uniq_name = "_QFEs"} : (!fir.ref<i32>) -> !fir.ref<i32> loc(#loc3)
return
} loc(#loc1)
fir.global @_QMexampleEmod_arr : !fir.array<2x2xi32> {
%0 = fir.zero_bits !fir.array<2x2xi32>
fir.has_value %0 : !fir.array<2x2xi32>
} loc(#loc4)
fir.global internal @_QMexampleFmod_subEss : i32 {
%c2_i32 = arith.constant 2 : i32
fir.has_value %c2_i32 : i32
} loc(#loc5)
fir.global internal @_QFEarr : !fir.array<3x4xi32> {
%0 = fir.zero_bits !fir.array<3x4xi32>
fir.has_value %0 : !fir.array<3x4xi32>
} loc(#loc2)
fir.global internal @_QFEs : i32 {
%c2_i32 = arith.constant 2 : i32
fir.has_value %c2_i32 : i32
} loc(#loc3)
}
#loc1 = loc("test.f90":21:1)
#loc2 = loc("test.f90":22:1)
#loc3 = loc("test.f90":23:1)
#loc4 = loc("test.f90":5:1)
#loc5 = loc("test.f90":12:1)
#loc6 = loc("test.f90":10:1)

// CHECK-DAG: #[[CU:.*]] = #llvm.di_compile_unit<{{.*}}>
// CHECK-DAG: #[[MOD:.*]] = #llvm.di_module<{{.*}}scope = #[[CU]]{{.*}}name = "example"{{.*}}>
// CHECK-DAG: #[[SP:.*]] = #llvm.di_subprogram<{{.*}}name = "_QQmain"{{.*}}>
// CHECK-DAG: #[[MOD_SP:.*]] = #llvm.di_subprogram<{{.*}}name = "mod_sub"{{.*}}>
// CHECK-DAG: #llvm.di_global_variable<scope = #[[SP]], name = "arr"{{.*}}line = 22{{.*}}>
// CHECK-DAG: #llvm.di_global_variable<scope = #[[SP]], name = "s"{{.*}}line = 23{{.*}}>
// CHECK-DAG: #llvm.di_global_variable<scope = #[[MOD_SP]], name = "ss"{{.*}}line = 12{{.*}}>
// CHECK-DAG: #llvm.di_global_variable<scope = #[[MOD]], name = "mod_arr"{{.*}}line = 5{{.*}}>
Loading