Skip to content

Commit 0ee0eeb

Browse files
authored
[flang] Enhance location information (#95862)
Add inclusion location information by using FusedLocation with attribute. More context here: https://discourse.llvm.org/t/rfc-enhancing-location-information/79650
1 parent 298a922 commit 0ee0eeb

File tree

9 files changed

+99
-9
lines changed

9 files changed

+99
-9
lines changed

flang/include/flang/Optimizer/Dialect/FIRAttr.td

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,17 @@ def fir_LowerBoundModifierAttribute : I32EnumAttr<
111111
let cppNamespace = "::fir";
112112
}
113113

114+
def fir_LocationKind : I32EnumAttr<"LocationKind", "Flang location kind",
115+
[
116+
I32EnumAttrCase<"Base", 0, "base">,
117+
I32EnumAttrCase<"Inclusion", 1, "inclusion">,
118+
]> {
119+
let genSpecializedAttr = 0;
120+
let cppNamespace = "::fir";
121+
}
122+
def fir_LocationKindAttr : EnumAttr<FIROpsDialect, fir_LocationKind, "loc_kind">;
123+
124+
def LocationKindArrayAttr : ArrayOfAttr<FIROpsDialect, "LocationKindArray",
125+
"loc_kind_array", "LocationKindAttr">;
126+
114127
#endif // FIR_DIALECT_FIR_ATTRS

flang/include/flang/Parser/provenance.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ class AllSources {
172172
}
173173
void setShowColors(bool showColors) { showColors_ = showColors; }
174174
bool getShowColors() const { return showColors_; }
175+
std::optional<ProvenanceRange> GetInclusionInfo(
176+
const std::optional<ProvenanceRange> &) const;
175177
void EmitMessage(llvm::raw_ostream &, const std::optional<ProvenanceRange> &,
176178
const std::string &message, const std::string &prefix,
177179
llvm::raw_ostream::Colors color, bool echoSourceLine = false) const;

flang/lib/Lower/Bridge.cpp

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -939,24 +939,59 @@ class FirConverter : public Fortran::lower::AbstractConverter {
939939
return mlir::UnknownLoc::get(&getMLIRContext());
940940
}
941941

942+
static mlir::Location genLocation(Fortran::parser::SourcePosition pos,
943+
mlir::MLIRContext &ctx) {
944+
llvm::SmallString<256> path(*pos.path);
945+
llvm::sys::fs::make_absolute(path);
946+
llvm::sys::path::remove_dots(path);
947+
return mlir::FileLineColLoc::get(&ctx, path.str(), pos.line, pos.column);
948+
}
949+
942950
/// Generate a `Location` from the `CharBlock`.
943951
mlir::Location
944952
genLocation(const Fortran::parser::CharBlock &block) override final {
953+
mlir::Location mainLocation = genUnknownLocation();
945954
if (const Fortran::parser::AllCookedSources *cooked =
946955
bridge.getCookedSource()) {
947956
if (std::optional<Fortran::parser::ProvenanceRange> provenance =
948957
cooked->GetProvenanceRange(block)) {
949958
if (std::optional<Fortran::parser::SourcePosition> filePos =
950-
cooked->allSources().GetSourcePosition(provenance->start())) {
951-
llvm::SmallString<256> filePath(*filePos->path);
952-
llvm::sys::fs::make_absolute(filePath);
953-
llvm::sys::path::remove_dots(filePath);
954-
return mlir::FileLineColLoc::get(&getMLIRContext(), filePath.str(),
955-
filePos->line, filePos->column);
959+
cooked->allSources().GetSourcePosition(provenance->start()))
960+
mainLocation = genLocation(*filePos, getMLIRContext());
961+
962+
llvm::SmallVector<mlir::Location> locs;
963+
locs.push_back(mainLocation);
964+
965+
llvm::SmallVector<fir::LocationKindAttr> locAttrs;
966+
locAttrs.push_back(fir::LocationKindAttr::get(&getMLIRContext(),
967+
fir::LocationKind::Base));
968+
969+
// Gather include location information if any.
970+
Fortran::parser::ProvenanceRange *prov = &*provenance;
971+
while (prov) {
972+
if (std::optional<Fortran::parser::ProvenanceRange> include =
973+
cooked->allSources().GetInclusionInfo(*prov)) {
974+
if (std::optional<Fortran::parser::SourcePosition> incPos =
975+
cooked->allSources().GetSourcePosition(include->start())) {
976+
locs.push_back(genLocation(*incPos, getMLIRContext()));
977+
locAttrs.push_back(fir::LocationKindAttr::get(
978+
&getMLIRContext(), fir::LocationKind::Inclusion));
979+
}
980+
prov = &*include;
981+
} else {
982+
prov = nullptr;
983+
}
984+
}
985+
if (locs.size() > 1) {
986+
assert(locs.size() == locAttrs.size() &&
987+
"expect as many attributes as locations");
988+
return mlir::FusedLocWith<fir::LocationKindArrayAttr>::get(
989+
&getMLIRContext(), locs,
990+
fir::LocationKindArrayAttr::get(&getMLIRContext(), locAttrs));
956991
}
957992
}
958993
}
959-
return genUnknownLocation();
994+
return mainLocation;
960995
}
961996

