Skip to content

Commit cd9f75c

Browse files
abidhgit-crd
authored andcommitted
[flang][debug] Track dummy argument positions explicitly. (llvm#167489)
CHARACTER dummy arguments were treated as local variables in debug info. This happened because our method to get the argument number was not robust. It relied on `DeclareOp` having a direct reference to arguments which was not the case for character arguments. This is fixed by storing source-level argument positions in `DeclareOp`. Fixes llvm#112886
1 parent 0d899c3 commit cd9f75c

File tree

193 files changed

+1114
-970
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

193 files changed

+1114
-970
lines changed

flang/include/flang/Lower/AbstractConverter.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,12 @@ class AbstractConverter {
271271
virtual bool
272272
isRegisteredDummySymbol(Fortran::semantics::SymbolRef symRef) const = 0;
273273

274+
/// Get the source-level argument position (1-based) for a dummy symbol.
275+
/// Returns 0 if the symbol is not a registered dummy or position is unknown.
276+
/// Can only be used reliably during the instantiation of variables.
277+
virtual unsigned
278+
getDummyArgPosition(const Fortran::semantics::Symbol &sym) const = 0;
279+
274280
/// Returns the FunctionLikeUnit being lowered, if any.
275281
virtual const Fortran::lower::pft::FunctionLikeUnit *
276282
getCurrentFunctionUnit() const = 0;

flang/include/flang/Optimizer/Builder/HLFIRTools.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ genDeclare(mlir::Location loc, fir::FirOpBuilder &builder,
233233
fir::FortranVariableFlagsAttr flags,
234234
mlir::Value dummyScope = nullptr, mlir::Value storage = nullptr,
235235
std::uint64_t storageOffset = 0,
236-
cuf::DataAttributeAttr dataAttr = {});
236+
cuf::DataAttributeAttr dataAttr = {}, unsigned dummyArgNo = 0);
237237

238238
/// Generate an hlfir.associate to build a variable from an expression value.
239239
/// The type of the variable must be provided so that scalar logicals are

flang/include/flang/Optimizer/Dialect/FIRCG/CGOps.td

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,12 +229,13 @@ def fircg_XDeclareOp : fircg_Op<"ext_declare", [AttrSizedOperandSegments]> {
229229

230230
let arguments = (ins AnyRefOrBox:$memref, Variadic<AnyIntegerType>:$shape,
231231
Variadic<AnyIntegerType>:$shift, Variadic<AnyIntegerType>:$typeparams,
232-
Optional<fir_DummyScopeType>:$dummy_scope, Builtin_StringAttr:$uniq_name);
232+
Optional<fir_DummyScopeType>:$dummy_scope, Builtin_StringAttr:$uniq_name,
233+
OptionalAttr<UI32Attr>:$dummy_arg_no);
233234
let results = (outs AnyRefOrBox);
234235

235236
let assemblyFormat = [{
236237
$memref (`(` $shape^ `)`)? (`origin` $shift^)? (`typeparams` $typeparams^)?
237-
(`dummy_scope` $dummy_scope^)?
238+
(`dummy_scope` $dummy_scope^ (`arg` $dummy_arg_no^)?)?
238239
attr-dict `:` functional-type(operands, results)
239240
}];
240241

flang/include/flang/Optimizer/Dialect/FIROps.td

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3274,13 +3274,14 @@ def fir_DeclareOp
32743274
DefaultValuedAttr<UI64Attr, "0">:$storage_offset,
32753275
Builtin_StringAttr:$uniq_name,
32763276
OptionalAttr<fir_FortranVariableFlagsAttr>:$fortran_attrs,
3277-
OptionalAttr<cuf_DataAttributeAttr>:$data_attr);
3277+
OptionalAttr<cuf_DataAttributeAttr>:$data_attr,
3278+
OptionalAttr<UI32Attr>:$dummy_arg_no);
32783279

32793280
let results = (outs AnyRefOrBox);
32803281

