[flang-commits] [flang] 21d2991 - [Flang] Enable support for conversion of recursive record types

Kiran Chandramohan via flang-commits flang-commits at lists.llvm.org
Tue Jan 4 05:55:21 PST 2022


Author: Kiran Chandramohan
Date: 2022-01-04T13:53:58Z
New Revision: 21d299172e23a37fc251ce69dc31032a6a4a2bfe

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

LOG: [Flang] Enable support for conversion of recursive record types

Uses the recursive type conversion implemented in D113579, D113580.
Tests check for recursive and mutually recursive types.

Note: The downstream implementation for recursive types is a bit old
and is based on a static map. This was removed while upstreaming
(https://reviews.llvm.org/D112961) based on review comments. Since
the recursive type conversion is now available in MLIR we are using
that. If this patch is accepted we can use the same in the downstream
implementation.
Part of upstreaming flang from fir-dev branch of https://github.com/flang-compiler/f18-llvm-project.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D115937

Co-authored-by: Eric Schweitz <eschweitz at nvidia.com>

Added: 
    flang/test/Fir/recursive-type.fir

Modified: 
    flang/lib/Optimizer/CodeGen/TypeConverter.h

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/CodeGen/TypeConverter.h b/flang/lib/Optimizer/CodeGen/TypeConverter.h
index 91e8ebfea7d72..d96b752be1b81 100644
--- a/flang/lib/Optimizer/CodeGen/TypeConverter.h
+++ b/flang/lib/Optimizer/CodeGen/TypeConverter.h
@@ -80,8 +80,10 @@ class LLVMTypeConverter : public mlir::LLVMTypeConverter {
     });
     addConversion(
         [&](fir::PointerType pointer) { return convertPointerLike(pointer); });
-    addConversion(
-        [&](fir::RecordType derived) { return convertRecordType(derived); });
+    addConversion([&](fir::RecordType derived, SmallVectorImpl<Type> &results,
+                      ArrayRef<Type> callStack) {
+      return convertRecordType(derived, results, callStack);
+    });
     addConversion([&](fir::FieldType field) {
       // Convert to i32 because of LLVM GEP indexing restriction.
       return mlir::IntegerType::get(field.getContext(), 32);
@@ -127,16 +129,23 @@ class LLVMTypeConverter : public mlir::LLVMTypeConverter {
   mlir::Type indexType() { return mlir::IntegerType::get(&getContext(), 64); }
 
   // fir.type<name(p : TY'...){f : TY...}>  -->  llvm<"%name = { ty... }">
-  mlir::Type convertRecordType(fir::RecordType derived) {
+  llvm::Optional<LogicalResult>
+  convertRecordType(fir::RecordType derived, SmallVectorImpl<Type> &results,
+                    ArrayRef<Type> callStack) {
     auto name = derived.getName();
     auto st = mlir::LLVM::LLVMStructType::getIdentified(&getContext(), name);
+    if (llvm::count(callStack, derived) > 1) {
+      results.push_back(st);
+      return success();
+    }
     llvm::SmallVector<mlir::Type> members;
     for (auto mem : derived.getTypeList()) {
       members.push_back(convertType(mem.second).cast<mlir::Type>());
     }
-    if (mlir::succeeded(st.setBody(members, /*isPacked=*/false)))
-      return st;
-    return mlir::Type();
+    if (mlir::failed(st.setBody(members, /*isPacked=*/false)))
+      return failure();
+    results.push_back(st);
+    return success();
   }
 
   // Is an extended descriptor needed given the element type of a fir.box type ?

diff  --git a/flang/test/Fir/recursive-type.fir b/flang/test/Fir/recursive-type.fir
new file mode 100644
index 0000000000000..bd97f9e6225e7
--- /dev/null
+++ b/flang/test/Fir/recursive-type.fir
@@ -0,0 +1,19 @@
+// Test lowering FIR to LLVM IR for recursive types
+  
+// RUN: fir-opt --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" %s | FileCheck %s
+// RUN: fir-opt --fir-to-llvm-ir="target=aarch64-unknown-linux-gnu" %s | FileCheck %s
+// RUN: fir-opt --fir-to-llvm-ir="target=i386-unknown-linux-gnu" %s | FileCheck %s
+// RUN: fir-opt --fir-to-llvm-ir="target=powerpc64le-unknown-linux-gn" %s | FileCheck %s
+
+!t1 = type !fir.type<t1 {a1:!fir.ptr<!fir.type<t1>>}>
+!t2 = type !fir.type<t2 {b1:f32,b2:!fir.ptr<!fir.type<t2>>,b3:i32,b4:!fir.ptr<!fir.type<t2>>}>
+!t3 = type !fir.type<t3 {c1:!fir.ptr<!fir.type<t4>>}>
+!t4 = type !fir.type<t4 {d1:!fir.ptr<!fir.type<t3>>}>
+
+// CHECK-LABEL: llvm.func @recursiveTypes
+// CHECK-SAME: %{{.*}}: !llvm.struct<"[[T1:.*]]", (ptr<struct<"[[T1]]">>)>
+// CHECK-SAME: %{{.*}}: !llvm.struct<"[[T2:.*]]", (f32, ptr<struct<"[[T2]]">>, i32, ptr<struct<"[[T2]]">>)>
+// CHECK-SAME: %{{.*}}: !llvm.struct<"[[T3:.*]]", (ptr<struct<"[[T4:.*]]", (ptr<struct<"[[T3]]">>)>>)>, %{{.*}}: !llvm.struct<"[[T4]]", (ptr<struct<"[[T3]]", (ptr<struct<"[[T4]]">>)>>)>)
+func @recursiveTypes(%a : !t1, %b : !t2, %c : !t3, %d : !t4) {
+  return
+}


        


More information about the flang-commits mailing list