Skip to content

Commit 97753ee

Browse files
authored
merge main into amd-staging (llvm#2555)
2 parents ab3ea8c + 3c81b3b commit 97753ee

File tree

69 files changed

+4801
-3156
lines changed

Some content is hidden

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

69 files changed

+4801
-3156
lines changed

compiler-rt/test/lit.common.configured.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ set_default("gold_executable", "@GOLD_EXECUTABLE@")
2525
set_default("clang", "@COMPILER_RT_RESOLVED_TEST_COMPILER@")
2626
set_default("compiler_id", "@COMPILER_RT_TEST_COMPILER_ID@")
2727
set_default("python_executable", "@Python3_EXECUTABLE@")
28+
set_default("python_root_dir", "@Python3_ROOT_DIR@")
2829
set_default("compiler_rt_debug", @COMPILER_RT_DEBUG_PYBOOL@)
2930
set_default("compiler_rt_intercept_libdispatch", @COMPILER_RT_INTERCEPT_LIBDISPATCH_PYBOOL@)
3031
set_default("compiler_rt_output_dir", "@COMPILER_RT_RESOLVED_OUTPUT_DIR@")

flang/include/flang/Semantics/symbol.h

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ class raw_ostream;
3030
}
3131
namespace Fortran::parser {
3232
struct Expr;
33+
struct OpenMPDeclareReductionConstruct;
34+
struct OmpMetadirectiveDirective;
3335
}
3436

3537
namespace Fortran::semantics {
@@ -728,14 +730,48 @@ class GenericDetails {
728730
};
729731
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const GenericDetails &);
730732

733+
// Used for OpenMP DECLARE REDUCTION, it holds the information
734+
// needed to resolve which declaration (there could be multiple
735+
// with the same name) to use for a given type.
736+
class UserReductionDetails {
737+
public:
738+
using TypeVector = std::vector<const DeclTypeSpec *>;
739+
using DeclInfo = std::variant<const parser::OpenMPDeclareReductionConstruct *,
740+
const parser::OmpMetadirectiveDirective *>;
741+
using DeclVector = std::vector<DeclInfo>;
742+
743+
UserReductionDetails() = default;
744+
745+
void AddType(const DeclTypeSpec &type) { typeList_.push_back(&type); }
746+
const TypeVector &GetTypeList() const { return typeList_; }
747+
748+
bool SupportsType(const DeclTypeSpec &type) const {
749+
// We have to compare the actual type, not the pointer, as some
750+
// types are not guaranteed to be the same object.
751+
for (auto t : typeList_) {
752+
if (*t == type) {
753+
return true;
754+
}
755+
}
756+
return false;
757+
}
758+
759+
void AddDecl(const DeclInfo &decl) { declList_.emplace_back(decl); }
760+
const DeclVector &GetDeclList() const { return declList_; }
761+
762+
private:
763+
TypeVector typeList_;
764+
DeclVector declList_;
765+
};
766+
731767
class UnknownDetails {};
732768

733769
using Details = std::variant<UnknownDetails, MainProgramDetails, ModuleDetails,
734770
SubprogramDetails, SubprogramNameDetails, EntityDetails,
735771
ObjectEntityDetails, ProcEntityDetails, AssocEntityDetails,
736772
DerivedTypeDetails, UseDetails, UseErrorDetails, HostAssocDetails,
737773
GenericDetails, ProcBindingDetails, NamelistDetails, CommonBlockDetails,
738-
TypeParamDetails, MiscDetails>;
774+
TypeParamDetails, MiscDetails, UserReductionDetails>;
739775
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Details &);
740776
std::string DetailsToString(const Details &);
741777

flang/lib/Parser/unparse.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3368,4 +3368,12 @@ template void Unparse<Program>(llvm::raw_ostream &, const Program &,
33683368
template void Unparse<Expr>(llvm::raw_ostream &, const Expr &,
33693369
const common::LangOptions &, Encoding, bool, bool, preStatementType *,
33703370
AnalyzedObjectsAsFortran *);
3371+
3372+
template void Unparse<parser::OpenMPDeclareReductionConstruct>(
3373+
llvm::raw_ostream &, const parser::OpenMPDeclareReductionConstruct &,
3374+
const common::LangOptions &, Encoding, bool, bool, preStatementType *,
3375+
AnalyzedObjectsAsFortran *);
3376+
template void Unparse<parser::OmpMetadirectiveDirective>(llvm::raw_ostream &,
3377+
const parser::OmpMetadirectiveDirective &, const common::LangOptions &,
3378+
Encoding, bool, bool, preStatementType *, AnalyzedObjectsAsFortran *);
33713379
} // namespace Fortran::parser

