@@ -900,6 +900,16 @@ class FirConverter : public Fortran::lower::AbstractConverter {
900
900
hostAssocTuple = val;
901
901
}
902
902
903
+ mlir::Value dummyArgsScopeValue () const override final {
904
+ return dummyArgsScope;
905
+ }
906
+
907
+ bool isRegisteredDummySymbol (
908
+ Fortran::semantics::SymbolRef symRef) const override final {
909
+ auto *sym = &*symRef;
910
+ return registeredDummySymbols.contains (sym);
911
+ }
912
+
903
913
void registerTypeInfo (mlir::Location loc,
904
914
Fortran::lower::SymbolRef typeInfoSym,
905
915
const Fortran::semantics::DerivedTypeSpec &typeSpec,
@@ -1145,10 +1155,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
1145
1155
// / yet. The final mapping will be done using this pre-mapping in
1146
1156
// / Fortran::lower::mapSymbolAttributes.
1147
1157
bool mapBlockArgToDummyOrResult (const Fortran::semantics::SymbolRef sym,
1148
- mlir::Value val, bool forced = false ) {
1149
- if (!forced && lookupSymbol (sym))
1150
- return false ;
1151
- localSymbols.addSymbol (sym, val, forced);
1158
+ mlir::Value val, bool isResult) {
1159
+ localSymbols.addSymbol (sym, val);
1160
+ if (!isResult)
1161
+ registerDummySymbol (sym);
1162
+
1152
1163
return true ;
1153
1164
}
1154
1165
@@ -4559,7 +4570,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
4559
4570
const Fortran::lower::CalleeInterface &callee) {
4560
4571
assert (builder && " require a builder object at this point" );
4561
4572
using PassBy = Fortran::lower::CalleeInterface::PassEntityBy;
4562
- auto mapPassedEntity = [&](const auto arg) {
4573
+ auto mapPassedEntity = [&](const auto arg, bool isResult = false ) {
4563
4574
if (arg.passBy == PassBy::AddressAndLength) {
4564
4575
if (callee.characterize ().IsBindC ())
4565
4576
return ;
@@ -4569,10 +4580,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
4569
4580
fir::factory::CharacterExprHelper charHelp{*builder, loc};
4570
4581
mlir::Value box =
4571
4582
charHelp.createEmboxChar (arg.firArgument , arg.firLength );
4572
- mapBlockArgToDummyOrResult (arg.entity ->get (), box);
4583
+ mapBlockArgToDummyOrResult (arg.entity ->get (), box, isResult );
4573
4584
} else {
4574
4585
if (arg.entity .has_value ()) {
4575
- mapBlockArgToDummyOrResult (arg.entity ->get (), arg.firArgument );
4586
+ mapBlockArgToDummyOrResult (arg.entity ->get (), arg.firArgument ,
4587
+ isResult);
4576
4588
} else {
4577
4589
assert (funit.parentHasTupleHostAssoc () && " expect tuple argument" );
4578
4590
}
@@ -4581,15 +4593,19 @@ class FirConverter : public Fortran::lower::AbstractConverter {
4581
4593
for (const Fortran::lower::CalleeInterface::PassedEntity &arg :
4582
4594
callee.getPassedArguments ())
4583
4595
mapPassedEntity (arg);
4596
+ if (lowerToHighLevelFIR () && !callee.getPassedArguments ().empty ()) {
4597
+ mlir::Value scopeOp = builder->create <fir::DummyScopeOp>(toLocation ());
4598
+ setDummyArgsScope (scopeOp);
4599
+ }
4584
4600
if (std::optional<Fortran::lower::CalleeInterface::PassedEntity>
4585
4601
passedResult = callee.getPassedResult ()) {
4586
- mapPassedEntity (*passedResult);
4602
+ mapPassedEntity (*passedResult, /* isResult= */ true );
4587
4603
// FIXME: need to make sure things are OK here. addSymbol may not be OK
4588
4604
if (funit.primaryResult &&
4589
4605
passedResult->entity ->get () != *funit.primaryResult )
4590
4606
mapBlockArgToDummyOrResult (
4591
- *funit.primaryResult ,
4592
- getSymbolAddress (passedResult-> entity -> get ()) );
4607
+ *funit.primaryResult , getSymbolAddress (passedResult-> entity -> get ()),
4608
+ /* isResult= */ true );
4593
4609
}
4594
4610
}
4595
4611
@@ -4766,7 +4782,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
4766
4782
Fortran::lower::StatementContext stmtCtx;
4767
4783
if (std::optional<Fortran::lower::CalleeInterface::PassedEntity>
4768
4784
passedResult = callee.getPassedResult ()) {
4769
- mapBlockArgToDummyOrResult (altResult.getSymbol (), resultArg.getAddr ());
4785
+ mapBlockArgToDummyOrResult (altResult.getSymbol (), resultArg.getAddr (),
4786
+ /* isResult=*/ true );
4770
4787
Fortran::lower::mapSymbolAttributes (*this , altResult, localSymbols,
4771
4788
stmtCtx);
4772
4789
} else {
@@ -4810,6 +4827,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
4810
4827
if (!funit.getHostAssoc ().empty ())
4811
4828
funit.getHostAssoc ().hostProcedureBindings (*this , localSymbols);
4812
4829
4830
+ // Unregister all dummy symbols, so that their cloning (e.g. for OpenMP
4831
+ // privatization) does not create the cloned hlfir.declare operations
4832
+ // with dummy_scope operands.
4833
+ resetRegisteredDummySymbols ();
4834
+
4813
4835
// Create most function blocks in advance.
4814
4836
createEmptyBlocks (funit.evaluationList );
4815
4837
@@ -4929,6 +4951,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
4929
4951
hostAssocTuple = mlir::Value{};
4930
4952
localSymbols.clear ();
4931
4953
blockId = 0 ;
4954
+ dummyArgsScope = mlir::Value{};
4955
+ resetRegisteredDummySymbols ();
4932
4956
}
4933
4957
4934
4958
// / Helper to generate GlobalOps when the builder is not positioned in any
@@ -4957,6 +4981,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
4957
4981
delete builder;
4958
4982
builder = nullptr ;
4959
4983
localSymbols.clear ();
4984
+ resetRegisteredDummySymbols ();
4960
4985
}
4961
4986
4962
4987
// / Instantiate the data from a BLOCK DATA unit.
@@ -5374,6 +5399,23 @@ class FirConverter : public Fortran::lower::AbstractConverter {
5374
5399
globalOmpRequiresSymbol);
5375
5400
}
5376
5401
5402
+ // / Record fir.dummy_scope operation for this function.
5403
+ // / It will be used to set dummy_scope operand of the hlfir.declare
5404
+ // / operations.
5405
+ void setDummyArgsScope (mlir::Value val) {
5406
+ assert (!dummyArgsScope && val);
5407
+ dummyArgsScope = val;
5408
+ }
5409
+
5410
+ // / Record the given symbol as a dummy argument of this function.
5411
+ void registerDummySymbol (Fortran::semantics::SymbolRef symRef) {
5412
+ auto *sym = &*symRef;
5413
+ registeredDummySymbols.insert (sym);
5414
+ }
5415
+
5416
+ // / Reset all registered dummy symbols.
5417
+ void resetRegisteredDummySymbols () { registeredDummySymbols.clear (); }
5418
+
5377
5419
// ===--------------------------------------------------------------------===//
5378
5420
5379
5421
Fortran::lower::LoweringBridge &bridge;
@@ -5400,6 +5442,15 @@ class FirConverter : public Fortran::lower::AbstractConverter {
5400
5442
// / Tuple of host associated variables
5401
5443
mlir::Value hostAssocTuple;
5402
5444
5445
+ // / Value of fir.dummy_scope operation for this function.
5446
+ mlir::Value dummyArgsScope;
5447
+
5448
+ // / A set of dummy argument symbols for this function.
5449
+ // / The set is only preserved during the instatiation
5450
+ // / of variables for this function.
5451
+ llvm::SmallPtrSet<const Fortran::semantics::Symbol *, 16 >
5452
+ registeredDummySymbols;
5453
+
5403
5454
// / A map of unique names for constant expressions.
5404
5455
// / The names are used for representing the constant expressions
5405
5456
// / with global constant initialized objects.
0 commit comments