[flang-commits] [flang] [flang] Enhance location information (PR #95862)

Valentin Clement バレンタイン クレメン via flang-commits flang-commits at lists.llvm.org
Mon Jul 15 09:18:53 PDT 2024


https://github.com/clementval updated https://github.com/llvm/llvm-project/pull/95862

>From 4d63cf0bf6092e1906be0feda70e9a6c82dfaaf4 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Mon, 17 Jun 2024 13:08:25 -0700
Subject: [PATCH 1/5] [flang] Enhance location information

---
 flang/include/flang/Parser/provenance.h |  2 ++
 flang/lib/Lower/Bridge.cpp              | 41 ++++++++++++++++++++-----
 flang/lib/Parser/provenance.cpp         | 21 +++++++++++++
 flang/test/Lower/location.f90           | 11 +++++++
 flang/test/Lower/location0.inc          |  1 +
 flang/test/Lower/location1.inc          |  1 +
 6 files changed, 70 insertions(+), 7 deletions(-)
 create mode 100644 flang/test/Lower/location.f90
 create mode 100644 flang/test/Lower/location0.inc
 create mode 100644 flang/test/Lower/location1.inc

diff --git a/flang/include/flang/Parser/provenance.h b/flang/include/flang/Parser/provenance.h
index 3189e012cd495..a9224b727fd05 100644
--- a/flang/include/flang/Parser/provenance.h
+++ b/flang/include/flang/Parser/provenance.h
@@ -172,6 +172,8 @@ class AllSources {
   }
   void setShowColors(bool showColors) { showColors_ = showColors; }
   bool getShowColors() const { return showColors_; }
+  std::optional<ProvenanceRange> GetInclusionInfo(
+      const std::optional<ProvenanceRange> &) const;
   void EmitMessage(llvm::raw_ostream &, const std::optional<ProvenanceRange> &,
       const std::string &message, const std::string &prefix,
       llvm::raw_ostream::Colors color, bool echoSourceLine = false) const;
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 3d071f6bb8d5a..3449fe7745b48 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -939,24 +939,51 @@ class FirConverter : public Fortran::lower::AbstractConverter {
     return mlir::UnknownLoc::get(&getMLIRContext());
   }
 
+  static mlir::Location genLocation(Fortran::parser::SourcePosition pos,
+                                    mlir::MLIRContext &ctx) {
+    llvm::SmallString<256> path(*pos.path);
+    llvm::sys::fs::make_absolute(path);
+    llvm::sys::path::remove_dots(path);
+    return mlir::FileLineColLoc::get(&ctx, path.str(), pos.line, pos.column);
+  }
+
   /// Generate a `Location` from the `CharBlock`.
   mlir::Location
   genLocation(const Fortran::parser::CharBlock &block) override final {
+    mlir::Location mainLocation = genUnknownLocation();
     if (const Fortran::parser::AllCookedSources *cooked =
             bridge.getCookedSource()) {
       if (std::optional<Fortran::parser::ProvenanceRange> provenance =
               cooked->GetProvenanceRange(block)) {
         if (std::optional<Fortran::parser::SourcePosition> filePos =
-                cooked->allSources().GetSourcePosition(provenance->start())) {
-          llvm::SmallString<256> filePath(*filePos->path);
-          llvm::sys::fs::make_absolute(filePath);
-          llvm::sys::path::remove_dots(filePath);
-          return mlir::FileLineColLoc::get(&getMLIRContext(), filePath.str(),
-                                           filePos->line, filePos->column);
+                cooked->allSources().GetSourcePosition(provenance->start()))
+          mainLocation = genLocation(*filePos, getMLIRContext());
+
+        llvm::SmallVector<mlir::Location> locs;
+        locs.push_back(mainLocation);
+
+        // Gather include location information if any.
+        Fortran::parser::ProvenanceRange *prov = &*provenance;
+        while (prov) {
+          if (std::optional<Fortran::parser::ProvenanceRange> include =
+                  cooked->allSources().GetInclusionInfo(*prov)) {
+            if (std::optional<Fortran::parser::SourcePosition> incPos =
+                    cooked->allSources().GetSourcePosition(include->start()))
+              locs.push_back(genLocation(*incPos, getMLIRContext()));
+            prov = &*include;
+          } else {
+            prov = nullptr;
+          }
+        }
+        if (locs.size() > 1) {
+          auto attr = mlir::IntegerAttr::get(
+              mlir::IntegerType::get(&getMLIRContext(), 32), 1);
+          return mlir::FusedLocWith<mlir::IntegerAttr>::get(&getMLIRContext(),
+                                                            locs, attr);
         }
       }
     }
-    return genUnknownLocation();
+    return mainLocation;
   }
 
   const Fortran::semantics::Scope &getCurrentScope() override final {
diff --git a/flang/lib/Parser/provenance.cpp b/flang/lib/Parser/provenance.cpp
index c67ddd22f0968..e31038b09e407 100644
--- a/flang/lib/Parser/provenance.cpp
+++ b/flang/lib/Parser/provenance.cpp
@@ -246,6 +246,27 @@ static void EmitPrefix(llvm::raw_ostream &o, llvm::raw_ostream::Colors color,
   }
 }
 
+std::optional<ProvenanceRange> AllSources::GetInclusionInfo(
+    const std::optional<ProvenanceRange> &range) const {
+  if (!range)
+    return std::nullopt;
+  const Origin &origin{MapToOrigin(range->start())};
+
+  return common::visit(
+      common::visitors{
+          [&](const Inclusion &inc) -> std::optional<ProvenanceRange> {
+            if (IsValid(origin.replaces) &&
+                range_.Contains(origin.replaces.start()))
+              return origin.replaces;
+            return std::nullopt;
+          },
+          [&](const auto &) -> std::optional<ProvenanceRange> {
+            return std::nullopt;
+          },
+      },
+      origin.u);
+}
+
 void AllSources::EmitMessage(llvm::raw_ostream &o,
     const std::optional<ProvenanceRange> &range, const std::string &message,
     const std::string &prefix, llvm::raw_ostream::Colors color,
diff --git a/flang/test/Lower/location.f90 b/flang/test/Lower/location.f90
new file mode 100644
index 0000000000000..0e9d456bd4356
--- /dev/null
+++ b/flang/test/Lower/location.f90
@@ -0,0 +1,11 @@
+! RUN: bbc -emit-hlfir --mlir-print-debuginfo %s -o - | FileCheck %s
+
+program test
+include 'location0.inc'
+
+end 
+
+! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "test"} {
+! CHECK: fir.call @_FortranAioOutputAscii(%{{.*}}, %{{.*}}, %{{.*}}) fastmath<contract> : (!fir.ref<i8>, !fir.ref<i8>, i64) -> i1 loc(fused<1 : i32>["{{.*}}flang/test/Lower/location1.inc":1:8, "{{.*}}flang/test/Lower/location0.inc":1:1, "{{.*}}flang/test/Lower/location.f90":4:1])
+! CHECK: return loc("{{.*}}flang/test/Lower/location.f90":6:1)
+! CHECK: } loc("{{.*}}flang/test/Lower/location.f90":3:1)
diff --git a/flang/test/Lower/location0.inc b/flang/test/Lower/location0.inc
new file mode 100644
index 0000000000000..d46282c73c51e
--- /dev/null
+++ b/flang/test/Lower/location0.inc
@@ -0,0 +1 @@
+include 'location1.inc'
diff --git a/flang/test/Lower/location1.inc b/flang/test/Lower/location1.inc
new file mode 100644
index 0000000000000..d55fb01230af6
--- /dev/null
+++ b/flang/test/Lower/location1.inc
@@ -0,0 +1 @@
+print*,'from location.inc'

>From 17ae8cb98fc350ef6424026fb69715a2d1370b12 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Thu, 11 Jul 2024 14:53:40 -0700
Subject: [PATCH 2/5] Use specific attribute

---
 .../include/flang/Optimizer/Dialect/FIRAttr.td | 13 +++++++++++++
 flang/lib/Lower/Bridge.cpp                     | 18 +++++++++++++-----
 flang/lib/Optimizer/Dialect/FIRAttr.cpp        |  3 ++-
 flang/test/Lower/location.f90                  |  2 +-
 4 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/flang/include/flang/Optimizer/Dialect/FIRAttr.td b/flang/include/flang/Optimizer/Dialect/FIRAttr.td
index aedb6769186e9..60281dfa63713 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRAttr.td
+++ b/flang/include/flang/Optimizer/Dialect/FIRAttr.td
@@ -111,4 +111,17 @@ def fir_LowerBoundModifierAttribute : I32EnumAttr<
   let cppNamespace = "::fir";
 }
 