flang/lib/Semantics/assignment.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class AssignmentContext {
4343
void Analyze(const parser::PointerAssignmentStmt &);
4444
void Analyze(const parser::ConcurrentControl &);
4545
int deviceConstructDepth_{0};
46+
SemanticsContext &context() { return context_; }
4647

4748
private:
4849
bool CheckForPureContext(const SomeExpr &rhs, parser::CharBlock rhsSource);
@@ -218,8 +219,17 @@ void AssignmentContext::PopWhereContext() {
218219

219220
AssignmentChecker::~AssignmentChecker() {}
220221

222+
SemanticsContext &AssignmentChecker::context() {
223+
return context_.value().context();
224+
}
225+
221226
AssignmentChecker::AssignmentChecker(SemanticsContext &context)
222227
: context_{new AssignmentContext{context}} {}
228+
229+
void AssignmentChecker::Enter(
230+
const parser::OpenMPDeclareReductionConstruct &x) {
231+
context().set_location(x.source);
232+
}
223233
void AssignmentChecker::Enter(const parser::AssignmentStmt &x) {
224234
context_.value().Analyze(x);
225235
}

flang/lib/Semantics/assignment.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class AssignmentChecker : public virtual BaseChecker {
3737
public:
3838
explicit AssignmentChecker(SemanticsContext &);
3939
~AssignmentChecker();
40+
void Enter(const parser::OpenMPDeclareReductionConstruct &x);
4041
void Enter(const parser::AssignmentStmt &);
4142
void Enter(const parser::PointerAssignmentStmt &);
4243
void Enter(const parser::WhereStmt &);
@@ -54,6 +55,8 @@ class AssignmentChecker : public virtual BaseChecker {
5455
void Enter(const parser::OpenACCLoopConstruct &);
5556
void Leave(const parser::OpenACCLoopConstruct &);
5657

58+
SemanticsContext &context();
59+
5760
private:
5861
common::Indirection<AssignmentContext> context_;
5962
};

flang/lib/Semantics/check-omp-structure.cpp

Lines changed: 68 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "check-omp-structure.h"
1010
#include "definable.h"
11+
#include "resolve-names-utils.h"
1112
#include "flang/Evaluate/check-expression.h"
1213
#include "flang/Evaluate/expression.h"
1314
#include "flang/Evaluate/type.h"
@@ -3507,6 +3508,17 @@ bool OmpStructureChecker::CheckReductionOperator(
35073508
break;
35083509
}
35093510
}
3511+
// User-defined operators are OK if there has been a declared reduction
3512+
// for that. We mangle those names to store the user details.
3513+
if (const auto *definedOp{std::get_if<parser::DefinedOpName>(&dOpr.u)}) {
3514+
std::string mangled{MangleDefinedOperator(definedOp->v.symbol->name())};
3515+
const Scope &scope{definedOp->v.symbol->owner()};
3516+
if (const Symbol *symbol{scope.FindSymbol(mangled)}) {
3517+
if (symbol->detailsIf<UserReductionDetails>()) {
3518+
return true;
3519+
}
3520+
}
3521+
}
35103522
context_.Say(source, "Invalid reduction operator in %s clause."_err_en_US,
35113523
parser::ToUpperCaseLetters(getClauseName(clauseId).str()));
35123524
return false;
@@ -3520,8 +3532,7 @@ bool OmpStructureChecker::CheckReductionOperator(
35203532
valid =
35213533
llvm::is_contained({"max", "min", "iand", "ior", "ieor"}, realName);
35223534
if (!valid) {
3523-
auto *misc{name->symbol->detailsIf<MiscDetails>()};
3524-
valid = misc && misc->kind() == MiscDetails::Kind::ConstructName;
3535+
valid = name->symbol->detailsIf<UserReductionDetails>();
35253536
}
35263537
}
35273538
if (!valid) {
@@ -3601,8 +3612,20 @@ void OmpStructureChecker::CheckReductionObjects(
36013612
}
36023613
}
36033614

3615+
static bool CheckSymbolSupportsType(const Scope &scope,
3616+
const parser::CharBlock &name, const DeclTypeSpec &type) {
3617+
if (const auto *symbol{scope.FindSymbol(name)}) {
3618+
if (const auto *reductionDetails{
3619+
symbol->detailsIf<UserReductionDetails>()}) {
3620+
return reductionDetails->SupportsType(type);
3621+
}
3622+
}
3623+
return false;
3624+
}
3625+
36043626
static bool IsReductionAllowedForType(
3605-
const parser::OmpReductionIdentifier &ident, const DeclTypeSpec &type) {
3627+
const parser::OmpReductionIdentifier &ident, const DeclTypeSpec &type,
3628+
const Scope &scope, SemanticsContext &context) {
36063629
auto isLogical{[](const DeclTypeSpec &type) -> bool {
36073630
return type.category() == DeclTypeSpec::Logical;
36083631
}};
@@ -3622,27 +3645,40 @@ static bool IsReductionAllowedForType(
36223645
case parser::DefinedOperator::IntrinsicOperator::Multiply:
36233646
case parser::DefinedOperator::IntrinsicOperator::Add:
36243647
case parser::DefinedOperator::IntrinsicOperator::Subtract:
3625-
return type.IsNumeric(TypeCategory::Integer) ||
3648+
if (type.IsNumeric(TypeCategory::Integer) ||
36263649
type.IsNumeric(TypeCategory::Real) ||
3627-
type.IsNumeric(TypeCategory::Complex);
3650+
type.IsNumeric(TypeCategory::Complex))
3651+
return true;
3652+
break;
36283653

36293654
case parser::DefinedOperator::IntrinsicOperator::AND:
36303655
case parser::DefinedOperator::IntrinsicOperator::OR:
36313656
case parser::DefinedOperator::IntrinsicOperator::EQV:
36323657
case parser::DefinedOperator::IntrinsicOperator::NEQV:
3633-
return isLogical(type);
3658+
if (isLogical(type)) {
3659+
return true;
3660+
}
3661+
break;
36343662

36353663
// Reduction identifier is not in OMP5.2 Table 5.2
36363664
default:
36373665
DIE("This should have been caught in CheckIntrinsicOperator");
36383666
return false;
36393667
}
3640-
}
3641-
return true;
3668+
parser::CharBlock name{MakeNameFromOperator(*intrinsicOp, context)};
3669+
return CheckSymbolSupportsType(scope, name, type);
3670+
} else if (const auto *definedOp{
3671+
std::get_if<parser::DefinedOpName>(&dOpr.u)}) {
3672+
return CheckSymbolSupportsType(
3673+
scope, MangleDefinedOperator(definedOp->v.symbol->name()), type);
3674+
}
3675+
llvm_unreachable(
3676+
"A DefinedOperator is either a DefinedOpName or an IntrinsicOperator");
36423677
}};
36433678

