CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
258 lines
9.4 KiB
C++
258 lines
9.4 KiB
C++
//===-- Lower/OpenMP/Utils.h ------------------------------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef FORTRAN_LOWER_OPENMPUTILS_H
|
|
#define FORTRAN_LOWER_OPENMPUTILS_H
|
|
|
|
#include "flang/Lower/OpenMP/Clauses.h"
|
|
#include "flang/Optimizer/Builder/HLFIRTools.h"
|
|
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
|
|
#include "mlir/IR/Location.h"
|
|
#include "mlir/IR/Value.h"
|
|
#include "llvm/Frontend/OpenMP/OMPContext.h"
|
|
#include "llvm/Support/CommandLine.h"
|
|
#include <cstdint>
|
|
#include <optional>
|
|
|
|
extern llvm::cl::opt<bool> treatIndexAsSection;
|
|
|
|
namespace fir {
|
|
class FirOpBuilder;
|
|
class RecordType;
|
|
} // namespace fir
|
|
namespace Fortran {
|
|
|
|
namespace semantics {
|
|
class Symbol;
|
|
} // namespace semantics
|
|
|
|
namespace parser {
|
|
struct OmpObject;
|
|
struct OmpObjectList;
|
|
} // namespace parser
|
|
|
|
namespace lower {
|
|
class StatementContext;
|
|
namespace pft {
|
|
struct Evaluation;
|
|
}
|
|
|
|
class AbstractConverter;
|
|
|
|
namespace omp {
|
|
|
|
struct DeclareTargetCaptureInfo {
|
|
mlir::omp::DeclareTargetCaptureClause clause;
|
|
bool automap = false;
|
|
const semantics::Symbol &symbol;
|
|
|
|
DeclareTargetCaptureInfo(mlir::omp::DeclareTargetCaptureClause c,
|
|
const semantics::Symbol &s, bool a = false)
|
|
: clause(c), automap(a), symbol(s) {}
|
|
};
|
|
|
|
// A small helper structure for keeping track of a component members MapInfoOp
|
|
// and index data when lowering OpenMP map clauses. Keeps track of the
|
|
// placement of the component in the derived type hierarchy it rests within,
|
|
// alongside the generated mlir::omp::MapInfoOp for the mapped component.
|
|
//
|
|
// As an example of what the contents of this data structure may be like,
|
|
// when provided the following derived type and map of that type:
|
|
//
|
|
// type :: bottom_layer
|
|
// real(8) :: i2
|
|
// real(4) :: array_i2(10)
|
|
// real(4) :: array_j2(10)
|
|
// end type bottom_layer
|
|
//
|
|
// type :: top_layer
|
|
// real(4) :: i
|
|
// integer(4) :: array_i(10)
|
|
// real(4) :: j
|
|
// type(bottom_layer) :: nested
|
|
// integer, allocatable :: array_j(:)
|
|
// integer(4) :: k
|
|
// end type top_layer
|
|
//
|
|
// type(top_layer) :: top_dtype
|
|
//
|
|
// map(tofrom: top_dtype%nested%i2, top_dtype%k, top_dtype%nested%array_i2)
|
|
//
|
|
// We would end up with an OmpMapParentAndMemberData populated like below:
|
|
//
|
|
// memberPlacementIndices:
|
|
// Vector 1: 3, 0
|
|
// Vector 2: 5
|
|
// Vector 3: 3, 1
|
|
//
|
|
// memberMap:
|
|
// Entry 1: omp.map.info for "top_dtype%nested%i2"
|
|
// Entry 2: omp.map.info for "top_dtype%k"
|
|
// Entry 3: omp.map.info for "top_dtype%nested%array_i2"
|
|
//
|
|
// And this OmpMapParentAndMemberData would be accessed via the parent
|
|
// symbol for top_dtype. Other parent derived type instances that have
|
|
// members mapped would have there own OmpMapParentAndMemberData entry
|
|
// accessed via their own symbol.
|
|
struct OmpMapParentAndMemberData {
|
|
// The indices representing the component members placement in its derived
|
|
// type parents hierarchy.
|
|
llvm::SmallVector<llvm::SmallVector<int64_t>> memberPlacementIndices;
|
|
|
|
// Placement of the member in the member vector.
|
|
llvm::SmallVector<mlir::omp::MapInfoOp> memberMap;
|
|
|
|
bool isDuplicateMemberMapInfo(llvm::SmallVectorImpl<int64_t> &memberIndices) {
|
|
return llvm::find_if(memberPlacementIndices, [&](auto &memberData) {
|
|
return llvm::equal(memberIndices, memberData);
|
|
}) != memberPlacementIndices.end();
|
|
}
|
|
|
|
void addChildIndexAndMapToParent(const omp::Object &object,
|
|
mlir::omp::MapInfoOp &mapOp,
|
|
semantics::SemanticsContext &semaCtx);
|
|
};
|
|
|
|
void insertChildMapInfoIntoParent(
|
|
Fortran::lower::AbstractConverter &converter,
|
|
Fortran::semantics::SemanticsContext &semaCtx,
|
|
Fortran::lower::StatementContext &stmtCtx,
|
|
std::map<Object, OmpMapParentAndMemberData> &parentMemberIndices,
|
|
llvm::SmallVectorImpl<mlir::Value> &mapOperands,
|
|
llvm::SmallVectorImpl<Object> &mapObjects);
|
|
|
|
void generateMemberPlacementIndices(
|
|
const Object &object, llvm::SmallVectorImpl<int64_t> &indices,
|
|
Fortran::semantics::SemanticsContext &semaCtx);
|
|
|
|
bool isMemberOrParentAllocatableOrPointer(
|
|
const Object &object, Fortran::semantics::SemanticsContext &semaCtx);
|
|
|
|
mlir::Value createParentSymAndGenIntermediateMaps(
|
|
mlir::Location clauseLocation, Fortran::lower::AbstractConverter &converter,
|
|
semantics::SemanticsContext &semaCtx, lower::StatementContext &stmtCtx,
|
|
omp::ObjectList &objectList, llvm::SmallVectorImpl<int64_t> &indices,
|
|
OmpMapParentAndMemberData &parentMemberIndices, llvm::StringRef asFortran,
|
|
mlir::omp::ClauseMapFlags mapTypeBits);
|
|
|
|
bool requiresImplicitDefaultDeclareMapper(
|
|
const semantics::DerivedTypeSpec &typeSpec);
|
|
|
|
omp::ObjectList gatherObjectsOf(omp::Object derivedTypeMember,
|
|
semantics::SemanticsContext &semaCtx);
|
|
|
|
mlir::Type getLoopVarType(lower::AbstractConverter &converter,
|
|
std::size_t loopVarTypeSize);
|
|
|
|
semantics::Symbol *
|
|
getIterationVariableSymbol(const lower::pft::Evaluation &eval);
|
|
|
|
void gatherFuncAndVarSyms(
|
|
const ObjectList &objects, mlir::omp::DeclareTargetCaptureClause clause,
|
|
llvm::SmallVectorImpl<DeclareTargetCaptureInfo> &symbolAndClause,
|
|
bool automap = false);
|
|
|
|
int64_t getCollapseValue(const List<Clause> &clauses);
|
|
|
|
void genObjectList(const ObjectList &objects,
|
|
lower::AbstractConverter &converter,
|
|
llvm::SmallVectorImpl<mlir::Value> &operands);
|
|
|
|
void lastprivateModifierNotSupported(const omp::clause::Lastprivate &lastp,
|
|
mlir::Location loc);
|
|
|
|
pft::Evaluation *getNestedDoConstruct(pft::Evaluation &eval);
|
|
|
|
int64_t collectLoopRelatedInfo(
|
|
lower::AbstractConverter &converter, mlir::Location currentLocation,
|
|
lower::pft::Evaluation &eval, lower::pft::Evaluation *nestedEval,
|
|
const omp::List<omp::Clause> &clauses,
|
|
mlir::omp::LoopRelatedClauseOps &result,
|
|
llvm::SmallVectorImpl<const semantics::Symbol *> &iv);
|
|
|
|
void collectLoopRelatedInfo(
|
|
lower::AbstractConverter &converter, mlir::Location currentLocation,
|
|
lower::pft::Evaluation &eval, lower::pft::Evaluation *nestedEval,
|
|
std::int64_t collapseValue,
|
|
// const omp::List<omp::Clause> &clauses,
|
|
mlir::omp::LoopRelatedClauseOps &result,
|
|
llvm::SmallVectorImpl<const semantics::Symbol *> &iv);
|
|
|
|
void collectTileSizesFromOpenMPConstruct(
|
|
const parser::OpenMPConstruct *ompCons,
|
|
llvm::SmallVectorImpl<int64_t> &tileSizes,
|
|
Fortran::semantics::SemanticsContext &semaCtx);
|
|
|
|
mlir::Value genElementSizeInBytes(fir::FirOpBuilder &builder,
|
|
mlir::Location loc,
|
|
const mlir::DataLayout &dl,
|
|
hlfir::Entity entity);
|
|
|
|
mlir::Value genAffinityAddr(Fortran::lower::AbstractConverter &converter,
|
|
const omp::Object &object,
|
|
Fortran::lower::StatementContext &stmtCtx,
|
|
mlir::Location loc);
|
|
|
|
mlir::Value genAffinityLen(fir::FirOpBuilder &builder, mlir::Location loc,
|
|
const mlir::DataLayout &dl, hlfir::Entity entity,
|
|
llvm::ArrayRef<mlir::Value> bounds);
|
|
|
|
struct IteratorRange {
|
|
mlir::Value lb;
|
|
mlir::Value ub;
|
|
mlir::Value step;
|
|
Fortran::semantics::Symbol *ivSym = nullptr;
|
|
};
|
|
|
|
bool hasIteratorIVReference(
|
|
const omp::Object &object,
|
|
const llvm::SmallPtrSetImpl<const Fortran::semantics::Symbol *> &ivSyms);
|
|
|
|
/// Default name mangler for implicit default mappers.
|
|
///
|
|
/// \param converter The converter to use for name mangling.
|
|
/// \param mapperIdName The name of the mapper to mangle.
|
|
/// \param memberName The name of the member to mangle.
|
|
void defaultMangler(Fortran::lower::AbstractConverter &converter,
|
|
std::string &mapperIdName, llvm::StringRef memberName);
|
|
|
|
mlir::Value genIteratorCoordinate(Fortran::lower::AbstractConverter &converter,
|
|
hlfir::Entity entity,
|
|
llvm::ArrayRef<mlir::Value> ivs,
|
|
mlir::Location loc);
|
|
|
|
std::optional<llvm::SmallVector<mlir::Value>> getIteratorElementIndices(
|
|
Fortran::lower::AbstractConverter &converter, const omp::Object &object,
|
|
Fortran::lower::StatementContext &stmtCtx, mlir::Location loc);
|
|
|
|
/// Map a parsed OpenMP context trait-set selector to its OMPContext kind.
|
|
llvm::omp::TraitSet
|
|
mapTraitSet(parser::OmpTraitSetSelectorName::Value flangSet);
|
|
|
|
/// Map a parsed OpenMP context trait selector within \p set to its OMPContext
|
|
/// kind.
|
|
llvm::omp::TraitSelector
|
|
mapTraitSelector(const parser::OmpTraitSelectorName &name,
|
|
llvm::omp::TraitSet set);
|
|
|
|
/// Populate \p vmi from a parsed OpenMP context selector. Constant user
|
|
/// conditions are folded into user_condition_true/false traits. A non-constant
|
|
/// user condition is recorded as user_condition_unknown and returned through
|
|
/// \p dynamicCondExpr for later lowering as a runtime condition.
|
|
void makeVariantMatchInfo(llvm::omp::VariantMatchInfo &vmi,
|
|
const parser::modifier::OmpContextSelector &ctxSel,
|
|
semantics::SemanticsContext &semaCtx,
|
|
mlir::Location loc,
|
|
const parser::ScalarExpr *&dynamicCondExpr);
|
|
|
|
} // namespace omp
|
|
} // namespace lower
|
|
} // namespace Fortran
|
|
|
|
#endif // FORTRAN_LOWER_OPENMPUTILS_H
|