[flang-dev] Intrinsic function with an optional TEAM_TYPE dummy argument

Jean Perier via flang-dev flang-dev at lists.llvm.org
Thu May 6 05:09:21 PDT 2021


Hi Craig,

I think you may be the first having to deal with optional derived type arguments in intrinsic functions. First, I would like to clarify where you are having an issue with IntrinsicTypeDefaultKinds::GetDefaultKind being called with a derived type category after your first three changes.
By "TypeAndShape constructor calls GetDefaultKind()", you mean that GetDefaultKind is called in the arguments of a TypeAndShape constructor, not inside the TypeAndShape constructor function itself right ?

Is this at: https://github.com/llvm/llvm-project/blob/d8805574c183484f055552855fa82d2e8932415e/flang/lib/Evaluate/intrinsics.cpp#L1666 ?

} else {
      // optional argument is absent
      CHECK(d.optionality != Optionality::required);
      if (d.typePattern.kindCode == KindCode::same) {
        dummyArgs.emplace_back(dummyArgs[sameDummyArg.value()]);
      } else {
        auto category{d.typePattern.categorySet.LeastElement().value()};
        characteristics::TypeAndShape typeAndShape{
            DynamicType{category, defaults.GetDefaultKind(category)}};
        dummyArgs.emplace_back(std::string{d.keyword},
            characteristics::DummyDataObject{std::move(typeAndShape)});

Looking at the code you propose, the overall idea looks good to me, the issue is that DynamicType cannot be created from the simply the TypeCategory for derived type. A semantics::DerivedTypeSpec that precisely described the derived type specification of a derived type entity needs to be provided (DynamicType must be different for objects of different derived types, there cannot be a single DynamicType for all derived types).

So going that way, I think you would need a semantics::DerivedTypeSpec for the team type. I am not sure there currently is a way to generate such DerivedTypeSpec without a user object (which I think would be your case, since there is no actual argument to get the type from). That is because TEAM_TYPE, like all derived types defined by the standard, are defined by means of Fortran source files (see module/iso_fortran_env.f90 and module/__fortran_builtins.f90), so the compiler has no knowledge of what these derived types actually are without access to these source/module files (For user objects, these module files are made accessible by the user via use statements to iso_fortran_env).

Jean

From: flang-dev <flang-dev-bounces at lists.llvm.org> On Behalf Of Rasmussen, Craig E. via flang-dev
Sent: Monday, May 3, 2021 10:39 PM
To: flang-dev at lists.llvm.org
Subject: [flang-dev] Intrinsic function with an optional TEAM_TYPE dummy argument

External email: Use caution opening links or attachments

I'm trying to implement team_number(team) in lib/Evaluate/intrinsics.cpp and I'm running into a problem.  The issue is how to handle team_type from the intrinsic module iso_fortran_env.  I'll outline the steps I've taken so far and then describe the problem I'm having.

I've:
  1. Changed the CategorySet in TypePattern TEAM_TYPE from IntType to DerivedType. I'm pretty sure this is the correct thing to do.
  2. Added team_number to the IntrinsicInterface list with an optional TEAM_TYPE. Again, no problem here.
  3. Implemented checking types and kinds of the actual argument against the team_number's interface. This is pretty straight forward:
         case KindCode::teamType:
           argOk = semantics::IsTeamType(GetDerivedTypeSpec(type));

The problem occurs when the code tries to check the dummy argument (team) for the case in which the optional actual argument is missing. The normal control flow path that this would take would be to move a characteristics::DummyDataObject (constructed with characteristics::TypeAndShape) onto the dummyArgs list. However, the TypeAndShape constructor calls GetDefaultKind() with a TEAM_TYPE category argument (which is TypeCategory::DerivedType).

Therein lies the problem. The function IntrinsicTypeDefaultKinds::GetDefaultKind(TypeCategory::DerivedType) fails with a hard error because a derived type is not an intrinsic type. At first I was thoroughly confused by the whole type kind thing for a derived type, specifically one from an intrinsic module. Then as a last (of course) resort, I checked the standard more carefully and found Note 16.34 which states that types in intrinsic modules are not themselves intrinsic. Thus IntrinsicTypeDefaultKinds::GetDefaultKind(TypeCategory::DerivedType) should fail.

So the conclusion is that I need help fixing this (for function team_type() and several other intrinsic functions with a dummy argument of TEAM_TYPE). The code could look something like the following (at roughly line 1670 in intrinsics.cpp):

      } else if (d.typePattern.kindCode == KindCode::teamType) {
        characteristics::TypeAndShape typeAndShape{DynamicType{TypeCategory::Derived}};
        dummyArgs.emplace_back(std::string{d.keyword},
            characteristics::DummyDataObject{std::move(typeAndShape)});
      }

However, there is no constructor for TypeAndShape with a single argument of type TypeCategory::Derived. After staring at many lines of code in flang I'm left wondering if there shouldn't be?

Thanks,
Craig

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/flang-dev/attachments/20210506/3c8c61f0/attachment.html>


More information about the flang-dev mailing list