brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.9 KiB · f191b4d Raw
705 lines · cpp
1//===-- flang/lib/Semantics/openmp-modifiers.cpp --------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "flang/Semantics/openmp-modifiers.h"10 11#include "flang/Parser/parse-tree.h"12#include "llvm/ADT/ArrayRef.h"13#include "llvm/Frontend/OpenMP/OMP.h"14 15#include <algorithm>16#include <cassert>17#include <map>18 19namespace Fortran::semantics {20using namespace llvm::omp;21 22/// Find the highest version that exists as a key in the given map,23/// and is less than or equal to `version`.24/// Account for "version" not being a value from getOpenMPVersions().25template <typename ValueTy>26static unsigned findVersion(27    unsigned version, const std::map<unsigned, ValueTy> &map) {28  llvm::ArrayRef<unsigned> versions{llvm::omp::getOpenMPVersions()};29  assert(!versions.empty() && "getOpenMPVersions returned empty list");30  version = std::clamp(version, versions.front(), versions.back());31 32  // std::map is sorted with respect to keys, by default in the ascending33  // order.34  unsigned found{0};35  for (auto &[v, _] : map) {36    if (v <= version) {37      found = v;38    } else {39      break;40    }41  }42 43  // It can happen that the above search will not find any version, for44  // example when the minimum version in the map is higher than the current45  // version. This is really an error, but this situation should be handled46  // gracefully, so make some sensible choice and return it.47  if (found == 0) {48    found = !map.empty() ? map.begin()->first : versions.front();49  }50  return found;51}52 53const OmpProperties &OmpModifierDescriptor::props(unsigned version) const {54  return props_.at(findVersion(version, props_));55}56 57const OmpClauses &OmpModifierDescriptor::clauses(unsigned version) const {58  return clauses_.at(findVersion(version, clauses_));59}60 61unsigned OmpModifierDescriptor::since(llvm::omp::Clause id) const {62  unsigned found{[&]() {63    for (auto &[v, cs] : clauses_) {64      if (cs.test(id)) {65        return v;66      }67    }68    return ~0u;69  }()};70 71  return found <= 45 ? 0 : found;72}73 74// Note: The intent for these functions is to have them be automatically-75// generated in the future.76 77template <>78const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpAccessGroup>() {79  static const OmpModifierDescriptor desc{80      /*name=*/"access-group",81      /*props=*/82      {83          {61, {OmpProperty::Unique}},84      },85      /*clauses=*/86      {87          {61, {Clause::OMPC_dyn_groupprivate}},88      },89  };90  return desc;91}92 93template <>94const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpAlignment>() {95  static const OmpModifierDescriptor desc{96      /*name=*/"alignment",97      /*props=*/98      {99          {45, {OmpProperty::Unique, OmpProperty::Ultimate, OmpProperty::Post}},100      },101      /*clauses=*/102      {103          {45, {Clause::OMPC_aligned}},104      },105  };106  return desc;107}108 109template <>110const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpAlignModifier>() {111  static const OmpModifierDescriptor desc{112      /*name=*/"align-modifier",113      /*props=*/114      {115          {51, {OmpProperty::Unique}},116      },117      /*clauses=*/118      {119          {51, {Clause::OMPC_allocate}},120      },121  };122  return desc;123}124 125template <>126const OmpModifierDescriptor &127OmpGetDescriptor<parser::OmpAllocatorComplexModifier>() {128  static const OmpModifierDescriptor desc{129      /*name=*/"allocator-complex-modifier",130      /*props=*/131      {132          {51, {OmpProperty::Unique}},133      },134      /*clauses=*/135      {136          {51, {Clause::OMPC_allocate}},137      },138  };139  return desc;140}141 142template <>143const OmpModifierDescriptor &144OmpGetDescriptor<parser::OmpAllocatorSimpleModifier>() {145  static const OmpModifierDescriptor desc{146      /*name=*/"allocator-simple-modifier",147      /*props=*/148      {149          {50, {OmpProperty::Exclusive, OmpProperty::Unique}},150      },151      /*clauses=*/152      {153          {50, {Clause::OMPC_allocate}},154      },155  };156  return desc;157}158 159template <>160const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpAlwaysModifier>() {161  static const OmpModifierDescriptor desc{162      /*name=*/"always-modifier",163      /*props=*/164      {165          {45, {OmpProperty::Unique}},166      },167      /*clauses=*/168      {169          {45, {Clause::OMPC_map}},170      },171  };172  return desc;173}174 175template <>176const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpAttachModifier>() {177  static const OmpModifierDescriptor desc{178      /*name=*/"attach-modifier",179      /*props=*/180      {181          {61, {OmpProperty::Unique}},182      },183      /*clauses=*/184      {185          {61, {Clause::OMPC_map}},186      },187  };188  return desc;189}190 191template <>192const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpAutomapModifier>() {193  static const OmpModifierDescriptor desc{194      /*name=*/"automap-modifier",195      /*props=*/196      {197          {60, {OmpProperty::Unique}},198      },199      /*clauses=*/200      {201          {60, {Clause::OMPC_enter}},202      },203  };204  return desc;205}206 207template <>208const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpChunkModifier>() {209  static const OmpModifierDescriptor desc{210      /*name=*/"chunk-modifier",211      /*props=*/212      {213          {45, {OmpProperty::Unique}},214      },215      /*clauses=*/216      {217          {45, {Clause::OMPC_schedule}},218      },219  };220  return desc;221}222 223template <>224const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpCloseModifier>() {225  static const OmpModifierDescriptor desc{226      /*name=*/"close-modifier",227      /*props=*/228      {229          {50, {OmpProperty::Unique}},230      },231      /*clauses=*/232      {233          {50, {Clause::OMPC_map}},234      },235  };236  return desc;237}238 239template <>240const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpContextSelector>() {241  static const OmpModifierDescriptor desc{242      /*name=*/"context-selector",243      /*props=*/244      {245          {50, {OmpProperty::Required, OmpProperty::Unique}},246      },247      /*clauses=*/248      {249          // The MATCH clause takes a selector as an argument, not modifier.250          {50, {Clause::OMPC_when}},251      },252  };253  return desc;254}255 256template <>257const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpDeleteModifier>() {258  static const OmpModifierDescriptor desc{259      /*name=*/"delete-modifier",260      /*props=*/261      {262          {45, {OmpProperty::Unique, OmpProperty::Ultimate}},263          {60, {OmpProperty::Unique}},264      },265      /*clauses=*/266      {267          {45, {Clause::OMPC_map}},268      },269  };270  return desc;271}272 273template <>274const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpDependenceType>() {275  static const OmpModifierDescriptor desc{276      /*name=*/"dependence-type",277      /*props=*/278      {279          {45, {OmpProperty::Required, OmpProperty::Ultimate}},280      },281      /*clauses=*/282      {283          {45, {Clause::OMPC_depend}},284          {51, {Clause::OMPC_depend, Clause::OMPC_update}},285          {52, {Clause::OMPC_doacross}},286      },287  };288  return desc;289}290 291template <>292const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpDeviceModifier>() {293  static const OmpModifierDescriptor desc{294      /*name=*/"device-modifier",295      /*props=*/296      {297          {45, {OmpProperty::Unique}},298      },299      /*clauses=*/300      {301          {45, {Clause::OMPC_device}},302      },303  };304  return desc;305}306 307template <>308const OmpModifierDescriptor &309OmpGetDescriptor<parser::OmpDirectiveNameModifier>() {310  static const OmpModifierDescriptor desc{311      /*name=*/"directive-name-modifier",312      /*props=*/313      {314          {45, {OmpProperty::Unique}},315      },316      /*clauses=*/317      {318          {45, {Clause::OMPC_if}},319      },320  };321  return desc;322}323 324template <>325const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpExpectation>() {326  static const OmpModifierDescriptor desc{327      /*name=*/"expectation",328      /*props=*/329      {330          {51, {OmpProperty::Unique}},331      },332      /*clauses=*/333      {334          {51, {Clause::OMPC_from, Clause::OMPC_to}},335      },336  };337  return desc;338}339 340template <>341const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpFallbackModifier>() {342  static const OmpModifierDescriptor desc{343      /*name=*/"fallback-modifier",344      /*props=*/345      {346          {61, {OmpProperty::Unique}},347      },348      /*clauses=*/349      {350          {61, {Clause::OMPC_dyn_groupprivate}},351      },352  };353  return desc;354}355 356template <>357const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpInteropPreference>() {358  static const OmpModifierDescriptor desc{359      /*name=*/"interop-preference",360      /*props=*/361      {362          {52, {OmpProperty::Unique}},363      },364      /*clauses=*/365      {366          {52, {Clause::OMPC_init}},367      },368  };369  return desc;370}371 372template <>373const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpInteropType>() {374  static const OmpModifierDescriptor desc{375      /*name=*/"interop-type",376      /*props=*/377      {378          {52, {OmpProperty::Required}},379      },380      /*clauses=*/381      {382          {52, {Clause::OMPC_init}},383      },384  };385  return desc;386}387 388template <>389const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpIterator>() {390  static const OmpModifierDescriptor desc{391      /*name=*/"iterator",392      /*props=*/393      {394          {50, {OmpProperty::Unique}},395      },396      /*clauses=*/397      {398          {50, {Clause::OMPC_affinity, Clause::OMPC_depend}},399          {51,400              {Clause::OMPC_affinity, Clause::OMPC_depend, Clause::OMPC_from,401                  Clause::OMPC_map, Clause::OMPC_to}},402      },403  };404  return desc;405}406 407template <>408const OmpModifierDescriptor &409OmpGetDescriptor<parser::OmpLastprivateModifier>() {410  static const OmpModifierDescriptor desc{411      /*name=*/"lastprivate-modifier",412      /*props=*/413      {414          {50, {OmpProperty::Unique}},415      },416      /*clauses=*/417      {418          {50, {Clause::OMPC_lastprivate}},419      },420  };421  return desc;422}423 424template <>425const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpLinearModifier>() {426  static const OmpModifierDescriptor desc{427      /*name=*/"linear-modifier",428      /*props=*/429      {430          {45, {OmpProperty::Unique}},431      },432      /*clauses=*/433      {434          {45, {Clause::OMPC_linear}},435      },436  };437  return desc;438}439 440template <> //441const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpMapper>() {442  static const OmpModifierDescriptor desc{443      /*name=*/"mapper",444      /*props=*/445      {446          {50, {OmpProperty::Unique}},447      },448      /*clauses=*/449      {450          {50, {Clause::OMPC_from, Clause::OMPC_map, Clause::OMPC_to}},451      },452  };453  return desc;454}455 456template <>457const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpMapType>() {458  static const OmpModifierDescriptor desc{459      /*name=*/"map-type",460      /*props=*/461      {462          {45, {OmpProperty::Ultimate}},463          {60, {OmpProperty::Unique}},464      },465      /*clauses=*/466      {467          {45, {Clause::OMPC_map}},468      },469  };470  return desc;471}472 473template <>474const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpMapTypeModifier>() {475  static const OmpModifierDescriptor desc{476      /*name=*/"map-type-modifier",477      /*props=*/478      {479          {45, {}}, // Repeatable480      },481      /*clauses=*/482      {483          {45, {Clause::OMPC_map}},484          {60, {}},485      },486  };487  return desc;488}489 490template <>491const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpOrderModifier>() {492  static const OmpModifierDescriptor desc{493      /*name=*/"order-modifier",494      /*props=*/495      {496          {51, {OmpProperty::Unique}},497      },498      /*clauses=*/499      {500          {51, {Clause::OMPC_order}},501      },502  };503  return desc;504}505 506template <>507const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpOrderingModifier>() {508  static const OmpModifierDescriptor desc{509      /*name=*/"ordering-modifier",510      /*props=*/511      {512          {45, {OmpProperty::Unique}},513      },514      /*clauses=*/515      {516          {45, {Clause::OMPC_schedule}},517      },518  };519  return desc;520}521 522template <>523const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpPrescriptiveness>() {524  static const OmpModifierDescriptor desc{525      /*name=*/"prescriptiveness",526      /*props=*/527      {528          {51, {OmpProperty::Unique}},529      },530      /*clauses=*/531      {532          {51, {Clause::OMPC_grainsize, Clause::OMPC_num_tasks}},533      },534  };535  return desc;536}537 538template <>539const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpPresentModifier>() {540  static const OmpModifierDescriptor desc{541      /*name=*/"present-modifier",542      /*props=*/543      {544          {51, {OmpProperty::Unique}},545      },546      /*clauses=*/547      {548          {51, {Clause::OMPC_map}},549      },550  };551  return desc;552}553 554template <>555const OmpModifierDescriptor &556OmpGetDescriptor<parser::OmpReductionIdentifier>() {557  static const OmpModifierDescriptor desc{558      /*name=*/"reduction-identifier",559      /*props=*/560      {561          {45, {OmpProperty::Required, OmpProperty::Ultimate}},562      },563      /*clauses=*/564      {565          {45, {Clause::OMPC_reduction}},566          {50,567              {Clause::OMPC_in_reduction, Clause::OMPC_reduction,568                  Clause::OMPC_task_reduction}},569      },570  };571  return desc;572}573 574template <>575const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpReductionModifier>() {576  static const OmpModifierDescriptor desc{577      /*name=*/"reduction-modifier",578      /*props=*/579      {580          {45, {OmpProperty::Unique}},581      },582      /*clauses=*/583      {584          {45, {Clause::OMPC_reduction}},585      },586  };587  return desc;588}589 590template <>591const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpRefModifier>() {592  static const OmpModifierDescriptor desc{593      /*name=*/"ref-modifier",594      /*props=*/595      {596          {60, {OmpProperty::Unique}},597      },598      /*clauses=*/599      {600          {60, {Clause::OMPC_map}},601      },602  };603  return desc;604}605 606template <>607const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpSelfModifier>() {608  static const OmpModifierDescriptor desc{609      /*name=*/"self-modifier",610      /*props=*/611      {612          {60, {OmpProperty::Unique}},613      },614      /*clauses=*/615      {616          {60, {Clause::OMPC_map}},617      },618  };619  return desc;620}621 622template <>623const OmpModifierDescriptor &624OmpGetDescriptor<parser::OmpStepComplexModifier>() {625  static const OmpModifierDescriptor desc{626      /*name=*/"step-complex-modifier",627      /*props=*/628      {629          {52, {OmpProperty::Unique}},630      },631      /*clauses=*/632      {633          {52, {Clause::OMPC_linear}},634      },635  };636  return desc;637}638 639template <>640const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpStepSimpleModifier>() {641  static const OmpModifierDescriptor desc{642      /*name=*/"step-simple-modifier",643      /*props=*/644      {645          {45, {OmpProperty::Unique, OmpProperty::Exclusive}},646      },647      /*clauses=*/648      {649          {45, {Clause::OMPC_linear}},650      },651  };652  return desc;653}654 655template <>656const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpTaskDependenceType>() {657  static const OmpModifierDescriptor desc{658      /*name=*/"task-dependence-type",659      /*props=*/660      {661          {45, {OmpProperty::Required, OmpProperty::Ultimate}},662      },663      /*clauses=*/664      {665          {45, {Clause::OMPC_depend}},666          {51, {Clause::OMPC_depend, Clause::OMPC_update}},667      },668  };669  return desc;670}671 672template <>673const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpVariableCategory>() {674  static const OmpModifierDescriptor desc{675      /*name=*/"variable-category",676      /*props=*/677      {678          {45, {OmpProperty::Required, OmpProperty::Unique}},679          {50, {OmpProperty::Unique}},680      },681      /*clauses=*/682      {683          {45, {Clause::OMPC_defaultmap}},684      },685  };686  return desc;687}688 689template <>690const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpxHoldModifier>() {691  static const OmpModifierDescriptor desc{692      /*name=*/"ompx-hold-modifier",693      /*props=*/694      {695          {45, {OmpProperty::Unique}},696      },697      /*clauses=*/698      {699          {45, {Clause::OMPC_map}},700      },701  };702  return desc;703}704} // namespace Fortran::semantics705