[flang-commits] [flang] a993dfc - [flang][debug] Support assumed-rank arrays. (#114404)

via flang-commits flang-commits at lists.llvm.org
Tue Nov 5 10:49:32 PST 2024


Author: Abid Qadeer
Date: 2024-11-05T18:49:29Z
New Revision: a993dfcdbf64ef7a8bd7e5ec4d97287b650d4f50

URL: https://github.com/llvm/llvm-project/commit/a993dfcdbf64ef7a8bd7e5ec4d97287b650d4f50
DIFF: https://github.com/llvm/llvm-project/commit/a993dfcdbf64ef7a8bd7e5ec4d97287b650d4f50.diff

LOG: [flang][debug] Support assumed-rank arrays. (#114404)

The assumed-rank array are represented by DIGenericSubrange in debug
metadata. We have to provide 2 things.

1. Expression to get rank value at the runtime from descriptor.

2. Assuming the dimension number for which we want the array information
has been put on the DWARF expression stack, expressions which will
extract the lowerBound, count and stride information from the descriptor
for the said dimension.

With this patch in place, this is how I see an assumed_rank variable
being evaluated by GDB.

```
function mean(x) result(y)
integer, intent(in) :: x(..)
...
end

program main
use mod
implicit none
integer :: x1,xvec(3),xmat(3,3),xtens(3,3,3)
x1 = 5
xvec = 6
xmat = 7
xtens = 8
print *,mean(xvec), mean(xmat), mean(xtens), mean(x1)
end program main

(gdb) p x
$1 = (6, 6, 6)

(gdb) p x
$2 = ((7, 7, 7) (7, 7, 7) (7, 7, 7))

(gdb) p x
$3 = (((8, 8, 8) (8, 8, 8) (8, 8, 8)) ((8, 8, 8) (8, 8, 8) (8, 8, 8)) ((8, 8, 8) (8, 8, 8) (8, 8, 8)))

(gdb) p x
$4 = 5
```

Added: 
    flang/test/Transforms/debug-assumed-rank-array.fir

Modified: 
    flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
    flang/lib/Optimizer/Transforms/DebugTypeGenerator.h

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
index a070c87137fa16..0187524d76cdd5 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
@@ -58,12 +58,17 @@ DebugTypeGenerator::DebugTypeGenerator(mlir::ModuleOp m,
   mlir::Type llvmDimsType = getDescFieldTypeModel<kDimsPosInBox>()(context);
   mlir::Type llvmPtrType = getDescFieldTypeModel<kAddrPosInBox>()(context);
   mlir::Type llvmLenType = getDescFieldTypeModel<kElemLenPosInBox>()(context);
+  mlir::Type llvmRankType = getDescFieldTypeModel<kRankPosInBox>()(context);
+
   dimsOffset =
       getComponentOffset<kDimsPosInBox>(*dataLayout, context, llvmDimsType);
   dimsSize = dataLayout->getTypeSize(llvmDimsType);
   ptrSize = dataLayout->getTypeSize(llvmPtrType);
+  rankSize = dataLayout->getTypeSize(llvmRankType);
   lenOffset =
       getComponentOffset<kElemLenPosInBox>(*dataLayout, context, llvmLenType);
+  rankOffset =
+      getComponentOffset<kRankPosInBox>(*dataLayout, context, llvmRankType);
 }
 
 static mlir::LLVM::DITypeAttr genBasicType(mlir::MLIRContext *context,
@@ -114,10 +119,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertBoxedSequenceType(
     bool genAllocated, bool genAssociated) {
 
   mlir::MLIRContext *context = module.getContext();
-  // FIXME: Assumed rank arrays not supported yet
-  if (seqTy.hasUnknownShape())
-    return genPlaceholderType(context);
-
+  llvm::SmallVector<mlir::LLVM::DINodeAttr> elements;
   llvm::SmallVector<mlir::LLVM::DIExpressionElemAttr> ops;
   auto addOp = [&](unsigned opc, llvm::ArrayRef<uint64_t> vals) {
     ops.push_back(mlir::LLVM::DIExpressionElemAttr::get(context, opc, vals));
@@ -129,6 +131,58 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertBoxedSequenceType(
   // dataLocation = *base_addr
   mlir::LLVM::DIExpressionAttr dataLocation =
       mlir::LLVM::DIExpressionAttr::get(context, ops);
+  ops.clear();
+
+  mlir::LLVM::DITypeAttr elemTy =
+      convertType(seqTy.getEleTy(), fileAttr, scope, declOp);
+
+  // Assumed-rank arrays
+  if (seqTy.hasUnknownShape()) {
+    addOp(llvm::dwarf::DW_OP_push_object_address, {});
+    addOp(llvm::dwarf::DW_OP_plus_uconst, {rankOffset});
+    addOp(llvm::dwarf::DW_OP_deref_size, {rankSize});
+    mlir::LLVM::DIExpressionAttr rank =
+        mlir::LLVM::DIExpressionAttr::get(context, ops);
+    ops.clear();
+
+    auto genSubrangeOp = [&](unsigned field) -> mlir::LLVM::DIExpressionAttr {
+      // The dwarf expression for generic subrange assumes that dimension for
+      // which it is being generated is already pushed on the stack. Here is the
+      // formula we will use to calculate count for example.
+      // *(base_addr + offset_count_0 + (dimsSize x dimension_number)).
+      // where offset_count_0 is offset of the count field for the 0th dimension
+      addOp(llvm::dwarf::DW_OP_push_object_address, {});
+      addOp(llvm::dwarf::DW_OP_over, {});
+      addOp(llvm::dwarf::DW_OP_constu, {dimsSize});
+      addOp(llvm::dwarf::DW_OP_mul, {});
+      addOp(llvm::dwarf::DW_OP_plus_uconst,
+            {dimsOffset + ((dimsSize / 3) * field)});
+      addOp(llvm::dwarf::DW_OP_plus, {});
+      addOp(llvm::dwarf::DW_OP_deref, {});
+      mlir::LLVM::DIExpressionAttr attr =
+          mlir::LLVM::DIExpressionAttr::get(context, ops);
+      ops.clear();
+      return attr;
+    };
+
+    mlir::LLVM::DIExpressionAttr lowerAttr = genSubrangeOp(kDimLowerBoundPos);
+    mlir::LLVM::DIExpressionAttr countAttr = genSubrangeOp(kDimExtentPos);
+    mlir::LLVM::DIExpressionAttr strideAttr = genSubrangeOp(kDimStridePos);
+
+    auto subrangeTy = mlir::LLVM::DIGenericSubrangeAttr::get(
+        context, countAttr, lowerAttr, /*upperBound=*/nullptr, strideAttr);
+    elements.push_back(subrangeTy);
+
+    return mlir::LLVM::DICompositeTypeAttr::get(
+        context, llvm::dwarf::DW_TAG_array_type, /*name=*/nullptr,
+        /*file=*/nullptr, /*line=*/0, /*scope=*/nullptr, elemTy,
+        mlir::LLVM::DIFlags::Zero, /*sizeInBits=*/0, /*alignInBits=*/0,
+        elements, dataLocation, rank, /*allocated=*/nullptr,
+        /*associated=*/nullptr);
+  }
+
+  addOp(llvm::dwarf::DW_OP_push_object_address, {});
+  addOp(llvm::dwarf::DW_OP_deref, {});
   addOp(llvm::dwarf::DW_OP_lit0, {});
   addOp(llvm::dwarf::DW_OP_ne, {});
 
@@ -139,9 +193,6 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertBoxedSequenceType(
   mlir::LLVM::DIExpressionAttr associated = genAssociated ? valid : nullptr;
   ops.clear();
 
-  llvm::SmallVector<mlir::LLVM::DINodeAttr> elements;
-  mlir::LLVM::DITypeAttr elemTy =
-      convertType(seqTy.getEleTy(), fileAttr, scope, declOp);
   unsigned offset = dimsOffset;
   unsigned index = 0;
   mlir::IntegerType intTy = mlir::IntegerType::get(context, 64);

diff  --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
index c1fce4bdae5ce5..7daa0af166e697 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
@@ -89,6 +89,8 @@ class DebugTypeGenerator {
   std::uint64_t dimsOffset;
   std::uint64_t ptrSize;
   std::uint64_t lenOffset;
+  std::uint64_t rankOffset;
+  std::uint64_t rankSize;
   llvm::DenseMap<mlir::Type, mlir::LLVM::DITypeAttr> typeCache;
 };
 

diff  --git a/flang/test/Transforms/debug-assumed-rank-array.fir b/flang/test/Transforms/debug-assumed-rank-array.fir
new file mode 100644
index 00000000000000..ce474cd259619b
--- /dev/null
+++ b/flang/test/Transforms/debug-assumed-rank-array.fir
@@ -0,0 +1,14 @@
+// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
+  func.func @_QFPfn(%arg0: !fir.box<!fir.array<*:i32>> )  {
+    %1 = fir.undefined !fir.dscope
+    %2 = fircg.ext_declare %arg0 dummy_scope %1 {uniq_name = "_QFFfnEx"} : (!fir.box<!fir.array<*:i32>>, !fir.dscope) -> !fir.box<!fir.array<*:i32>> loc(#loc2)
+    return
+  } loc(#loc1)
+}
+#loc1 = loc("test1.f90":1:1)
+#loc2 = loc("test1.f90":3:16)
+
+// CHECK: #[[TY:.*]] = #llvm.di_composite_type<tag = DW_TAG_array_type{{.*}}elements = #llvm.di_generic_subrange<count = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_over, DW_OP_constu(24), DW_OP_mul, DW_OP_plus_uconst(32), DW_OP_plus, DW_OP_deref]>, lowerBound = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_over, DW_OP_constu(24), DW_OP_mul, DW_OP_plus_uconst(24), DW_OP_plus, DW_OP_deref]>, stride = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_over, DW_OP_constu(24), DW_OP_mul, DW_OP_plus_uconst(40), DW_OP_plus, DW_OP_deref]>>, dataLocation = <[DW_OP_push_object_address, DW_OP_deref]>, rank = <[DW_OP_push_object_address, DW_OP_plus_uconst(20), DW_OP_deref_size(1)]>>
+// CHECK: #llvm.di_local_variable<{{.*}}name = "x"{{.*}}type = #[[TY]]{{.*}}>


        


More information about the flang-commits mailing list