36443679
auto checkDesignator{[&](const parser::ProcedureDesignator &procD) {
36453680
const parser::Name *name{std::get_if<parser::Name>(&procD.u)};
3681+
CHECK(name && name->symbol);
36463682
if (name && name->symbol) {
36473683
const SourceName &realName{name->symbol->GetUltimate().name()};
36483684
// OMP5.2: The type [...] of a list item that appears in a
@@ -3651,18 +3687,35 @@ static bool IsReductionAllowedForType(
36513687
// IAND: arguments must be integers: F2023 16.9.100
36523688
// IEOR: arguments must be integers: F2023 16.9.106
36533689
// IOR: arguments must be integers: F2023 16.9.111
3654-
return type.IsNumeric(TypeCategory::Integer);
3690+
if (type.IsNumeric(TypeCategory::Integer)) {
3691+
return true;
3692+
}
36553693
} else if (realName == "max" || realName == "min") {
36563694
// MAX: arguments must be integer, real, or character:
36573695
// F2023 16.9.135
36583696
// MIN: arguments must be integer, real, or character:
36593697
// F2023 16.9.141
3660-
return type.IsNumeric(TypeCategory::Integer) ||
3661-
type.IsNumeric(TypeCategory::Real) || isCharacter(type);
3698+
if (type.IsNumeric(TypeCategory::Integer) ||
3699+
type.IsNumeric(TypeCategory::Real) || isCharacter(type)) {
3700+
return true;
3701+
}
36623702
}
3703+
3704+
// If we get here, it may be a user declared reduction, so check
3705+
// if the symbol has UserReductionDetails, and if so, the type is
3706+
// supported.
3707+
if (const auto *reductionDetails{
3708+
name->symbol->detailsIf<UserReductionDetails>()}) {
3709+
return reductionDetails->SupportsType(type);
3710+
}
3711+
3712+
// We also need to check for mangled names (max, min, iand, ieor and ior)
3713+
// and then check if the type is there.
3714+
parser::CharBlock mangledName{MangleSpecialFunctions(name->source)};
3715+
return CheckSymbolSupportsType(scope, mangledName, type);
36633716
}
3664-
// TODO: user defined reduction operators. Just allow everything for now.
3665-
return true;
3717+
// Everything else is "not matching type".
3718+
return false;
36663719
}};
36673720