32813282
let assemblyFormat = [{
32823283
$memref (`(` $shape^ `)`)? (`typeparams` $typeparams^)?
3283-
(`dummy_scope` $dummy_scope^)?
3284+
(`dummy_scope` $dummy_scope^ (`arg` $dummy_arg_no^)?)?
32843285
(`storage` `(` $storage^ `[` $storage_offset `]` `)`)?
32853286
attr-dict `:` functional-type(operands, results)
32863287
}];

flang/include/flang/Optimizer/HLFIR/HLFIROps.td

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,13 @@ def hlfir_DeclareOp
103103
Builtin_StringAttr:$uniq_name,
104104
OptionalAttr<fir_FortranVariableFlagsAttr>:$fortran_attrs,
105105
OptionalAttr<cuf_DataAttributeAttr>:$data_attr,
106-
OptionalAttr<UnitAttr>:$skip_rebox);
106+
OptionalAttr<UnitAttr>:$skip_rebox, OptionalAttr<UI32Attr>:$dummy_arg_no);
107107

108108
let results = (outs AnyFortranVariable, AnyRefOrBoxLike);
109109

110110
let assemblyFormat = [{
111111
$memref (`(` $shape^ `)`)? (`typeparams` $typeparams^)?
112-
(`dummy_scope` $dummy_scope^)?
112+
(`dummy_scope` $dummy_scope^ (`arg` $dummy_arg_no^)?)?
113113
(`storage` `(` $storage^ `[` $storage_offset `]` `)`)?
114114
(`skip_rebox` $skip_rebox^)?
115115
attr-dict `:` functional-type(operands, results)
@@ -122,7 +122,8 @@ def hlfir_DeclareOp
122122
CArg<"mlir::Value", "{}">:$storage,
123123
CArg<"std::uint64_t", "0">:$storage_offset,
124124
CArg<"fir::FortranVariableFlagsAttr", "{}">:$fortran_attrs,
125-
CArg<"cuf::DataAttributeAttr", "{}">:$data_attr)>];
125+
CArg<"cuf::DataAttributeAttr", "{}">:$data_attr,
126+
CArg<"unsigned", "0">:$dummy_arg_no)>];
126127

