[flang-commits] [flang] 391efeb - [flang][NFC] Retrieve binding table from fir.dispatch_table operations

Valentin Clement via flang-commits flang-commits at lists.llvm.org
Tue Nov 29 04:22:23 PST 2022


Author: Valentin Clement
Date: 2022-11-29T13:22:16+01:00
New Revision: 391efeb53828c888f8fd3aa75d1ff19e1dd8f1d3

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

LOG: [flang][NFC] Retrieve binding table from fir.dispatch_table operations

Change how the binding tables are retrived. Use the newly lowered
fir.dispatch_table operations instead of the fir.global type infos.

Reviewed By: jeanPerier

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

Added: 
    

Modified: 
    flang/lib/Optimizer/CodeGen/CodeGen.cpp
    flang/test/Fir/dispatch.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 249625bb90404..fad77e6ed2879 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -949,17 +949,12 @@ struct DispatchOpConversion : public FIROpConversion<fir::DispatchOp> {
             .Default([](mlir::Type t) { return t; });
     assert(declaredType.isa<fir::RecordType>() && "expecting fir.type");
     auto recordType = declaredType.dyn_cast<fir::RecordType>();
-    std::string typeDescName =
-        fir::NameUniquer::getTypeDescriptorName(recordType.getName());
-    std::string typeDescBindingTableName =
-        fir::NameUniquer::getTypeDescriptorBindingTableName(
-            recordType.getName());
 
     // Lookup for the binding table.
-    auto bindingsIter = bindingTables.find(typeDescBindingTableName);
+    auto bindingsIter = bindingTables.find(recordType.getName());
     if (bindingsIter == bindingTables.end())
       return emitError(loc)
-             << "cannot find binding table for " << typeDescBindingTableName;
+             << "cannot find binding table for " << recordType.getName();
 
     // Lookup for the binding.
     const BindingTable &bindingTable = bindingsIter->second;
@@ -973,6 +968,8 @@ struct DispatchOpConversion : public FIROpConversion<fir::DispatchOp> {
 
     auto module = dispatch.getOperation()->getParentOfType<mlir::ModuleOp>();
     mlir::Type typeDescTy;
+    std::string typeDescName =
+        fir::NameUniquer::getTypeDescriptorName(recordType.getName());
     if (auto global = module.lookupSymbol<fir::GlobalOp>(typeDescName)) {
       typeDescTy = convertType(global.getType());
     } else if (auto global =
@@ -3640,29 +3637,22 @@ class FIRToLLVMLowering
       return signalPassFailure();
 
     // Reconstruct binding tables for dynamic dispatch. The binding tables
-    // are defined in FIR from semantics as fir.global operation with region
-    // initializer. Go through each bining tables and store the procedure name
+    // are defined in FIR from lowering as fir.dispatch_table operation.
+    // Go through each binding tables and store the procedure name
     // and binding index for later use by the fir.dispatch conversion pattern.
     BindingTables bindingTables;
-    for (auto globalOp : mod.getOps<fir::GlobalOp>()) {
-      if (globalOp.getSymName().contains(bindingTableSeparator)) {
-        unsigned bindingIdx = 0;
-        BindingTable bindings;
-        for (auto addrOp : globalOp.getRegion().getOps<fir::AddrOfOp>()) {
-          if (fir::isa_char(fir::unwrapRefType(addrOp.getType()))) {
-            if (auto nameGlobal =
-                    mod.lookupSymbol<fir::GlobalOp>(addrOp.getSymbol())) {
-              auto stringLit = llvm::to_vector(
-                  nameGlobal.getRegion().getOps<fir::StringLitOp>())[0];
-              auto procName =
-                  stringLit.getValue().dyn_cast<mlir::StringAttr>().getValue();
-              bindings[procName] = bindingIdx;
-              ++bindingIdx;
-            }
-          }
-        }
-        bindingTables[globalOp.getSymName()] = bindings;
+    for (auto dispatchTableOp : mod.getOps<fir::DispatchTableOp>()) {
+      unsigned bindingIdx = 0;
+      BindingTable bindings;
+      if (dispatchTableOp.getRegion().empty()) {
+        bindingTables[dispatchTableOp.getSymName()] = bindings;
+        continue;
+      }
+      for (auto dtEntry : dispatchTableOp.getBlock().getOps<fir::DTEntryOp>()) {
+        bindings[dtEntry.getMethod()] = bindingIdx;
+        ++bindingIdx;
       }
+      bindingTables[dispatchTableOp.getSymName()] = bindings;
     }
 
     auto *context = getModule().getContext();

diff  --git a/flang/test/Fir/dispatch.f90 b/flang/test/Fir/dispatch.f90
index 7b462df81c52f..eadc9251ba06f 100644
--- a/flang/test/Fir/dispatch.f90
+++ b/flang/test/Fir/dispatch.f90
@@ -32,6 +32,18 @@ module dispatch1
     procedure, pass(this) :: proc_pass => proc_pass_p2
   end type
 
+  type, abstract :: a1
+    integer a
+  contains
+    procedure :: a1_proc
+  end type
+
+  type, extends(a1) :: a2
+    integer b
+  contains
+    procedure :: a1_proc => a2_proc
+  end type
+
 contains
 
   subroutine display1_p1(this)
@@ -135,6 +147,19 @@ subroutine no_pass_array_pointer(a)
     call a(1)%proc_nopass()
   end subroutine
 
+  subroutine a1_proc(this)
+    class(a1) :: this
+  end subroutine
+
+  subroutine a2_proc(this)
+    class(a2) :: this
+  end subroutine
+
+  subroutine call_a1_proc(p)
+    class(a1), pointer :: p
+    call p%a1_proc()
+  end subroutine
+
 end module
 
 program test_type_to_class
@@ -250,28 +275,36 @@ program test_type_to_class
 ! CHECK-LABEL: _QMdispatch1Pno_pass_array
 ! CHECK-LABEL: _QMdispatch1Pno_pass_array_allocatable
 ! CHECK-LABEL: _QMdispatch1Pno_pass_array_pointer
+! CHECK-LABEL: _QMdispatch1Pcall_a1_proc
 
 ! Check the layout of the binding table. This is easier to do in FIR than in 
 ! LLVM IR.
 
-! BT-LABEL: fir.global linkonce_odr @_QMdispatch1E.v.p1 constant target : !fir.array<7x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>> {
-! BT: %{{.*}} = fir.address_of(@_QMdispatch1Paproc) : (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>) -> ()
-! BT: %{{.*}} = fir.address_of(@_QMdispatch1Pdisplay1_p1) : (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>) -> ()
-! BT: %{{.*}} = fir.address_of(@_QMdispatch1Pdisplay2_p1) : (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>) -> ()
-! BT: %{{.*}} = fir.address_of(@_QMdispatch1Pget_value_p1) : (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>) -> i32
-! BT: %{{.*}} = fir.address_of(@_QMdispatch1Pproc_nopass_p1) : () -> ()
-! BT: %{{.*}} = fir.address_of(@_QMdispatch1Pproc_pass_p1) : (!fir.ref<i32>, !fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>) -> ()
-! BT: %{{.*}} = fir.address_of(@_QMdispatch1Pproc_p1) : (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>, !fir.ref<f32>) -> ()
+! BT-LABEL: fir.dispatch_table @_QMdispatch1Tp1 {
+! BT: fir.dt_entry "aproc", @_QMdispatch1Paproc
+! BT: fir.dt_entry "display1", @_QMdispatch1Pdisplay1_p1
+! BT: fir.dt_entry "display2", @_QMdispatch1Pdisplay2_p1
+! BT: fir.dt_entry "get_value", @_QMdispatch1Pget_value_p1
+! BT: fir.dt_entry "proc_nopass", @_QMdispatch1Pproc_nopass_p1
+! BT: fir.dt_entry "proc_pass", @_QMdispatch1Pproc_pass_p1
+! BT: fir.dt_entry "proc_with_values", @_QMdispatch1Pproc_p1
 ! BT: }
 
-! BT-LABEL: fir.global linkonce_odr @_QMdispatch1E.v.p2 constant target : !fir.array<8x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>> {
-! BT: %{{.*}} = fir.address_of(@_QMdispatch1Paproc) : (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>) -> ()
-! BT: %{{.*}} = fir.address_of(@_QMdispatch1Pdisplay1_p2) : (!fir.class<!fir.type<_QMdispatch1Tp2{a:i32,b:i32,c:i32}>>) -> ()
-! BT: %{{.*}} = fir.address_of(@_QMdispatch1Pdisplay2_p2) : (!fir.class<!fir.type<_QMdispatch1Tp2{a:i32,b:i32,c:i32}>>) -> ()
-! BT: %{{.*}} = fir.address_of(@_QMdispatch1Pget_value_p2) : (!fir.class<!fir.type<_QMdispatch1Tp2{a:i32,b:i32,c:i32}>>) -> i32
-! BT: %{{.*}} = fir.address_of(@_QMdispatch1Pproc_nopass_p2) : () -> ()
-! BT: %{{.*}} = fir.address_of(@_QMdispatch1Pproc_pass_p2) : (!fir.ref<i32>, !fir.class<!fir.type<_QMdispatch1Tp2{a:i32,b:i32,c:i32}>>) -> ()
-! BT: %{{.*}} = fir.address_of(@_QMdispatch1Pproc_p2) : (!fir.class<!fir.type<_QMdispatch1Tp2{a:i32,b:i32,c:i32}>>, !fir.ref<f32>) -> ()
-! BT: %{{.*}} = fir.address_of(@_QMdispatch1Pdisplay3) : (!fir.class<!fir.type<_QMdispatch1Tp2{a:i32,b:i32,c:i32}>>) -> ()
+! BT-LABEL: fir.dispatch_table @_QMdispatch1Ta1 {
+! BT: fir.dt_entry "a1_proc", @_QMdispatch1Pa1_proc
 ! BT: }
 
+! BT-LABEL: fir.dispatch_table @_QMdispatch1Ta2 extends("_QMdispatch1Ta1") {
+! BT:  fir.dt_entry "a1_proc", @_QMdispatch1Pa2_proc
+! BT: }
+
+! BT-LABEL: fir.dispatch_table @_QMdispatch1Tp2 extends("_QMdispatch1Tp1") {
+! BT:  fir.dt_entry "aproc", @_QMdispatch1Paproc
+! BT:  fir.dt_entry "display1", @_QMdispatch1Pdisplay1_p2
+! BT:  fir.dt_entry "display2", @_QMdispatch1Pdisplay2_p2
+! BT:  fir.dt_entry "get_value", @_QMdispatch1Pget_value_p2
+! BT:  fir.dt_entry "proc_nopass", @_QMdispatch1Pproc_nopass_p2
+! BT:  fir.dt_entry "proc_pass", @_QMdispatch1Pproc_pass_p2
+! BT:  fir.dt_entry "proc_with_values", @_QMdispatch1Pproc_p2
+! BT:  fir.dt_entry "display3", @_QMdispatch1Pdisplay3
+! BT: }


        


More information about the flang-commits mailing list