+def fir_LocationKind : I32EnumAttr<"LocationKind", "Flang location kind",
+  [
+    I32EnumAttrCase<"Base", 0, "base">,
+    I32EnumAttrCase<"Inclusion", 1, "inclusion">,
+  ]> {
+  let genSpecializedAttr = 0;
+  let cppNamespace = "::fir";
+}
+def fir_LocationKindAttr : EnumAttr<FIROpsDialect, fir_LocationKind, "loc_kind">;
+
+def LocationKindArrayAttr : ArrayOfAttr<FIROpsDialect, "LocationKindArray",
+    "loc_kind_array", "LocationKindAttr">;
+
 #endif // FIR_DIALECT_FIR_ATTRS
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 3449fe7745b48..7726c8393e1f0 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -962,24 +962,32 @@ class FirConverter : public Fortran::lower::AbstractConverter {
         llvm::SmallVector<mlir::Location> locs;
         locs.push_back(mainLocation);
 
+        llvm::SmallVector<fir::LocationKindAttr> locAttrs;
+        locAttrs.push_back(fir::LocationKindAttr::get(&getMLIRContext(),
+                                                      fir::LocationKind::Base));
+
         // Gather include location information if any.
         Fortran::parser::ProvenanceRange *prov = &*provenance;
         while (prov) {
           if (std::optional<Fortran::parser::ProvenanceRange> include =
                   cooked->allSources().GetInclusionInfo(*prov)) {
             if (std::optional<Fortran::parser::SourcePosition> incPos =
-                    cooked->allSources().GetSourcePosition(include->start()))
+                    cooked->allSources().GetSourcePosition(include->start())) {
               locs.push_back(genLocation(*incPos, getMLIRContext()));
+              locAttrs.push_back(fir::LocationKindAttr::get(
+                  &getMLIRContext(), fir::LocationKind::Inclusion));
+            }
             prov = &*include;
           } else {
             prov = nullptr;
           }
         }
         if (locs.size() > 1) {
-          auto attr = mlir::IntegerAttr::get(
-              mlir::IntegerType::get(&getMLIRContext(), 32), 1);
-          return mlir::FusedLocWith<mlir::IntegerAttr>::get(&getMLIRContext(),
-                                                            locs, attr);
+          assert(locs.size() == locAttrs.size() &&
+                 "expect as many attributes as locations");
+          return mlir::FusedLocWith<fir::LocationKindArrayAttr>::get(
+              &getMLIRContext(), locs,
+              fir::LocationKindArrayAttr::get(&getMLIRContext(), locAttrs));
         }
       }
     }
