[flang-commits] [flang] [flang][debug] Track dummy argument positions explicitly. (PR #167489)
via flang-commits
flang-commits at lists.llvm.org
Tue Nov 11 03:09:41 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Abid Qadeer (abidh)
<details>
<summary>Changes</summary>
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 #<!-- -->112886
---
Patch is 920.80 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/167489.diff
192 Files Affected:
- (modified) flang/include/flang/Lower/AbstractConverter.h (+6)
- (modified) flang/include/flang/Optimizer/Builder/HLFIRTools.h (+1-1)
- (modified) flang/include/flang/Optimizer/Dialect/FIRCG/CGOps.td (+3-2)
- (modified) flang/include/flang/Optimizer/Dialect/FIROps.td (+3-2)
- (modified) flang/include/flang/Optimizer/HLFIR/HLFIROps.td (+4-3)
- (modified) flang/lib/Lower/Bridge.cpp (+39-6)
- (modified) flang/lib/Lower/ConvertVariable.cpp (+8-3)
- (modified) flang/lib/Optimizer/Builder/FIRBuilder.cpp (+2-1)
- (modified) flang/lib/Optimizer/Builder/HLFIRTools.cpp (+2-2)
- (modified) flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp (+5-1)
- (modified) flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp (+10-9)
- (modified) flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp (+2-1)
- (modified) flang/lib/Optimizer/Transforms/AddDebugInfo.cpp (+3-16)
- (modified) flang/test/Fir/dispatch.f90 (+1-1)
- (modified) flang/test/HLFIR/assumed-type-actual-args.f90 (+10-10)
- (modified) flang/test/HLFIR/assumed_shape_with_value_keyword.f90 (+9-9)
- (modified) flang/test/HLFIR/boxchar_emboxing.f90 (+2-2)
- (modified) flang/test/HLFIR/c_ptr_byvalue.f90 (+1-1)
- (modified) flang/test/HLFIR/call_with_poly_dummy.f90 (+1-1)
- (modified) flang/test/HLFIR/optional_dummy.f90 (+1-1)
- (added) flang/test/Integration/debug-char-arg-issue-112886.f90 (+46)
- (modified) flang/test/Lower/CUDA/cuda-data-attribute.cuf (+4-4)
- (modified) flang/test/Lower/CUDA/cuda-data-transfer.cuf (+8-8)
- (modified) flang/test/Lower/HLFIR/actual_target_for_dummy_pointer.f90 (+11-11)
- (modified) flang/test/Lower/HLFIR/allocatable-and-pointer-status-change.f90 (+6-6)
- (modified) flang/test/Lower/HLFIR/allocatables-and-pointers.f90 (+9-9)
- (modified) flang/test/Lower/HLFIR/array-ctor-as-elemental-nested.f90 (+2-2)
- (modified) flang/test/Lower/HLFIR/array-ctor-as-elemental.f90 (+5-5)
- (modified) flang/test/Lower/HLFIR/array-ctor-as-inlined-temp.f90 (+6-6)
- (modified) flang/test/Lower/HLFIR/array-ctor-index.f90 (+4-4)
- (modified) flang/test/Lower/HLFIR/assumed-rank-calls.f90 (+6-6)
- (modified) flang/test/Lower/HLFIR/assumed-rank-entry.f90 (+1-1)
- (modified) flang/test/Lower/HLFIR/assumed-rank-iface-alloc-ptr.f90 (+5-5)
- (modified) flang/test/Lower/HLFIR/assumed-rank-iface.f90 (+9-9)
- (modified) flang/test/Lower/HLFIR/assumed-rank-inquiries-2.f90 (+5-5)
- (modified) flang/test/Lower/HLFIR/assumed-rank-inquiries.f90 (+24-24)
- (modified) flang/test/Lower/HLFIR/assumed-rank-internal-proc.f90 (+3-3)
- (modified) flang/test/Lower/HLFIR/binary-ops.f90 (+2-2)
- (modified) flang/test/Lower/HLFIR/bindc-value-derived.f90 (+2-2)
- (modified) flang/test/Lower/HLFIR/call-sequence-associated-descriptors.f90 (+8-8)
- (modified) flang/test/Lower/HLFIR/calls-array-results.f90 (+3-3)
- (modified) flang/test/Lower/HLFIR/calls-assumed-shape.f90 (+7-7)
- (modified) flang/test/Lower/HLFIR/calls-constant-expr-arg.f90 (+2-2)
- (modified) flang/test/Lower/HLFIR/calls-f77.f90 (+7-7)
- (modified) flang/test/Lower/HLFIR/calls-optional.f90 (+7-7)
- (modified) flang/test/Lower/HLFIR/calls-percent-val-ref.f90 (+6-6)
- (modified) flang/test/Lower/HLFIR/calls-poly-to-assumed-type.f90 (+1-1)
- (modified) flang/test/Lower/HLFIR/charconvert.f90 (+4-4)
- (modified) flang/test/Lower/HLFIR/complex-div-to-hlfir-kind10.f90 (+3-3)
- (modified) flang/test/Lower/HLFIR/complex-div-to-hlfir-kind16.f90 (+3-3)
- (modified) flang/test/Lower/HLFIR/complex-div-to-hlfir.f90 (+12-12)
- (modified) flang/test/Lower/HLFIR/convert-mbox-to-value.f90 (+8-8)
- (modified) flang/test/Lower/HLFIR/convert-variable-assumed-rank.f90 (+9-9)
- (modified) flang/test/Lower/HLFIR/convert-variable-block.f90 (+1-1)
- (modified) flang/test/Lower/HLFIR/convert-variable.f90 (+11-11)
- (modified) flang/test/Lower/HLFIR/cray-pointers.f90 (+5-5)
- (modified) flang/test/Lower/HLFIR/cshift.f90 (+3-3)
- (modified) flang/test/Lower/HLFIR/custom-intrinsic.f90 (+50-50)
- (modified) flang/test/Lower/HLFIR/designators-component-ref.f90 (+4-4)
- (modified) flang/test/Lower/HLFIR/designators.f90 (+20-20)
- (modified) flang/test/Lower/HLFIR/dot_product.f90 (+2-2)
- (added) flang/test/Lower/HLFIR/dummy-arg-number.f90 (+53)
- (modified) flang/test/Lower/HLFIR/dummy-scope.f90 (+2-2)
- (modified) flang/test/Lower/HLFIR/elemental-array-ops.f90 (+6-6)
- (modified) flang/test/Lower/HLFIR/elemental-polymorphic-merge.f90 (+4-4)
- (modified) flang/test/Lower/HLFIR/elemental-result-length.f90 (+6-6)
- (modified) flang/test/Lower/HLFIR/elemental-user-procedure-ref.f90 (+3-3)
- (modified) flang/test/Lower/HLFIR/eoshift.f90 (+11-11)
- (modified) flang/test/Lower/HLFIR/expr-addr.f90 (+1-1)
- (modified) flang/test/Lower/HLFIR/expr-box.f90 (+1-1)
- (modified) flang/test/Lower/HLFIR/expr-value.f90 (+1-1)
- (modified) flang/test/Lower/HLFIR/ignore-rank-unlimited-polymorphic.f90 (+5-5)
- (modified) flang/test/Lower/HLFIR/implicit-type-conversion.f90 (+14-14)
- (modified) flang/test/Lower/HLFIR/index.f90 (+12-12)
- (modified) flang/test/Lower/HLFIR/intentout-allocatable-components.f90 (+2-2)
- (modified) flang/test/Lower/HLFIR/internal-procedures.f90 (+1-1)
- (modified) flang/test/Lower/HLFIR/intrinsic-dynamically-optional.f90 (+2-2)
- (modified) flang/test/Lower/HLFIR/procedure-pointer.f90 (+3-3)
- (modified) flang/test/Lower/HLFIR/select-rank.f90 (+18-18)
- (modified) flang/test/Lower/HLFIR/statement-functions.f90 (+1-1)
- (modified) flang/test/Lower/HLFIR/structure-constructor.f90 (+8-8)
- (modified) flang/test/Lower/HLFIR/transformational.f90 (+1-1)
- (modified) flang/test/Lower/HLFIR/transpose.f90 (+5-5)
- (modified) flang/test/Lower/HLFIR/trim.f90 (+1-1)
- (modified) flang/test/Lower/HLFIR/user-defined-assignment.f90 (+19-19)
- (modified) flang/test/Lower/HLFIR/vector-subscript-as-value.f90 (+3-3)
- (modified) flang/test/Lower/Intrinsics/associated-proc-pointers.f90 (+6-6)
- (modified) flang/test/Lower/Intrinsics/c_f_procpointer.f90 (+4-4)
- (modified) flang/test/Lower/Intrinsics/c_funloc-proc-pointers.f90 (+2-2)
- (modified) flang/test/Lower/Intrinsics/c_ptr_eq_ne.f90 (+4-4)
- (modified) flang/test/Lower/Intrinsics/etime-function.f90 (+2-2)
- (modified) flang/test/Lower/Intrinsics/etime.f90 (+2-2)
- (modified) flang/test/Lower/Intrinsics/execute_command_line-optional.f90 (+5-5)
- (modified) flang/test/Lower/Intrinsics/execute_command_line.f90 (+6-6)
- (modified) flang/test/Lower/Intrinsics/getcwd-function.f90 (+1-1)
- (modified) flang/test/Lower/Intrinsics/getcwd-optional.f90 (+2-2)
- (modified) flang/test/Lower/Intrinsics/getcwd.f90 (+3-3)
- (modified) flang/test/Lower/Intrinsics/ieee_logb.f90 (+1-1)
- (modified) flang/test/Lower/Intrinsics/nearest.f90 (+14-14)
- (modified) flang/test/Lower/Intrinsics/perror.f90 (+1-1)
- (modified) flang/test/Lower/Intrinsics/putenv-sub.f90 (+3-3)
- (modified) flang/test/Lower/Intrinsics/rename.f90 (+4-4)
- (modified) flang/test/Lower/Intrinsics/second.f90 (+4-4)
- (modified) flang/test/Lower/Intrinsics/selected_char_kind.f90 (+1-1)
- (modified) flang/test/Lower/Intrinsics/selected_logical_kind.f90 (+5-5)
- (modified) flang/test/Lower/Intrinsics/signal.f90 (+1-1)
- (modified) flang/test/Lower/Intrinsics/sizeof.f90 (+2-2)
- (modified) flang/test/Lower/Intrinsics/system-optional.f90 (+2-2)
- (modified) flang/test/Lower/Intrinsics/system.f90 (+4-4)
- (modified) flang/test/Lower/Intrinsics/unlink-sub.f90 (+3-3)
- (modified) flang/test/Lower/OpenACC/acc-atomic-update-array.f90 (+9-9)
- (modified) flang/test/Lower/OpenACC/acc-bounds.f90 (+5-5)
- (modified) flang/test/Lower/OpenACC/acc-data-operands-remapping.f90 (+46-46)
- (modified) flang/test/Lower/OpenACC/acc-declare.f90 (+7-7)
- (modified) flang/test/Lower/OpenACC/acc-enter-data.f90 (+1-1)
- (modified) flang/test/Lower/OpenACC/acc-firstprivate-derived-pointer-component.f90 (+2-2)
- (modified) flang/test/Lower/OpenACC/acc-loop-exit.f90 (+1-1)
- (modified) flang/test/Lower/OpenACC/acc-private.f90 (+6-6)
- (modified) flang/test/Lower/OpenACC/acc-reduction.f90 (+4-4)
- (modified) flang/test/Lower/OpenACC/acc-use-device.f90 (+3-3)
- (modified) flang/test/Lower/OpenMP/allocatable-array-bounds.f90 (+1-1)
- (modified) flang/test/Lower/OpenMP/array-bounds.f90 (+2-2)
- (modified) flang/test/Lower/OpenMP/cancel.f90 (+4-4)
- (modified) flang/test/Lower/OpenMP/depend-complex.f90 (+1-1)
- (modified) flang/test/Lower/OpenMP/depend-substring.f90 (+4-4)
- (modified) flang/test/Lower/OpenMP/flush.f90 (+6-6)
- (modified) flang/test/Lower/OpenMP/optional-argument-map-2.f90 (+2-2)
- (modified) flang/test/Lower/OpenMP/parallel-firstprivate-clause-scalar.f90 (+21-21)
- (modified) flang/test/Lower/OpenMP/parallel-lastprivate-clause-scalar.f90 (+9-9)
- (modified) flang/test/Lower/OpenMP/parallel-private-clause-fixes.f90 (+3-3)
- (modified) flang/test/Lower/OpenMP/parallel-private-clause-str.f90 (+1-1)
- (modified) flang/test/Lower/OpenMP/parallel-reduction3.f90 (+1-1)
- (modified) flang/test/Lower/OpenMP/parallel-wsloop-firstpriv.f90 (+3-3)
- (modified) flang/test/Lower/OpenMP/parallel-wsloop-lastpriv.f90 (+5-5)
- (modified) flang/test/Lower/OpenMP/parallel-wsloop.f90 (+11-11)
- (modified) flang/test/Lower/OpenMP/reduction-array-intrinsic.f90 (+2-2)
- (modified) flang/test/Lower/OpenMP/sections-array-reduction.f90 (+1-1)
- (modified) flang/test/Lower/OpenMP/sections-reduction.f90 (+2-2)
- (modified) flang/test/Lower/OpenMP/sections.f90 (+1-1)
- (modified) flang/test/Lower/OpenMP/simd.f90 (+7-7)
- (modified) flang/test/Lower/OpenMP/single.f90 (+6-6)
- (modified) flang/test/Lower/OpenMP/target.f90 (+1-1)
- (modified) flang/test/Lower/OpenMP/task-depend-array-section.f90 (+4-4)
- (modified) flang/test/Lower/OpenMP/tile01.f90 (+3-3)
- (modified) flang/test/Lower/OpenMP/tile02.f90 (+3-3)
- (modified) flang/test/Lower/OpenMP/unroll-heuristic01.f90 (+3-3)
- (modified) flang/test/Lower/OpenMP/unroll-heuristic02.f90 (+6-6)
- (modified) flang/test/Lower/OpenMP/unroll-heuristic03.f90 (+3-3)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-array-assumed-shape.f90 (+1-1)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-iand-byref.f90 (+1-1)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-iand.f90 (+1-1)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-ieor-byref.f90 (+1-1)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-ieor.f90 (+1-1)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-ior-byref.f90 (+1-1)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-ior.f90 (+1-1)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-logical-and-byref.f90 (+3-3)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-logical-and.f90 (+3-3)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-logical-eqv-byref.f90 (+3-3)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-logical-eqv.f90 (+3-3)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-logical-neqv-byref.f90 (+3-3)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-logical-neqv.f90 (+3-3)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-logical-or-byref.f90 (+3-3)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-logical-or.f90 (+3-3)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-max-byref.f90 (+2-2)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-max.f90 (+2-2)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-min-byref.f90 (+2-2)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-min.f90 (+2-2)
- (modified) flang/test/Lower/allocatable-assignment.f90 (+30-30)
- (modified) flang/test/Lower/allocatable-polymorphic.f90 (+3-3)
- (modified) flang/test/Lower/array-character.f90 (+2-2)
- (modified) flang/test/Lower/array-elemental-calls-char-byval.f90 (+12-12)
- (modified) flang/test/Lower/array-elemental-calls-char-dynamic.f90 (+11-11)
- (modified) flang/test/Lower/array-elemental-calls-char.f90 (+15-15)
- (modified) flang/test/Lower/box-address.f90 (+1-1)
- (modified) flang/test/Lower/call-by-value-attr.f90 (+1-1)
- (modified) flang/test/Lower/call-character-array-to-polymorphic-pointer.f90 (+1-1)
- (modified) flang/test/Lower/character-substrings.f90 (+9-9)
- (modified) flang/test/Lower/charconvert.f90 (+4-4)
- (modified) flang/test/Lower/components.f90 (+7-7)
- (modified) flang/test/Lower/derived-assignments.f90 (+12-12)
- (modified) flang/test/Lower/dispatch.f90 (+15-15)
- (modified) flang/test/Lower/entry-statement.f90 (+6-6)
- (modified) flang/test/Lower/forall-pointer-assignment.f90 (+1-1)
- (modified) flang/test/Lower/forall/scalar-substring.f90 (+1-1)
- (modified) flang/test/Lower/structure-constructors-alloc-comp.f90 (+3-3)
- (modified) flang/test/Lower/unsigned-ops.f90 (+4-4)
- (modified) flang/test/Lower/volatile-derived-type.f90 (+1-1)
- (modified) flang/test/Lower/volatile-string.f90 (+2-2)
- (modified) flang/test/Lower/volatile3.f90 (+6-6)
- (modified) flang/test/Transforms/debug-dummy-argument.fir (+1-1)
- (modified) flang/test/Transforms/debug-local-var.fir (+6-6)
- (modified) flang/unittests/Optimizer/FortranVariableTest.cpp (+8-4)
``````````diff
diff --git a/flang/include/flang/Lower/AbstractConverter.h b/flang/include/flang/Lower/AbstractConverter.h
index f8322a50effc4..2031f3845509c 100644
--- a/flang/include/flang/Lower/AbstractConverter.h
+++ b/flang/include/flang/Lower/AbstractConverter.h
@@ -271,6 +271,12 @@ class AbstractConverter {
virtual bool
isRegisteredDummySymbol(Fortran::semantics::SymbolRef symRef) const = 0;
+ /// Get the source-level argument position (1-based) for a dummy symbol.
+ /// Returns 0 if the symbol is not a registered dummy or position is unknown.
+ /// Can only be used reliably during the instantiation of variables.
+ virtual unsigned
+ getDummyArgPosition(const Fortran::semantics::Symbol &sym) const = 0;
+
/// Returns the FunctionLikeUnit being lowered, if any.
virtual const Fortran::lower::pft::FunctionLikeUnit *
getCurrentFunctionUnit() const = 0;
diff --git a/flang/include/flang/Optimizer/Builder/HLFIRTools.h b/flang/include/flang/Optimizer/Builder/HLFIRTools.h
index 891373e8dbb0a..9933e3ed6c308 100644
--- a/flang/include/flang/Optimizer/Builder/HLFIRTools.h
+++ b/flang/include/flang/Optimizer/Builder/HLFIRTools.h
@@ -233,7 +233,7 @@ genDeclare(mlir::Location loc, fir::FirOpBuilder &builder,
fir::FortranVariableFlagsAttr flags,
mlir::Value dummyScope = nullptr, mlir::Value storage = nullptr,
std::uint64_t storageOffset = 0,
- cuf::DataAttributeAttr dataAttr = {});
+ cuf::DataAttributeAttr dataAttr = {}, unsigned dummyArgNo = 0);
/// Generate an hlfir.associate to build a variable from an expression value.
/// The type of the variable must be provided so that scalar logicals are
diff --git a/flang/include/flang/Optimizer/Dialect/FIRCG/CGOps.td b/flang/include/flang/Optimizer/Dialect/FIRCG/CGOps.td
index 04f839386498c..b29228eed1591 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRCG/CGOps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIRCG/CGOps.td
@@ -229,12 +229,13 @@ def fircg_XDeclareOp : fircg_Op<"ext_declare", [AttrSizedOperandSegments]> {
let arguments = (ins AnyRefOrBox:$memref, Variadic<AnyIntegerType>:$shape,
Variadic<AnyIntegerType>:$shift, Variadic<AnyIntegerType>:$typeparams,
- Optional<fir_DummyScopeType>:$dummy_scope, Builtin_StringAttr:$uniq_name);
+ Optional<fir_DummyScopeType>:$dummy_scope, Builtin_StringAttr:$uniq_name,
+ OptionalAttr<UI32Attr>:$dummy_arg_no);
let results = (outs AnyRefOrBox);
let assemblyFormat = [{
$memref (`(` $shape^ `)`)? (`origin` $shift^)? (`typeparams` $typeparams^)?
- (`dummy_scope` $dummy_scope^)?
+ (`dummy_scope` $dummy_scope^ (`arg` $dummy_arg_no^)?)?
attr-dict `:` functional-type(operands, results)
}];
diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td
index bae52d63fda45..da5f7da2f4229 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIROps.td
@@ -3274,13 +3274,14 @@ def fir_DeclareOp
DefaultValuedAttr<UI64Attr, "0">:$storage_offset,
Builtin_StringAttr:$uniq_name,
OptionalAttr<fir_FortranVariableFlagsAttr>:$fortran_attrs,
- OptionalAttr<cuf_DataAttributeAttr>:$data_attr);
+ OptionalAttr<cuf_DataAttributeAttr>:$data_attr,
+ OptionalAttr<UI32Attr>:$dummy_arg_no);
let results = (outs AnyRefOrBox);
let assemblyFormat = [{
$memref (`(` $shape^ `)`)? (`typeparams` $typeparams^)?
- (`dummy_scope` $dummy_scope^)?
+ (`dummy_scope` $dummy_scope^ (`arg` $dummy_arg_no^)?)?
(`storage` `(` $storage^ `[` $storage_offset `]` `)`)?
attr-dict `:` functional-type(operands, results)
}];
diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
index b7563a2f752f0..73f6be604a55c 100644
--- a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
+++ b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
@@ -103,13 +103,13 @@ def hlfir_DeclareOp
Builtin_StringAttr:$uniq_name,
OptionalAttr<fir_FortranVariableFlagsAttr>:$fortran_attrs,
OptionalAttr<cuf_DataAttributeAttr>:$data_attr,
- OptionalAttr<UnitAttr>:$skip_rebox);
+ OptionalAttr<UnitAttr>:$skip_rebox, OptionalAttr<UI32Attr>:$dummy_arg_no);
let results = (outs AnyFortranVariable, AnyRefOrBoxLike);
let assemblyFormat = [{
$memref (`(` $shape^ `)`)? (`typeparams` $typeparams^)?
- (`dummy_scope` $dummy_scope^)?
+ (`dummy_scope` $dummy_scope^ (`arg` $dummy_arg_no^)?)?
(`storage` `(` $storage^ `[` $storage_offset `]` `)`)?
(`skip_rebox` $skip_rebox^)?
attr-dict `:` functional-type(operands, results)
@@ -122,7 +122,8 @@ def hlfir_DeclareOp
CArg<"mlir::Value", "{}">:$storage,
CArg<"std::uint64_t", "0">:$storage_offset,
CArg<"fir::FortranVariableFlagsAttr", "{}">:$fortran_attrs,
- CArg<"cuf::DataAttributeAttr", "{}">:$data_attr)>];
+ CArg<"cuf::DataAttributeAttr", "{}">:$data_attr,
+ CArg<"unsigned", "0">:$dummy_arg_no)>];
let extraClassDeclaration = [{
/// Get the variable original base (same as input). It lacks
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 5779bcd5d293c..364471eaf9df5 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -1129,6 +1129,12 @@ class FirConverter : public Fortran::lower::AbstractConverter {
return registeredDummySymbols.contains(sym);
}
+ unsigned getDummyArgPosition(
+ const Fortran::semantics::Symbol &sym) const override final {
+ auto it = dummyArgPositions.find(&sym);
+ return (it != dummyArgPositions.end()) ? it->second : 0;
+ }
+
const Fortran::lower::pft::FunctionLikeUnit *
getCurrentFunctionUnit() const override final {
return currentFunctionUnit;
@@ -1413,11 +1419,14 @@ class FirConverter : public Fortran::lower::AbstractConverter {
/// definitive mapping. The specification expression have not been lowered
/// yet. The final mapping will be done using this pre-mapping in
/// Fortran::lower::mapSymbolAttributes.
+ /// \param argNo The 1-based source position of this argument (0 if
+ /// unknown/result)
bool mapBlockArgToDummyOrResult(const Fortran::semantics::SymbolRef sym,
- mlir::Value val, bool isResult) {
+ mlir::Value val, bool isResult,
+ unsigned argNo = 0) {
localSymbols.addSymbol(sym, val);
if (!isResult)
- registerDummySymbol(sym);
+ registerDummySymbol(sym, argNo);
return true;
}
@@ -5962,7 +5971,16 @@ class FirConverter : public Fortran::lower::AbstractConverter {
const Fortran::lower::CalleeInterface &callee) {
assert(builder && "require a builder object at this point");
using PassBy = Fortran::lower::CalleeInterface::PassEntityBy;
+
+ // Track the source-level argument position (1-based)
+ unsigned argPosition = 0;
+
auto mapPassedEntity = [&](const auto arg, bool isResult = false) {
+ // Count only actual source-level dummy arguments (not results or
+ // host assoc tuples)
+ if (!isResult && arg.entity.has_value())
+ argPosition++;
+
if (arg.passBy == PassBy::AddressAndLength) {
if (callee.characterize().IsBindC())
return;
@@ -5973,11 +5991,12 @@ class FirConverter : public Fortran::lower::AbstractConverter {
mlir::Value casted =
builder->createVolatileCast(loc, false, arg.firArgument);
mlir::Value box = charHelp.createEmboxChar(casted, arg.firLength);
- mapBlockArgToDummyOrResult(arg.entity->get(), box, isResult);
+ mapBlockArgToDummyOrResult(arg.entity->get(), box, isResult,
+ isResult ? 0 : argPosition);
} else {
if (arg.entity.has_value()) {
mapBlockArgToDummyOrResult(arg.entity->get(), arg.firArgument,
- isResult);
+ isResult, isResult ? 0 : argPosition);
} else {
assert(funit.parentHasTupleHostAssoc() && "expect tuple argument");
}
@@ -6835,13 +6854,22 @@ class FirConverter : public Fortran::lower::AbstractConverter {
}
/// Record the given symbol as a dummy argument of this function.
- void registerDummySymbol(Fortran::semantics::SymbolRef symRef) {
+ /// \param symRef The symbol representing the dummy argument
+ /// \param argNo The 1-based position of this argument in the source (0 =
+ /// unknown)
+ void registerDummySymbol(Fortran::semantics::SymbolRef symRef,
+ unsigned argNo = 0) {
auto *sym = &*symRef;
registeredDummySymbols.insert(sym);
+ if (argNo > 0)
+ dummyArgPositions[sym] = argNo;
}
/// Reset all registered dummy symbols.
- void resetRegisteredDummySymbols() { registeredDummySymbols.clear(); }
+ void resetRegisteredDummySymbols() {
+ registeredDummySymbols.clear();
+ dummyArgPositions.clear();
+ }
void setCurrentFunctionUnit(Fortran::lower::pft::FunctionLikeUnit *unit) {
currentFunctionUnit = unit;
@@ -6883,6 +6911,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
llvm::SmallPtrSet<const Fortran::semantics::Symbol *, 16>
registeredDummySymbols;
+ /// Map from dummy symbols to their 1-based argument positions.
+ /// Used to generate debug info with correct argument numbers.
+ llvm::DenseMap<const Fortran::semantics::Symbol *, unsigned>
+ dummyArgPositions;
+
/// A map of unique names for constant expressions.
/// The names are used for representing the constant expressions
/// with global constant initialized objects.
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index 2517ab35d4ff0..53d4d7566acfa 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -1946,12 +1946,15 @@ static void genDeclareSymbol(Fortran::lower::AbstractConverter &converter,
return;
}
mlir::Value dummyScope;
- if (converter.isRegisteredDummySymbol(sym))
+ unsigned argNo = 0;
+ if (converter.isRegisteredDummySymbol(sym)) {
dummyScope = converter.dummyArgsScopeValue();
+ argNo = converter.getDummyArgPosition(sym);
+ }
auto [storage, storageOffset] = converter.getSymbolStorage(sym);
auto newBase = hlfir::DeclareOp::create(
builder, loc, base, name, shapeOrShift, lenParams, dummyScope, storage,
- storageOffset, attributes, dataAttr);
+ storageOffset, attributes, dataAttr, argNo);
symMap.addVariableDefinition(sym, newBase, force);
return;
}
@@ -2004,15 +2007,17 @@ void Fortran::lower::genDeclareSymbol(
sym.GetUltimate());
auto name = converter.mangleName(sym);
mlir::Value dummyScope;
+ unsigned argNo = 0;
fir::ExtendedValue base = exv;
if (converter.isRegisteredDummySymbol(sym)) {
base = genPackArray(converter, sym, exv);
dummyScope = converter.dummyArgsScopeValue();
+ argNo = converter.getDummyArgPosition(sym);
}
auto [storage, storageOffset] = converter.getSymbolStorage(sym);
hlfir::EntityWithAttributes declare =
hlfir::genDeclare(loc, builder, base, name, attributes, dummyScope,
- storage, storageOffset, dataAttr);
+ storage, storageOffset, dataAttr, argNo);
symMap.addVariableDefinition(sym, declare.getIfVariableInterface(), force);
return;
}
diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
index 5da27d1713825..6ef6074cf73ad 100644
--- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp
+++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
@@ -427,7 +427,8 @@ mlir::Value fir::FirOpBuilder::genTempDeclareOp(
builder, loc, memref.getType(), memref, shape, typeParams,
/*dummy_scope=*/nullptr,
/*storage=*/nullptr,
- /*storage_offset=*/0, nameAttr, fortranAttrs, cuf::DataAttributeAttr{});
+ /*storage_offset=*/0, nameAttr, fortranAttrs, cuf::DataAttributeAttr{},
+ /*dummy_arg_no=*/mlir::IntegerAttr{});
}
mlir::Value fir::FirOpBuilder::genStackSave(mlir::Location loc) {
diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
index 793be32400db6..b435ae15cff58 100644
--- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp
+++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
@@ -250,7 +250,7 @@ hlfir::genDeclare(mlir::Location loc, fir::FirOpBuilder &builder,
const fir::ExtendedValue &exv, llvm::StringRef name,
fir::FortranVariableFlagsAttr flags, mlir::Value dummyScope,
mlir::Value storage, std::uint64_t storageOffset,
- cuf::DataAttributeAttr dataAttr) {
+ cuf::DataAttributeAttr dataAttr, unsigned dummyArgNo) {
mlir::Value base = fir::getBase(exv);
assert(fir::conformsWithPassByRef(base.getType()) &&
@@ -281,7 +281,7 @@ hlfir::genDeclare(mlir::Location loc, fir::FirOpBuilder &builder,
[](const auto &) {});
auto declareOp = hlfir::DeclareOp::create(
builder, loc, base, name, shapeOrShift, lenParams, dummyScope, storage,
- storageOffset, flags, dataAttr);
+ storageOffset, flags, dataAttr, dummyArgNo);
return mlir::cast<fir::FortranVariableOpInterface>(declareOp.getOperation());
}
diff --git a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
index 1b1d43c11c707..bafeb32660e6c 100644
--- a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
+++ b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
@@ -302,11 +302,15 @@ class DeclareOpConversion : public mlir::OpRewritePattern<fir::DeclareOp> {
else
return mlir::failure();
}
+ // Extract dummy_arg_no attribute if present
+ mlir::IntegerAttr dummyArgNoAttr;
+ if (auto attr = declareOp->getAttrOfType<mlir::IntegerAttr>("dummy_arg_no"))
+ dummyArgNoAttr = attr;
// FIXME: Add FortranAttrs and CudaAttrs
auto xDeclOp = fir::cg::XDeclareOp::create(
rewriter, loc, declareOp.getType(), declareOp.getMemref(), shapeOpers,
shiftOpers, declareOp.getTypeparams(), declareOp.getDummyScope(),
- declareOp.getUniqName());
+ declareOp.getUniqName(), dummyArgNoAttr);
LLVM_DEBUG(llvm::dbgs()
<< "rewriting " << declareOp << " to " << xDeclOp << '\n');
rewriter.replaceOp(declareOp, xDeclOp.getOperation()->getResults());
diff --git a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
index 1332dc57fb086..8d6b888789c15 100644
--- a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
+++ b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
@@ -261,14 +261,12 @@ updateDeclaredInputTypeWithVolatility(mlir::Type inputType, mlir::Value memref,
return std::make_pair(inputType, memref);
}
-void hlfir::DeclareOp::build(mlir::OpBuilder &builder,
- mlir::OperationState &result, mlir::Value memref,
- llvm::StringRef uniq_name, mlir::Value shape,
- mlir::ValueRange typeparams,
- mlir::Value dummy_scope, mlir::Value storage,
- std::uint64_t storage_offset,
- fir::FortranVariableFlagsAttr fortran_attrs,
- cuf::DataAttributeAttr data_attr) {
+void hlfir::DeclareOp::build(
+ mlir::OpBuilder &builder, mlir::OperationState &result, mlir::Value memref,
+ llvm::StringRef uniq_name, mlir::Value shape, mlir::ValueRange typeparams,
+ mlir::Value dummy_scope, mlir::Value storage, std::uint64_t storage_offset,
+ fir::FortranVariableFlagsAttr fortran_attrs,
+ cuf::DataAttributeAttr data_attr, unsigned dummy_arg_no) {
auto nameAttr = builder.getStringAttr(uniq_name);
mlir::Type inputType = memref.getType();
bool hasExplicitLbs = hasExplicitLowerBounds(shape);
@@ -279,9 +277,12 @@ void hlfir::DeclareOp::build(mlir::OpBuilder &builder,
}
auto [hlfirVariableType, firVarType] =
getDeclareOutputTypes(inputType, hasExplicitLbs);
+ mlir::IntegerAttr argNoAttr;
+ if (dummy_arg_no > 0)
+ argNoAttr = builder.getUI32IntegerAttr(dummy_arg_no);
build(builder, result, {hlfirVariableType, firVarType}, memref, shape,
typeparams, dummy_scope, storage, storage_offset, nameAttr,
- fortran_attrs, data_attr, /*skip_rebox=*/mlir::UnitAttr{});
+ fortran_attrs, data_attr, /*skip_rebox=*/mlir::UnitAttr{}, argNoAttr);
}
llvm::LogicalResult hlfir::DeclareOp::verify() {
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
index 6a57bf2ae6fec..4c3f37bdead3f 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
@@ -308,7 +308,8 @@ class DeclareOpConversion : public mlir::OpRewritePattern<hlfir::DeclareOp> {
declareOp.getTypeparams(), declareOp.getDummyScope(),
/*storage=*/declareOp.getStorage(),
/*storage_offset=*/declareOp.getStorageOffset(),
- declareOp.getUniqName(), fortranAttrs, dataAttr);
+ declareOp.getUniqName(), fortranAttrs, dataAttr,
+ declareOp.getDummyArgNoAttr());
// Propagate other attributes from hlfir.declare to fir.declare.
// OpenACC's acc.declare is one example. Right now, the propagation
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index e006d2e878fd8..00633b4104b6c 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -228,24 +228,11 @@ void AddDebugInfoPass::handleDeclareOp(fir::cg::XDeclareOp declOp,
}
}
- // FIXME: There may be cases where an argument is processed a bit before
- // DeclareOp is generated. In that case, DeclareOp may point to an
- // intermediate op and not to BlockArgument.
- // Moreover, with MLIR inlining we cannot use the BlockArgument
- // position to identify the original number of the dummy argument.
- // If we want to keep running AddDebugInfoPass late, the dummy argument
- // position in the argument list has to be expressed in FIR (e.g. as a
- // constant attribute of [hl]fir.declare/fircg.ext_declare operation that has
- // a dummy_scope operand).
+ // Get the dummy argument position from the explicit attribute.
unsigned argNo = 0;
if (declOp.getDummyScope()) {
- if (auto arg = llvm::dyn_cast<mlir::BlockArgument>(declOp.getMemref())) {
- // Check if it is the BlockArgument of the function's entry block.
- if (auto funcLikeOp =
- declOp->getParentOfType<mlir::FunctionOpInterface>())
- if (arg.getOwner() == &funcLikeOp.front())
- argNo = arg.getArgNumber() + 1;
- }
+ if (auto argNoOpt = declOp.getDummyArgNo())
+ argNo = *argNoOpt;
}
auto tyAttr = typeGen.convertType(fir::unwrapRefType(declOp.getType()),
diff --git a/flang/test/Fir/dispatch.f90 b/flang/test/Fir/dispatch.f90
index 2b1ae225986ca..9219e5453c779 100644
--- a/flang/test/Fir/dispatch.f90
+++ b/flang/test/Fir/dispatch.f90
@@ -195,7 +195,7 @@ program test_type_to_class
! CHECK-LABEL: func.func @_QMdispatch1Pdisplay_class(
! CHECK-SAME: %[[ARG:.*]]: [[CLASS:!fir.class<.*>>]]
-! CHECK: %[[ARG_DECL:.*]]:2 = hlfir.declare %[[ARG]] dummy_scope %{{[0-9]+}} {uniq_name = "_QMdispatch1Fdisplay_classEp"} : (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>, !fir.dscope) -> (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>, !fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>)
+! CHECK: %[[ARG_DECL:.*]]:2 = hlfir.declare %[[ARG]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QMdispatch1Fdisplay_classEp"} : (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>, !fir.dscope) -> (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>, !fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>)
! Check dynamic dispatch equal to `call p%display2()` with binding index = 2.
! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG_DECL]]#0 : ([[CLASS]]) -> !fir.tdesc<none>
diff --git a/flang/test/HLFIR/assumed-type-actual-args.f90 b/flang/test/HLFIR/assumed-type-actual-args.f90
index aaac98...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/167489
More information about the flang-commits
mailing list