127128
let extraClassDeclaration = [{
128129
/// Get the variable original base (same as input). It lacks

flang/lib/Lower/Bridge.cpp

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,12 @@ class FirConverter : public Fortran::lower::AbstractConverter {
11571157
return registeredDummySymbols.contains(sym);
11581158
}
11591159

1160+
unsigned getDummyArgPosition(
1161+
const Fortran::semantics::Symbol &sym) const override final {
1162+
auto it = dummyArgPositions.find(&sym);
1163+
return (it != dummyArgPositions.end()) ? it->second : 0;
1164+
}
1165+
11601166
const Fortran::lower::pft::FunctionLikeUnit *
11611167
getCurrentFunctionUnit() const override final {
11621168
return currentFunctionUnit;
@@ -1441,11 +1447,14 @@ class FirConverter : public Fortran::lower::AbstractConverter {
14411447
/// definitive mapping. The specification expression have not been lowered
14421448
/// yet. The final mapping will be done using this pre-mapping in
14431449
/// Fortran::lower::mapSymbolAttributes.
1450+
/// \param argNo The 1-based source position of this argument (0 if
1451+
/// unknown/result)
14441452
bool mapBlockArgToDummyOrResult(const Fortran::semantics::SymbolRef sym,
1445-
mlir::Value val, bool isResult) {
1453+
mlir::Value val, bool isResult,
1454+
unsigned argNo = 0) {
14461455
localSymbols.addSymbol(sym, val);
14471456
if (!isResult)
1448-
registerDummySymbol(sym);
1457+
registerDummySymbol(sym, argNo);
14491458

14501459
return true;
14511460
}
@@ -6007,7 +6016,16 @@ class FirConverter : public Fortran::lower::AbstractConverter {
60076016
const Fortran::lower::CalleeInterface &callee) {
60086017
assert(builder && "require a builder object at this point");
60096018
using PassBy = Fortran::lower::CalleeInterface::PassEntityBy;
6019+
6020+
// Track the source-level argument position (1-based)
6021+
unsigned argPosition = 0;
6022+
60106023
auto mapPassedEntity = [&](const auto arg, bool isResult = false) {
6024+
// Count only actual source-level dummy arguments (not results or
6025+
// host assoc tuples)
6026+
if (!isResult && arg.entity.has_value())
6027+
argPosition++;
6028+
60116029
if (arg.passBy == PassBy::AddressAndLength) {
60126030
if (callee.characterize().IsBindC())
60136031
return;
@@ -6018,11 +6036,12 @@ class FirConverter : public Fortran::lower::AbstractConverter {
60186036
mlir::Value casted =
60196037
builder->createVolatileCast(loc, false, arg.firArgument);
60206038
mlir::Value box = charHelp.createEmboxChar(casted, arg.firLength);
6021-
mapBlockArgToDummyOrResult(arg.entity->get(), box, isResult);
6039+
mapBlockArgToDummyOrResult(arg.entity->get(), box, isResult,
6040+
isResult ? 0 : argPosition);
60226041
} else {
60236042
if (arg.entity.has_value()) {
60246043
mapBlockArgToDummyOrResult(arg.entity->get(), arg.firArgument,
6025-
isResult);
6044+
isResult, isResult ? 0 : argPosition);
60266045
} else {
60276046
assert(funit.parentHasTupleHostAssoc() && "expect tuple argument");
60286047
}
@@ -6880,13 +6899,22 @@ class FirConverter : public Fortran::lower::AbstractConverter {
68806899
}
68816900

68826901
/// Record the given symbol as a dummy argument of this function.
6883-
void registerDummySymbol(Fortran::semantics::SymbolRef symRef) {
6902+
/// \param symRef The symbol representing the dummy argument
6903+
/// \param argNo The 1-based position of this argument in the source (0 =
6904+
/// unknown)
6905+
void registerDummySymbol(Fortran::semantics::SymbolRef symRef,
6906+
unsigned argNo = 0) {
68846907
auto *sym = &*symRef;
68856908
registeredDummySymbols.insert(sym);
6909+
if (argNo > 0)
6910+
dummyArgPositions[sym] = argNo;
68866911
}
68876912

68886913
/// Reset all registered dummy symbols.
6889-
void resetRegisteredDummySymbols() { registeredDummySymbols.clear(); }
6914+
void resetRegisteredDummySymbols() {
6915+
registeredDummySymbols.clear();
6916+
dummyArgPositions.clear();
6917+
}
68906918

68916919
void setCurrentFunctionUnit(Fortran::lower::pft::FunctionLikeUnit *unit) {
68926920
currentFunctionUnit = unit;
@@ -6928,6 +6956,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
69286956
llvm::SmallPtrSet<const Fortran::semantics::Symbol *, 16>
69296957
registeredDummySymbols;
69306958

6959+
/// Map from dummy symbols to their 1-based argument positions.
6960+
/// Used to generate debug info with correct argument numbers.
6961+
llvm::DenseMap<const Fortran::semantics::Symbol *, unsigned>
6962+
dummyArgPositions;
6963+
69316964
/// A map of unique names for constant expressions.
69326965
/// The names are used for representing the constant expressions
69336966
/// with global constant initialized objects.

flang/lib/Lower/ConvertVariable.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1946,12 +1946,15 @@ static void genDeclareSymbol(Fortran::lower::AbstractConverter &converter,
19461946
return;
19471947
}
19481948
mlir::Value dummyScope;
1949-
if (converter.isRegisteredDummySymbol(sym))
1949+
unsigned argNo = 0;
1950+
if (converter.isRegisteredDummySymbol(sym)) {
19501951
dummyScope = converter.dummyArgsScopeValue();
1952+
argNo = converter.getDummyArgPosition(sym);
1953+
}
19511954
auto [storage, storageOffset] = converter.getSymbolStorage(sym);
19521955
auto newBase = hlfir::DeclareOp::create(
19531956
builder, loc, base, name, shapeOrShift, lenParams, dummyScope, storage,
1954-
storageOffset, attributes, dataAttr);
1957+
storageOffset, attributes, dataAttr, argNo);
19551958
symMap.addVariableDefinition(sym, newBase, force);
19561959
return;
19571960
}
@@ -2004,15 +2007,17 @@ void Fortran::lower::genDeclareSymbol(
20042007
sym.GetUltimate());
20052008
auto name = converter.mangleName(sym);
20062009
mlir::Value dummyScope;
2010+
unsigned argNo = 0;
20072011
fir::ExtendedValue base = exv;
20082012
if (converter.isRegisteredDummySymbol(sym)) {
20092013
base = genPackArray(converter, sym, exv);
20102014
dummyScope = converter.dummyArgsScopeValue();
2015+
argNo = converter.getDummyArgPosition(sym);
20112016
}
20122017
auto [storage, storageOffset] = converter.getSymbolStorage(sym);
20132018
hlfir::EntityWithAttributes declare =
20142019
hlfir::genDeclare(loc, builder, base, name, attributes, dummyScope,
2015-
storage, storageOffset, dataAttr);
2020+
storage, storageOffset, dataAttr, argNo);
20162021
symMap.addVariableDefinition(sym, declare.getIfVariableInterface(), force);
20172022
return;
20182023
}

flang/lib/Optimizer/Builder/FIRBuilder.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,8 @@ mlir::Value fir::FirOpBuilder::genTempDeclareOp(
427427
builder, loc, memref.getType(), memref, shape, typeParams,
428428
/*dummy_scope=*/nullptr,
429429
/*storage=*/nullptr,
430-
/*storage_offset=*/0, nameAttr, fortranAttrs, cuf::DataAttributeAttr{});
430+
/*storage_offset=*/0, nameAttr, fortranAttrs, cuf::DataAttributeAttr{},
431+
/*dummy_arg_no=*/mlir::IntegerAttr{});
431432
}
432433

433434
mlir::Value fir::FirOpBuilder::genStackSave(mlir::Location loc) {

flang/lib/Optimizer/Builder/HLFIRTools.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ hlfir::genDeclare(mlir::Location loc, fir::FirOpBuilder &builder,
250250
const fir::ExtendedValue &exv, llvm::StringRef name,
251251
fir::FortranVariableFlagsAttr flags, mlir::Value dummyScope,
252252
mlir::Value storage, std::uint64_t storageOffset,
253-
cuf::DataAttributeAttr dataAttr) {
253+
cuf::DataAttributeAttr dataAttr, unsigned dummyArgNo) {
254254

255255
mlir::Value base = fir::getBase(exv);
256256
assert(fir::conformsWithPassByRef(base.getType()) &&
@@ -281,7 +281,7 @@ hlfir::genDeclare(mlir::Location loc, fir::FirOpBuilder &builder,
281281
[](const auto &) {});
282282
auto declareOp = hlfir::DeclareOp::create(
283283
builder, loc, base, name, shapeOrShift, lenParams, dummyScope, storage,
284-
storageOffset, flags, dataAttr);
284+
storageOffset, flags, dataAttr, dummyArgNo);
285285
return mlir::cast<fir::FortranVariableOpInterface>(declareOp.getOperation());
286286
}
287287

flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,11 +302,15 @@ class DeclareOpConversion : public mlir::OpRewritePattern<fir::DeclareOp> {
302302
else
303303
return mlir::failure();
304304
}
305+
// Extract dummy_arg_no attribute if present
306+
mlir::IntegerAttr dummyArgNoAttr;
307+
if (auto attr = declareOp->getAttrOfType<mlir::IntegerAttr>("dummy_arg_no"))
308+
dummyArgNoAttr = attr;
305309
// FIXME: Add FortranAttrs and CudaAttrs
306310
auto xDeclOp = fir::cg::XDeclareOp::create(
307311
rewriter, loc, declareOp.getType(), declareOp.getMemref(), shapeOpers,
308312
shiftOpers, declareOp.getTypeparams(), declareOp.getDummyScope(),
309-
declareOp.getUniqName());
313+
declareOp.getUniqName(), dummyArgNoAttr);
310314
LLVM_DEBUG(llvm::dbgs()
311315
<< "rewriting " << declareOp << " to " << xDeclOp << '\n');
312316
rewriter.replaceOp(declareOp, xDeclOp.getOperation()->getResults());

0 commit comments

Comments
 (0)