Skip to content
This repository has been archived by the owner on Jan 20, 2024. It is now read-only.

Commit

Permalink
Minor quick and lazy update (code that'll be deprecated by rebase on …
Browse files Browse the repository at this point in the history
…IFA PR) to support target loops

Handling of implicits for target parallel do/parallel distribtue do, to test a larger subset of milestone 3a/3b.

This will be deprecated in favour of IFA so not a lot of
effort put into removing
obvious code duplication.
  • Loading branch information
agozillon committed Nov 9, 2023
1 parent 27808fb commit 2e2676f
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 0 deletions.
7 changes: 7 additions & 0 deletions flang/include/flang/Lower/OpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace Fortran {
namespace parser {
struct OpenMPConstruct;
struct OpenMPBlockConstruct;
struct OpenMPLoopConstruct;
struct OpenMPDeclarativeConstruct;
struct OmpEndLoopDirective;
struct OmpClauseList;
Expand Down Expand Up @@ -67,6 +68,12 @@ void genImplicitMapsForTarget(
Fortran::lower::pft::Evaluation &eval,
const Fortran::parser::OpenMPBlockConstruct &ompBlock);

void genImplicitMapsForTarget(
Fortran::lower::AbstractConverter &converter,
Fortran::semantics::SemanticsContext &semanticsContext,
Fortran::lower::pft::Evaluation &eval,
const Fortran::parser::OpenMPLoopConstruct &ompLoop);

mlir::Operation *findReductionChain(mlir::Value, mlir::Value * = nullptr);
fir::ConvertOp getConvertFromReductionOp(mlir::Operation *, mlir::Value);
void updateReduction(mlir::Operation *, fir::FirOpBuilder &, mlir::Value,
Expand Down
5 changes: 5 additions & 0 deletions flang/lib/Lower/Bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2432,6 +2432,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
*ompBlock);
}

if (ompLoop) {
genImplicitMapsForTarget(*this, bridge.getSemanticsContext(), *curEval,
*ompLoop);
}

localSymbols.popScope();
builder->restoreInsertionPoint(insertPt);

Expand Down
165 changes: 165 additions & 0 deletions flang/lib/Lower/OpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2590,6 +2590,171 @@ genEnterExitDataOp(Fortran::lower::AbstractConverter &converter,
deviceOperand, nowaitAttr, mapOperands);
}