diff --git a/flang/lib/Optimizer/Dialect/FIRAttr.cpp b/flang/lib/Optimizer/Dialect/FIRAttr.cpp
index a0202a0159228..443e94ae6606f 100644
--- a/flang/lib/Optimizer/Dialect/FIRAttr.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRAttr.cpp
@@ -298,5 +298,6 @@ void fir::printFirAttribute(FIROpsDialect *dialect, mlir::Attribute attr,
 void FIROpsDialect::registerAttributes() {
   addAttributes<ClosedIntervalAttr, ExactTypeAttr, FortranVariableFlagsAttr,
                 LowerBoundAttr, PointIntervalAttr, RealAttr, ReduceAttr,
-                SubclassAttr, UpperBoundAttr>();
+                SubclassAttr, UpperBoundAttr, LocationKindAttr,
+                LocationKindArrayAttr>();
 }
diff --git a/flang/test/Lower/location.f90 b/flang/test/Lower/location.f90
index 0e9d456bd4356..565e3824d2355 100644
--- a/flang/test/Lower/location.f90
+++ b/flang/test/Lower/location.f90
@@ -6,6 +6,6 @@ program test
 end 
 
 ! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "test"} {
-! CHECK: fir.call @_FortranAioOutputAscii(%{{.*}}, %{{.*}}, %{{.*}}) fastmath<contract> : (!fir.ref<i8>, !fir.ref<i8>, i64) -> i1 loc(fused<1 : i32>["{{.*}}flang/test/Lower/location1.inc":1:8, "{{.*}}flang/test/Lower/location0.inc":1:1, "{{.*}}flang/test/Lower/location.f90":4:1])
+! CHECK: fir.call @_FortranAioOutputAscii(%{{.*}}, %{{.*}}, %{{.*}}) fastmath<contract> : (!fir.ref<i8>, !fir.ref<i8>, i64) -> i1 loc(fused<#fir<loc_kind_array[ base,  inclusion,  inclusion]>>["{{.*}}location1.inc":1:8, "{{.*}}location0.inc":1:1, "{{.*}}location.f90":4:1])
 ! CHECK: return loc("{{.*}}flang/test/Lower/location.f90":6:1)
 ! CHECK: } loc("{{.*}}flang/test/Lower/location.f90":3:1)

>From d5214fcc9c3205d4c6fb6b96185d340b7f65d5cb Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Thu, 11 Jul 2024 15:00:24 -0700
Subject: [PATCH 3/5] formatting in include file

---
 flang/test/Lower/location1.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/test/Lower/location1.inc b/flang/test/Lower/location1.inc
index d55fb01230af6..6a2671c61828e 100644
--- a/flang/test/Lower/location1.inc
+++ b/flang/test/Lower/location1.inc
@@ -1 +1 @@
-print*,'from location.inc'
+print *, 'from location.inc'

>From e2a463aa6372f14031e106d1bb33442b0e4b2565 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Mon, 15 Jul 2024 09:08:17 -0700
Subject: [PATCH 4/5] Fix test

---
 flang/test/Lower/location.f90 | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/flang/test/Lower/location.f90 b/flang/test/Lower/location.f90
index 565e3824d2355..9cd7c2bbe75ca 100644
--- a/flang/test/Lower/location.f90
+++ b/flang/test/Lower/location.f90
@@ -6,6 +6,8 @@ program test
 end 
 
 ! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "test"} {
-! CHECK: fir.call @_FortranAioOutputAscii(%{{.*}}, %{{.*}}, %{{.*}}) fastmath<contract> : (!fir.ref<i8>, !fir.ref<i8>, i64) -> i1 loc(fused<#fir<loc_kind_array[ base,  inclusion,  inclusion]>>["{{.*}}location1.inc":1:8, "{{.*}}location0.inc":1:1, "{{.*}}location.f90":4:1])
+! CHECK: fir.call @_FortranAioOutputAscii(%2, %5, %6) fastmath<contract> : (!fir.ref<i8>, !fir.ref<i8>, i64) -> i1 loc(fused<#fir<loc_kind_array[ base,  inclusion,  inclusion]>>["{{.*}}flang/test/Lower/location1.inc":1:10, "{{.*}}flang/test/Lower/location0.inc":1:1, "{{.*}}flang/test/Lower/location.f90":4:1])
 ! CHECK: return loc("{{.*}}flang/test/Lower/location.f90":6:1)
 ! CHECK: } loc("{{.*}}flang/test/Lower/location.f90":3:1)
+
+

>From 3fa0796c436485118a15fab14de819a3bfbfefbe Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Mon, 15 Jul 2024 09:18:41 -0700
Subject: [PATCH 5/5] Update condition

---
 flang/lib/Optimizer/Transforms/AddDebugInfo.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index 10c71d3fc9551..3afb1290411c2 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -228,7 +228,7 @@ void AddDebugInfoPass::runOnOperation() {
     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 (l->findInstanceOf<mlir::FusedLocWith<mlir::LLVM::DISubprogramAttr>>())
       return;
 
     unsigned int CC = (funcOp.getName() == fir::NameUniquer::doProgramEntry())



More information about the flang-commits mailing list