[flang-commits] [flang] [flang][debug] Allow non default array lower bounds. (PR #104467)
Abid Qadeer via flang-commits
flang-commits at lists.llvm.org
Fri Aug 16 02:49:32 PDT 2024
https://github.com/abidh updated https://github.com/llvm/llvm-project/pull/104467
>From cec5819f88bac641ac510576c24f1e72cb672f59 Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Tue, 13 Aug 2024 19:17:07 +0100
Subject: [PATCH 1/3] [flang][debug] Allow non default array lower bounds.
As mentioned in #98877, we currently always use 1 as lower bound for
fixed size arrays. This PR fixes this issue. It passes along `DeclareOp`
to type conversion functions and uses the shift information (if present)
to get the lower bound information. This was suggested by @jeanPerier in
https://github.com/llvm/llvm-project/pull/96746#issuecomment-2195164553
This PR also adds a small cleanup that type conversion functions don't
take Location now. It was initially added so that location of derived
types can be passed. But that information can be extracted from typeInfo
objects and we don't need to pass it along.
Fixes #98877.
---
.../lib/Optimizer/Transforms/AddDebugInfo.cpp | 21 +++---
.../Transforms/DebugTypeGenerator.cpp | 72 +++++++++++--------
.../Optimizer/Transforms/DebugTypeGenerator.h | 26 +++----
.../Integration/debug-fixed-array-type-2.f90 | 38 ++++++----
.../Transforms/debug-fixed-array-type.fir | 7 ++
5 files changed, 101 insertions(+), 63 deletions(-)
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index 3c067bf946cfc9..a3ee943cf68db8 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -65,7 +65,8 @@ class AddDebugInfoPass : public fir::impl::AddDebugInfoBase<AddDebugInfoPass> {
void handleGlobalOp(fir::GlobalOp glocalOp, mlir::LLVM::DIFileAttr fileAttr,
mlir::LLVM::DIScopeAttr scope,
- mlir::SymbolTable *symbolTable);
+ mlir::SymbolTable *symbolTable,
+ fir::cg::XDeclareOp declOp);
void handleFuncOp(mlir::func::FuncOp funcOp, mlir::LLVM::DIFileAttr fileAttr,
mlir::LLVM::DICompileUnitAttr cuAttr,
mlir::SymbolTable *symbolTable);
@@ -100,10 +101,9 @@ void AddDebugInfoPass::handleDeclareOp(fir::cg::XDeclareOp declOp,
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);
+ handleGlobalOp(global, fileAttr, scopeAttr, symbolTable, declOp);
return;
}
@@ -127,7 +127,7 @@ void AddDebugInfoPass::handleDeclareOp(fir::cg::XDeclareOp declOp,
}
auto tyAttr = typeGen.convertType(fir::unwrapRefType(declOp.getType()),
- fileAttr, scopeAttr, declOp.getLoc());
+ fileAttr, scopeAttr, declOp);
auto localVarAttr = mlir::LLVM::DILocalVariableAttr::get(
context, scopeAttr, mlir::StringAttr::get(context, result.second.name),
@@ -160,7 +160,8 @@ mlir::LLVM::DIModuleAttr AddDebugInfoPass::getOrCreateModuleAttr(
void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
mlir::LLVM::DIFileAttr fileAttr,
mlir::LLVM::DIScopeAttr scope,
- mlir::SymbolTable *symbolTable) {
+ mlir::SymbolTable *symbolTable,
+ fir::cg::XDeclareOp declOp) {
if (debugInfoIsAlreadySet(globalOp.getLoc()))
return;
mlir::ModuleOp module = getOperation();
@@ -200,8 +201,8 @@ void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
scope = getOrCreateModuleAttr(result.second.modules[0], fileAttr, scope,
line - 1, !globalOp.isInitialized());
}
- mlir::LLVM::DITypeAttr diType = typeGen.convertType(
- globalOp.getType(), fileAttr, scope, globalOp.getLoc());
+ mlir::LLVM::DITypeAttr diType =
+ typeGen.convertType(globalOp.getType(), fileAttr, scope, declOp);
auto gvAttr = mlir::LLVM::DIGlobalVariableAttr::get(
context, scope, mlir::StringAttr::get(context, result.second.name),
mlir::StringAttr::get(context, globalOp.getName()), fileAttr, line,
@@ -246,12 +247,12 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp,
llvm::SmallVector<mlir::LLVM::DITypeAttr> types;
fir::DebugTypeGenerator typeGen(module);
for (auto resTy : funcOp.getResultTypes()) {
- auto tyAttr = typeGen.convertType(resTy, fileAttr, cuAttr, funcOp.getLoc());
+ auto tyAttr = typeGen.convertType(resTy, fileAttr, cuAttr, nullptr);
types.push_back(tyAttr);
}
for (auto inTy : funcOp.getArgumentTypes()) {
auto tyAttr = typeGen.convertType(fir::unwrapRefType(inTy), fileAttr,
- cuAttr, funcOp.getLoc());
+ cuAttr, nullptr);
types.push_back(tyAttr);
}
@@ -358,7 +359,7 @@ void AddDebugInfoPass::runOnOperation() {
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);
+ handleGlobalOp(globalOp, fileAttr, cuAttr, &symbolTable, nullptr);
}
}
diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
index db559731552df2..30637c2ac9d5a7 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
@@ -83,8 +83,8 @@ static mlir::LLVM::DITypeAttr genPlaceholderType(mlir::MLIRContext *context) {
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertBoxedSequenceType(
fir::SequenceType seqTy, mlir::LLVM::DIFileAttr fileAttr,
- mlir::LLVM::DIScopeAttr scope, mlir::Location loc, bool genAllocated,
- bool genAssociated) {
+ mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp,
+ bool genAllocated, bool genAssociated) {
mlir::MLIRContext *context = module.getContext();
// FIXME: Assumed rank arrays not supported yet
@@ -114,7 +114,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertBoxedSequenceType(
llvm::SmallVector<mlir::LLVM::DINodeAttr> elements;
mlir::LLVM::DITypeAttr elemTy =
- convertType(seqTy.getEleTy(), fileAttr, scope, loc);
+ convertType(seqTy.getEleTy(), fileAttr, scope, declOp);
unsigned offset = dimsOffset;
const unsigned indexSize = dimsSize / 3;
for ([[maybe_unused]] auto _ : seqTy.getShape()) {
@@ -156,14 +156,28 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertBoxedSequenceType(
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
fir::SequenceType seqTy, mlir::LLVM::DIFileAttr fileAttr,
- mlir::LLVM::DIScopeAttr scope, mlir::Location loc) {
+ mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp) {
mlir::MLIRContext *context = module.getContext();
llvm::SmallVector<mlir::LLVM::DINodeAttr> elements;
mlir::LLVM::DITypeAttr elemTy =
- convertType(seqTy.getEleTy(), fileAttr, scope, loc);
-
- for (fir::SequenceType::Extent dim : seqTy.getShape()) {
+ convertType(seqTy.getEleTy(), fileAttr, scope, declOp);
+
+ // The seqTy.getShape() should have a value for each dimension of the array.
+ // But we can have a null declOp or declOp.getShift() can be an empty
+ // sequence (e.g. when default lower bound is used). We use an empty vector in
+ // that case.
+ for (auto [dimOpt, shiftOpt] : zip_longest(
+ seqTy.getShape(),
+ declOp ? declOp.getShift() : llvm::SmallVector<mlir::Value>())) {
+ // It is assumed that size of seqTy.getShape() will always be greater or
+ // equal to size of the 2nd argument of zip_longest so we should never have
+ // the scenario where dimOpt is nullopt.
+ if (!dimOpt) {
+ assert(dimOpt);
+ break;
+ }
+ fir::SequenceType::Extent dim = *dimOpt;
if (dim == seqTy.getUnknownExtent()) {
// FIXME: This path is taken for assumed size arrays but also for arrays
// with non constant extent. For the latter case, the DISubrangeAttr
@@ -174,15 +188,16 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
elements.push_back(subrangeTy);
} else {
auto intTy = mlir::IntegerType::get(context, 64);
- // FIXME: Only supporting lower bound of 1 at the moment. The
- // 'SequenceType' has information about the shape but not the shift. In
- // cases where the conversion originated during the processing of
- // 'DeclareOp', it may be possible to pass on this information. But the
- // type conversion should ideally be based on what information present in
- // the type class so that it works from everywhere (e.g. when it is part
- // of a module or a derived type.)
+ int64_t shift = 1;
+ if (shiftOpt) {
+ if (auto defOp = mlir::dyn_cast<mlir::arith::ConstantOp>(
+ shiftOpt->getDefiningOp())) {
+ if (auto iattr = mlir::dyn_cast<mlir::IntegerAttr>(defOp.getValue()))
+ shift = iattr.getInt();
+ }
+ }
auto countAttr = mlir::IntegerAttr::get(intTy, llvm::APInt(64, dim));
- auto lowerAttr = mlir::IntegerAttr::get(intTy, llvm::APInt(64, 1));
+ auto lowerAttr = mlir::IntegerAttr::get(intTy, llvm::APInt(64, shift));
auto subrangeTy = mlir::LLVM::DISubrangeAttr::get(
context, countAttr, lowerAttr, /*upperBound=*/nullptr,
/*stride=*/nullptr);
@@ -203,7 +218,8 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
fir::CharacterType charTy, mlir::LLVM::DIFileAttr fileAttr,
- mlir::LLVM::DIScopeAttr scope, mlir::Location loc, bool hasDescriptor) {
+ mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp,
+ bool hasDescriptor) {
mlir::MLIRContext *context = module.getContext();
// DWARF 5 says the following about the character encoding in 5.1.1.2.
@@ -250,21 +266,21 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertPointerLikeType(
mlir::Type elTy, mlir::LLVM::DIFileAttr fileAttr,
- mlir::LLVM::DIScopeAttr scope, mlir::Location loc, bool genAllocated,
- bool genAssociated) {
+ mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp,
+ bool genAllocated, bool genAssociated) {
mlir::MLIRContext *context = module.getContext();
// Arrays and character need different treatment because DWARF have special
// constructs for them to get the location from the descriptor. Rest of
// types are handled like pointer to underlying type.
if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(elTy))
- return convertBoxedSequenceType(seqTy, fileAttr, scope, loc, genAllocated,
- genAssociated);
+ return convertBoxedSequenceType(seqTy, fileAttr, scope, declOp,
+ genAllocated, genAssociated);
if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(elTy))
- return convertCharacterType(charTy, fileAttr, scope, loc,
+ return convertCharacterType(charTy, fileAttr, scope, declOp,
/*hasDescriptor=*/true);
- mlir::LLVM::DITypeAttr elTyAttr = convertType(elTy, fileAttr, scope, loc);
+ mlir::LLVM::DITypeAttr elTyAttr = convertType(elTy, fileAttr, scope, declOp);
return mlir::LLVM::DIDerivedTypeAttr::get(
context, llvm::dwarf::DW_TAG_pointer_type,
@@ -276,7 +292,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertPointerLikeType(
mlir::LLVM::DITypeAttr
DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
mlir::LLVM::DIScopeAttr scope,
- mlir::Location loc) {
+ fir::cg::XDeclareOp declOp) {
mlir::MLIRContext *context = module.getContext();
if (Ty.isInteger()) {
return genBasicType(context, mlir::StringAttr::get(context, "integer"),
@@ -306,22 +322,22 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
return genBasicType(context, mlir::StringAttr::get(context, "complex"),
bitWidth * 2, llvm::dwarf::DW_ATE_complex_float);
} else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(Ty)) {
- return convertSequenceType(seqTy, fileAttr, scope, loc);
+ return convertSequenceType(seqTy, fileAttr, scope, declOp);
} else if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(Ty)) {
- return convertCharacterType(charTy, fileAttr, scope, loc,
+ return convertCharacterType(charTy, fileAttr, scope, declOp,
/*hasDescriptor=*/false);
} else if (auto boxTy = mlir::dyn_cast_or_null<fir::BoxType>(Ty)) {
auto elTy = boxTy.getElementType();
if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(elTy))
- return convertBoxedSequenceType(seqTy, fileAttr, scope, loc, false,
+ return convertBoxedSequenceType(seqTy, fileAttr, scope, declOp, false,
false);
if (auto heapTy = mlir::dyn_cast_or_null<fir::HeapType>(elTy))
return convertPointerLikeType(heapTy.getElementType(), fileAttr, scope,
- loc, /*genAllocated=*/true,
+ declOp, /*genAllocated=*/true,
/*genAssociated=*/false);
if (auto ptrTy = mlir::dyn_cast_or_null<fir::PointerType>(elTy))
return convertPointerLikeType(ptrTy.getElementType(), fileAttr, scope,
- loc, /*genAllocated=*/false,
+ declOp, /*genAllocated=*/false,
/*genAssociated=*/true);
return genPlaceholderType(context);
} else {
diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
index ec881e8be7cadc..5ab6ca5e9f880e 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
@@ -13,6 +13,7 @@
#ifndef FORTRAN_OPTIMIZER_TRANSFORMS_DEBUGTYPEGENERATOR_H
#define FORTRAN_OPTIMIZER_TRANSFORMS_DEBUGTYPEGENERATOR_H
+#include "flang/Optimizer/CodeGen/CGOps.h"
#include "flang/Optimizer/Dialect/FIRType.h"
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
#include "flang/Optimizer/Dialect/Support/KindMapping.h"
@@ -28,33 +29,34 @@ class DebugTypeGenerator {
mlir::LLVM::DITypeAttr convertType(mlir::Type Ty,
mlir::LLVM::DIFileAttr fileAttr,
mlir::LLVM::DIScopeAttr scope,
- mlir::Location loc);
+ fir::cg::XDeclareOp declOp);
private:
mlir::LLVM::DITypeAttr convertSequenceType(fir::SequenceType seqTy,
mlir::LLVM::DIFileAttr fileAttr,
mlir::LLVM::DIScopeAttr scope,
- mlir::Location loc);
+ fir::cg::XDeclareOp declOp);
/// The 'genAllocated' is true when we want to generate 'allocated' field
/// in the DICompositeType. It is needed for the allocatable arrays.
/// Similarly, 'genAssociated' is used with 'pointer' type to generate
/// 'associated' field.
- mlir::LLVM::DITypeAttr
- convertBoxedSequenceType(fir::SequenceType seqTy,
- mlir::LLVM::DIFileAttr fileAttr,
- mlir::LLVM::DIScopeAttr scope, mlir::Location loc,
- bool genAllocated, bool genAssociated);
+ mlir::LLVM::DITypeAttr convertBoxedSequenceType(
+ fir::SequenceType seqTy, mlir::LLVM::DIFileAttr fileAttr,
+ mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp,
+ bool genAllocated, bool genAssociated);
mlir::LLVM::DITypeAttr convertCharacterType(fir::CharacterType charTy,
mlir::LLVM::DIFileAttr fileAttr,
mlir::LLVM::DIScopeAttr scope,
- mlir::Location loc,
+ fir::cg::XDeclareOp declOp,
bool hasDescriptor);
- mlir::LLVM::DITypeAttr
- convertPointerLikeType(mlir::Type elTy, mlir::LLVM::DIFileAttr fileAttr,
- mlir::LLVM::DIScopeAttr scope, mlir::Location loc,
- bool genAllocated, bool genAssociated);
+ mlir::LLVM::DITypeAttr convertPointerLikeType(mlir::Type elTy,
+ mlir::LLVM::DIFileAttr fileAttr,
+ mlir::LLVM::DIScopeAttr scope,
+ fir::cg::XDeclareOp declOp,
+ bool genAllocated,
+ bool genAssociated);
mlir::ModuleOp module;
KindMapping kindMapping;
diff --git a/flang/test/Integration/debug-fixed-array-type-2.f90 b/flang/test/Integration/debug-fixed-array-type-2.f90
index b34413458ad8d3..705c1da593c705 100644
--- a/flang/test/Integration/debug-fixed-array-type-2.f90
+++ b/flang/test/Integration/debug-fixed-array-type-2.f90
@@ -1,19 +1,22 @@
! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
-program mn
-
+module test
integer d1(3)
- integer d2(2, 5)
- real d3(6, 8, 7)
+ integer d2(1:4, -1:3)
+ real d3(-2:6, 0:5, 3:7)
+end
+
+program mn
+ use test
i8 = fn1(d1, d2, d3)
contains
function fn1(a1, b1, c1) result (res)
integer a1(3)
- integer b1(2, 5)
- real c1(6, 8, 7)
+ integer b1(-1:0, 5:9)
+ real c1(-2:6, 0:5, 3:7)
integer res
- res = a1(1) + b1(1,2) + c1(3, 3, 4)
+ res = a1(1) + b1(0,6) + c1(3, 3, 4)
end function
end program
@@ -24,17 +27,26 @@ function fn1(a1, b1, c1) result (res)
! CHECK-DAG: ![[SUB1:.*]] = !{![[R1]]}
! CHECK-DAG: ![[D1TY:.*]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[INT]], elements: ![[SUB1]])
-! CHECK-DAG: ![[R21:.*]] = !DISubrange(count: 2, lowerBound: 1)
-! CHECK-DAG: ![[R22:.*]] = !DISubrange(count: 5, lowerBound: 1)
+! CHECK-DAG: ![[R21:.*]] = !DISubrange(count: 4, 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: ![[R31:.*]] = !DISubrange(count: 6, lowerBound: 1)
-! CHECK-DAG: ![[R32:.*]] = !DISubrange(count: 8, lowerBound: 1)
-! CHECK-DAG: ![[R33:.*]] = !DISubrange(count: 7, lowerBound: 1)
+! CHECK-DAG: ![[R31:.*]] = !DISubrange(count: 9, lowerBound: -2)
+! CHECK-DAG: ![[R32:.*]] = !DISubrange(count: 6, lowerBound: 0)
+! CHECK-DAG: ![[R33:.*]] = !DISubrange(count: 5, lowerBound: 3)
! CHECK-DAG: ![[SUB3:.*]] = !{![[R31]], ![[R32]], ![[R33]]}
! CHECK-DAG: ![[D3TY:.*]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[REAL]], elements: ![[SUB3]])
+! CHECK-DAG: ![[B11:.*]] = !DISubrange(count: 2, lowerBound: -1)
+! CHECK-DAG: ![[B12:.*]] = !DISubrange(count: 5, lowerBound: 5)
+! CHECK-DAG: ![[B1:.*]] = !{![[B11]], ![[B12]]}
+! CHECK-DAG: ![[B1TY:.*]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[INT]], elements: ![[B1]])
+
+! CHECK-DAG: {{.*}}!DIGlobalVariable(name: "d1"{{.*}}type: ![[D1TY]]{{.*}})
+! CHECK-DAG: {{.*}}!DIGlobalVariable(name: "d2"{{.*}}type: ![[D2TY]]{{.*}})
+! CHECK-DAG: {{.*}}!DIGlobalVariable(name: "d3"{{.*}}type: ![[D3TY]]{{.*}})
+
! CHECK-DAG: !DILocalVariable(name: "a1", arg: 1{{.*}}type: ![[D1TY]])
-! CHECK-DAG: !DILocalVariable(name: "b1", arg: 2{{.*}}type: ![[D2TY]])
+! CHECK-DAG: !DILocalVariable(name: "b1", arg: 2{{.*}}type: ![[B1TY]])
! CHECK-DAG: !DILocalVariable(name: "c1", arg: 3{{.*}}type: ![[D3TY]])
diff --git a/flang/test/Transforms/debug-fixed-array-type.fir b/flang/test/Transforms/debug-fixed-array-type.fir
index d4ed0b97020898..1a7d8115908a07 100644
--- a/flang/test/Transforms/debug-fixed-array-type.fir
+++ b/flang/test/Transforms/debug-fixed-array-type.fir
@@ -8,12 +8,16 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
%c5 = arith.constant 5 : index
%c2 = arith.constant 2 : index
%c3 = arith.constant 3 : index
+ %c-2 = arith.constant -2 : index loc(#loc3)
+ %c4 = arith.constant 4 : index loc(#loc3)
%0 = fir.alloca !fir.array<3xi32> {bindc_name = "d1", uniq_name = "_QFEd1"}
%1 = fircg.ext_declare %0(%c3) {uniq_name = "_QFEd1"} : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<!fir.array<3xi32>> loc(#loc1)
%2 = fir.address_of(@_QFEd2) : !fir.ref<!fir.array<2x5xi32>>
%3 = fircg.ext_declare %2(%c2, %c5) {uniq_name = "_QFEd2"} : (!fir.ref<!fir.array<2x5xi32>>, index, index) -> !fir.ref<!fir.array<2x5xi32>> loc(#loc2)
%4 = fir.address_of(@_QFEd3) : !fir.ref<!fir.array<6x8x7xf32>>
%5 = fircg.ext_declare %4(%c6, %c8, %c7) {uniq_name = "_QFEd3"} : (!fir.ref<!fir.array<6x8x7xf32>>, index, index, index) -> !fir.ref<!fir.array<6x8x7xf32>> loc(#loc3)
+ %6 = fir.address_of(@_QFEd4) : !fir.ref<!fir.array<6x7xi32>>
+ %7 = fircg.ext_declare %6(%c6, %c7) origin %c-2, %c4 {uniq_name = "_QFEd4"} : (!fir.ref<!fir.array<6x7xi32>>, index, index, index, index) -> !fir.ref<!fir.array<6x7xi32>> loc(#loc5)
return
} loc(#loc4)
}
@@ -22,6 +26,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
#loc2 = loc("test.f90":6:11)
#loc3 = loc("test.f90":7:11)
#loc4 = loc("test.f90":2:8)
+#loc5 = loc("test.f90":8:11)
// CHECK-DAG: #[[INT:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer", sizeInBits = 32, encoding = DW_ATE_signed>
@@ -29,6 +34,8 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
// CHECK-DAG: #[[D1TY:.*]] = #llvm.di_composite_type<tag = DW_TAG_array_type{{.*}}baseType = #[[INT]], elements = #llvm.di_subrange<count = 3 : i64, lowerBound = 1 : i64>>
// CHECK-DAG: #[[D2TY:.*]] = #llvm.di_composite_type<tag = DW_TAG_array_type{{.*}}baseType = #[[INT]], elements = #llvm.di_subrange<count = 2 : i64, lowerBound = 1 : i64>, #llvm.di_subrange<count = 5 : i64, lowerBound = 1 : i64>>
// CHECK-DAG: #[[D3TY:.*]] = #llvm.di_composite_type<tag = DW_TAG_array_type{{.*}}baseType = #[[REAL]], elements = #llvm.di_subrange<count = 6 : i64, lowerBound = 1 : i64>, #llvm.di_subrange<count = 8 : i64, lowerBound = 1 : i64>, #llvm.di_subrange<count = 7 : i64, lowerBound = 1 : i64>>
+// CHECK-DAG: #[[D4TY:.*]] = #llvm.di_composite_type<tag = DW_TAG_array_type, baseType = #di_basic_type, elements = #llvm.di_subrange<count = 6 : i64, lowerBound = -2 : i64>, #llvm.di_subrange<count = 7 : i64, lowerBound = 4 : i64>>
// CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "d1"{{.*}}type = #[[D1TY]]>
// CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "d2"{{.*}}type = #[[D2TY]]>
// CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "d3"{{.*}}type = #[[D3TY]]>
+// CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "d4"{{.*}}type = #[[D4TY]]>
>From 478b0b270c82df54338a5d8e50e826e8e67c32b5 Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Thu, 15 Aug 2024 17:03:54 +0100
Subject: [PATCH 2/3] [flang][debug] Add comments for constant value arguments.
---
flang/lib/Optimizer/Transforms/AddDebugInfo.cpp | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index a3ee943cf68db8..30fc4185575e61 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -247,12 +247,13 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp,
llvm::SmallVector<mlir::LLVM::DITypeAttr> types;
fir::DebugTypeGenerator typeGen(module);
for (auto resTy : funcOp.getResultTypes()) {
- auto tyAttr = typeGen.convertType(resTy, fileAttr, cuAttr, nullptr);
+ auto tyAttr =
+ typeGen.convertType(resTy, fileAttr, cuAttr, /*declOp=*/nullptr);
types.push_back(tyAttr);
}
for (auto inTy : funcOp.getArgumentTypes()) {
auto tyAttr = typeGen.convertType(fir::unwrapRefType(inTy), fileAttr,
- cuAttr, nullptr);
+ cuAttr, /*declOp=*/nullptr);
types.push_back(tyAttr);
}
@@ -359,7 +360,8 @@ void AddDebugInfoPass::runOnOperation() {
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, nullptr);
+ handleGlobalOp(globalOp, fileAttr, cuAttr, &symbolTable,
+ /*declOp=*/nullptr);
}
}
>From 0b6ce90b5c38610a9d866b7f263d3f195b1414a6 Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Fri, 16 Aug 2024 10:42:28 +0100
Subject: [PATCH 3/3] Use index instead of zip_longest.
It makes the code simpler.
---
.../Transforms/DebugTypeGenerator.cpp | 22 +++++--------------
1 file changed, 5 insertions(+), 17 deletions(-)
diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
index 30637c2ac9d5a7..c31d5a38416534 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
@@ -163,21 +163,8 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
mlir::LLVM::DITypeAttr elemTy =
convertType(seqTy.getEleTy(), fileAttr, scope, declOp);
- // The seqTy.getShape() should have a value for each dimension of the array.
- // But we can have a null declOp or declOp.getShift() can be an empty
- // sequence (e.g. when default lower bound is used). We use an empty vector in
- // that case.
- for (auto [dimOpt, shiftOpt] : zip_longest(
- seqTy.getShape(),
- declOp ? declOp.getShift() : llvm::SmallVector<mlir::Value>())) {
- // It is assumed that size of seqTy.getShape() will always be greater or
- // equal to size of the 2nd argument of zip_longest so we should never have
- // the scenario where dimOpt is nullopt.
- if (!dimOpt) {
- assert(dimOpt);
- break;
- }
- fir::SequenceType::Extent dim = *dimOpt;
+ unsigned index = 0;
+ for (fir::SequenceType::Extent dim : seqTy.getShape()) {
if (dim == seqTy.getUnknownExtent()) {
// FIXME: This path is taken for assumed size arrays but also for arrays
// with non constant extent. For the latter case, the DISubrangeAttr
@@ -189,9 +176,9 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
} else {
auto intTy = mlir::IntegerType::get(context, 64);
int64_t shift = 1;
- if (shiftOpt) {
+ if (declOp && declOp.getShift().size() > index) {
if (auto defOp = mlir::dyn_cast<mlir::arith::ConstantOp>(
- shiftOpt->getDefiningOp())) {
+ declOp.getShift()[index].getDefiningOp())) {
if (auto iattr = mlir::dyn_cast<mlir::IntegerAttr>(defOp.getValue()))
shift = iattr.getInt();
}
@@ -203,6 +190,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
/*stride=*/nullptr);
elements.push_back(subrangeTy);
}
+ ++index;
}
// Apart from arrays, the `DICompositeTypeAttr` is used for other things like
// structure types. Many of its fields which are not applicable to arrays
More information about the flang-commits
mailing list