36683721
return common::visit(
@@ -3677,7 +3730,8 @@ void OmpStructureChecker::CheckReductionObjectTypes(
36773730

36783731
for (auto &[symbol, source] : symbols) {
36793732
if (auto *type{symbol->GetType()}) {
3680-
if (!IsReductionAllowedForType(ident, *type)) {
3733+
const auto &scope{context_.FindScope(symbol->name())};
3734+
if (!IsReductionAllowedForType(ident, *type, scope, context_)) {
36813735
context_.Say(source,
36823736
"The type of '%s' is incompatible with the reduction operator."_err_en_US,
36833737
symbol->name());

flang/lib/Semantics/mod-file.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,7 @@ void ModFileWriter::PutEntity(llvm::raw_ostream &os, const Symbol &symbol) {
894894
[&](const ObjectEntityDetails &) { PutObjectEntity(os, symbol); },
895895
[&](const ProcEntityDetails &) { PutProcEntity(os, symbol); },
896896
[&](const TypeParamDetails &) { PutTypeParam(os, symbol); },
897+
[&](const UserReductionDetails &) { PutUserReduction(os, symbol); },
897898
[&](const auto &) {
898899
common::die("PutEntity: unexpected details: %s",
899900
DetailsToString(symbol.details()).c_str());
@@ -1043,6 +1044,28 @@ void ModFileWriter::PutTypeParam(llvm::raw_ostream &os, const Symbol &symbol) {
10431044
os << '\n';
10441045
}
10451046

1047+
void ModFileWriter::PutUserReduction(
1048+
llvm::raw_ostream &os, const Symbol &symbol) {
1049+
const auto &details{symbol.get<UserReductionDetails>()};
1050+
// The module content for a OpenMP Declare Reduction is the OpenMP
1051+
// declaration. There may be multiple declarations.
1052+
// Decls are pointers, so do not use a reference.
1053+
for (const auto decl : details.GetDeclList()) {
1054+
common::visit( //
1055+
common::visitors{//
1056+
[&](const parser::OpenMPDeclareReductionConstruct *d) {
1057+
Unparse(os, *d, context_.langOptions());
1058+
},
1059+
[&](const parser::OmpMetadirectiveDirective *m) {
1060+
Unparse(os, *m, context_.langOptions());
1061+
},
1062+
[&](const auto &) {
1063+
DIE("Unknown OpenMP DECLARE REDUCTION content");
1064+
}},
1065+
decl);
1066+
}
1067+
}
1068+
10461069
void PutInit(llvm::raw_ostream &os, const Symbol &symbol, const MaybeExpr &init,
10471070
const parser::Expr *unanalyzed, SemanticsContext &context) {
10481071
if (IsNamedConstant(symbol) || symbol.owner().IsDerivedType()) {

flang/lib/Semantics/mod-file.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class ModFileWriter {
8080
void PutDerivedType(const Symbol &, const Scope * = nullptr);
8181
void PutDECStructure(const Symbol &, const Scope * = nullptr);
8282
void PutTypeParam(llvm::raw_ostream &, const Symbol &);
83+
void PutUserReduction(llvm::raw_ostream &, const Symbol &);
8384
void PutSubprogram(const Symbol &);
8485
void PutGeneric(const Symbol &);
8586
void PutUse(const Symbol &);

flang/lib/Semantics/resolve-names-utils.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,5 +146,11 @@ struct SymbolAndTypeMappings;
146146
void MapSubprogramToNewSymbols(const Symbol &oldSymbol, Symbol &newSymbol,
147147
Scope &newScope, SymbolAndTypeMappings * = nullptr);
148148

149+
parser::CharBlock MakeNameFromOperator(
150+
const parser::DefinedOperator::IntrinsicOperator &op,
151+
SemanticsContext &context);
152+
parser::CharBlock MangleSpecialFunctions(const parser::CharBlock &name);
153+
std::string MangleDefinedOperator(const parser::CharBlock &name);
154+
149155
} // namespace Fortran::semantics
150156
#endif // FORTRAN_SEMANTICS_RESOLVE_NAMES_H_

0 commit comments

Comments
 (0)