void Fortran::lower::genImplicitMapsForTarget(
Fortran::lower::AbstractConverter &converter,
Fortran::semantics::SemanticsContext &semanticsContext,
Fortran::lower::pft::Evaluation &eval,
const Fortran::parser::OpenMPLoopConstruct &ompLoop) {
llvm::SmallVector<std::pair<const Fortran::semantics::Symbol *, mlir::Value>>
targetSyms;

auto printList = [&](const Fortran::semantics::Symbol &sym) {
for (auto syms : targetSyms)
if (*std::get<0>(syms) == sym)
return;
// skip these, declare target should be handled elsewhere via a provided
// explicit map and functions and subroutines are not symbols that are
// required to be mapped
if (sym.test(Fortran::semantics::Symbol::Flag::Function) ||
sym.test(Fortran::semantics::Symbol::Flag::Subroutine) ||
sym.test(Fortran::semantics::Symbol::Flag::OmpDeclareTarget))
return;

targetSyms.push_back(
std::pair<const Fortran::semantics::Symbol *, mlir::Value>(
&sym, converter.getSymbolAddress(sym)));
};

Fortran::lower::pft::visitAllSymbols(eval, printList);

auto isScalarType = [&](mlir::Type type) {
if (type.isa<fir::ReferenceType>())
type = type.cast<fir::ReferenceType>().getEleTy();

if (type.isa<fir::IntegerType>() || type.isa<fir::CharacterType>() ||
type.isa<fir::LogicalType>() || type.isa<fir::ComplexType>() ||
type.isa<fir::RealType>() || type.isa<mlir::IntegerType>() ||
type.isa<mlir::FloatType>())
return true;
return false;
};

const auto &beginLoopDirective =
std::get<Fortran::parser::OmpBeginLoopDirective>(ompLoop.t);
const auto &directive =
std::get<Fortran::parser::OmpLoopDirective>(beginLoopDirective.t);
fir::FirOpBuilder builder = converter.getFirOpBuilder();

if (llvm::omp::Directive::OMPD_target_parallel_do == directive.v
|| llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do == directive.v) {
if (auto tarOp = mlir::dyn_cast<mlir::omp::TargetOp>(
builder.getInsertionPoint()->getParentOfType<mlir::omp::TargetOp>())) {
// NOTE: It is possible to use Fortran::lower::pft::visitAllSymbols,
// here to access individual symbolic/semantic information for each
// implicit map operand where neccessary (need to retrieve the
// symbol name from the op to find the matching semantic symbol)
llvm::SetVector<mlir::Value> operandSet;
mlir::getUsedValuesDefinedAbove(tarOp.getRegion(), operandSet);

// filter out uses already being mapped (explicit maps)
bool removed = false;
for (llvm::SetVector<mlir::Value>::iterator iter = operandSet.begin();
iter != operandSet.end();) {
for (auto mapValue : tarOp.getMapOperands()) {
if (auto mapOp = mlir::dyn_cast_if_present<mlir::omp::MapInfoOp>(
mapValue.getDefiningOp())) {
mlir::Value underlyingValue = mapOp.getVarPtr();

// If we have a box, we have some value chasing to do, as the
// original symbol/used value is hidden by the box which
// contains more information on the underlying operation.
if (auto boxAddr = mlir::dyn_cast_if_present<fir::BoxAddrOp>(
mapOp.getVarPtr().getDefiningOp())) {
if (auto load = mlir::dyn_cast_if_present<fir::LoadOp>(
boxAddr.getVal().getDefiningOp())) {
underlyingValue = load.getMemref();
}
}

if (underlyingValue == *iter) {
iter = operandSet.erase(iter);
removed = true;
break;
}
}
}
if (!removed)
iter++;
else
removed = false;
}

builder.setInsertionPoint(tarOp);

llvm::SmallVector<mlir::Value> impMapOps;
for (auto value : operandSet) {
llvm::omp::OpenMPOffloadMappingFlags mapTypeBits =
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE;

const Fortran::semantics::Symbol *sym = nullptr;
for (auto &tarSym : targetSyms) {
if (std::get<1>(tarSym) == value) {
sym = std::get<0>(tarSym);
}
}

bool isScalar = isScalarType(value.getType());

// Default implicit map cases, only handle two for the moment
if (isScalar) {
mapTypeBits =
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TARGET_PARAM |
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_LITERAL |
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT;
} else { // non-scalar values
mapTypeBits |=
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT |
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO |
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM |
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TARGET_PARAM;
}

mlir::Value baseAddr;
llvm::SmallVector<mlir::Value> bounds;
if (sym) {
baseAddr = getDataOperandBaseAddr(converter, builder, *sym,
converter.getCurrentLocation());
if (fir::unwrapRefType(baseAddr.getType()).isa<fir::BaseBoxType>())
bounds = genBoundsOpsFromBox<mlir::omp::DataBoundsOp,
mlir::omp::DataBoundsType>(
builder, converter.getCurrentLocation(), converter,
converter.getSymbolExtendedValue(*sym), baseAddr);
if (fir::unwrapRefType(baseAddr.getType()).isa<fir::SequenceType>())
bounds = genBaseBoundsOps<mlir::omp::DataBoundsOp,
mlir::omp::DataBoundsType>(
builder, converter.getCurrentLocation(), converter,
converter.getSymbolExtendedValue(*sym), baseAddr);
}
uint64_t mapType = static_cast<
std::underlying_type_t<llvm::omp::OpenMPOffloadMappingFlags>>(
mapTypeBits);

// compare implicit mapped vs explicit mapped bounds out
if (sym && Fortran::semantics::IsAllocatableOrPointer(*sym)) {
mlir::Value descriptor = converter.getSymbolAddress(*sym);
impMapOps.push_back(createMapInfoOp(
builder, tarOp->getLoc(), descriptor, nullptr,
sym->name().ToString(), mlir::SmallVector<mlir::Value>{},
static_cast<
std::underlying_type_t<llvm::omp::OpenMPOffloadMappingFlags>>(
mapTypeBits),
mlir::omp::VariableCaptureKind::ByRef, true,
descriptor.getType()));
} else {
impMapOps.push_back(createMapInfoOp(
builder, tarOp->getLoc(), baseAddr ? baseAddr : value, nullptr,
sym ? sym->name().ToString() : "", bounds, mapType,
isScalar ? mlir::omp::VariableCaptureKind::ByCopy
: mlir::omp::VariableCaptureKind::ByRef,
false, value.getType()));
}
}

tarOp.getMapOperandsMutable().append(impMapOps);
}
}
}

void Fortran::lower::genImplicitMapsForTarget(
Fortran::lower::AbstractConverter &converter,
Fortran::semantics::SemanticsContext &semanticsContext,
Expand Down

0 comments on commit 2e2676f

Please sign in to comment.