962997
const Fortran::semantics::Scope &getCurrentScope() override final {

flang/lib/Optimizer/Dialect/FIRAttr.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,5 +298,6 @@ void fir::printFirAttribute(FIROpsDialect *dialect, mlir::Attribute attr,
298298
void FIROpsDialect::registerAttributes() {
299299
addAttributes<ClosedIntervalAttr, ExactTypeAttr, FortranVariableFlagsAttr,
300300
LowerBoundAttr, PointIntervalAttr, RealAttr, ReduceAttr,
301-
SubclassAttr, UpperBoundAttr>();
301+
SubclassAttr, UpperBoundAttr, LocationKindAttr,
302+
LocationKindArrayAttr>();
302303
}

flang/lib/Optimizer/Transforms/AddDebugInfo.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,11 @@ static uint32_t getLineFromLoc(mlir::Location loc) {
7676
}
7777

7878
bool debugInfoIsAlreadySet(mlir::Location loc) {
79-
if (mlir::isa<mlir::FusedLoc>(loc))
79+
if (mlir::isa<mlir::FusedLoc>(loc)) {
80+
if (loc->findInstanceOf<mlir::FusedLocWith<fir::LocationKindAttr>>())
81+
return false;
8082
return true;
83+
}
8184
return false;
8285
}
8386

flang/lib/Parser/provenance.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,27 @@ static void EmitPrefix(llvm::raw_ostream &o, llvm::raw_ostream::Colors color,
246246
}
247247
}
248248

249+
std::optional<ProvenanceRange> AllSources::GetInclusionInfo(
250+
const std::optional<ProvenanceRange> &range) const {
251+
if (!range)
252+
return std::nullopt;
253+
const Origin &origin{MapToOrigin(range->start())};
254+
255+
return common::visit(
256+
common::visitors{
257+
[&](const Inclusion &inc) -> std::optional<ProvenanceRange> {
258+
if (IsValid(origin.replaces) &&
259+
range_.Contains(origin.replaces.start()))
260+
return origin.replaces;
261+
return std::nullopt;
262+
},
263+
[&](const auto &) -> std::optional<ProvenanceRange> {
264+
return std::nullopt;
265+
},
266+
},
267+
origin.u);
268+
}
269+
249270
void AllSources::EmitMessage(llvm::raw_ostream &o,
250271
const std::optional<ProvenanceRange> &range, const std::string &message,
251272
const std::string &prefix, llvm::raw_ostream::Colors color,

flang/test/Lower/location.f90

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
! RUN: bbc -emit-hlfir --mlir-print-debuginfo %s -o - | FileCheck %s
2+
3+
program test
4+
include 'location0.inc'
5+
6+
end
7+
8+
! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "test"} {
9+
! 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:10, "{{.*}}location0.inc":1:1, "{{.*}}location.f90":4:1])
10+
! CHECK: return loc("{{.*}}location.f90":6:1)
11+
! CHECK: } loc("{{.*}}location.f90":3:1)
12+
13+

flang/test/Lower/location0.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include 'location1.inc'

flang/test/Lower/location1.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
print *, 'from location.inc'

0 commit comments

Comments
 (0)