2020-09-15 04:39:52 +08:00
|
|
|
//===-- OpenACC.cpp -- OpenACC directive lowering -------------------------===//
|
[flang][openacc] Skeleton for OpenACC construct lowering
Summary:
This patch introduce the basic infrastructure to be able to lower
OpenACC constructs to the future OpenACC dialect.
Reviewers: schweitz, kiranchandramohan, DavidTruby, sscalpone, jdoerfert, ichoyjx
Reviewed By: ichoyjx
Subscribers: ichoyjx, SouraVX, mgorny, jfb, sstefan1, llvm-commits
Tags: #llvm, #flang
Differential Revision: https://reviews.llvm.org/D84195
2020-07-23 09:32:57 +08:00
|
|
|
//
|
|
|
|
// 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
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2020-07-24 02:10:00 +08:00
|
|
|
//
|
|
|
|
// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
[flang][openacc] Skeleton for OpenACC construct lowering
Summary:
This patch introduce the basic infrastructure to be able to lower
OpenACC constructs to the future OpenACC dialect.
Reviewers: schweitz, kiranchandramohan, DavidTruby, sscalpone, jdoerfert, ichoyjx
Reviewed By: ichoyjx
Subscribers: ichoyjx, SouraVX, mgorny, jfb, sstefan1, llvm-commits
Tags: #llvm, #flang
Differential Revision: https://reviews.llvm.org/D84195
2020-07-23 09:32:57 +08:00
|
|
|
|
|
|
|
#include "flang/Lower/OpenACC.h"
|
2020-09-17 23:34:28 +08:00
|
|
|
#include "flang/Common/idioms.h"
|
[flang][openacc] Skeleton for OpenACC construct lowering
Summary:
This patch introduce the basic infrastructure to be able to lower
OpenACC constructs to the future OpenACC dialect.
Reviewers: schweitz, kiranchandramohan, DavidTruby, sscalpone, jdoerfert, ichoyjx
Reviewed By: ichoyjx
Subscribers: ichoyjx, SouraVX, mgorny, jfb, sstefan1, llvm-commits
Tags: #llvm, #flang
Differential Revision: https://reviews.llvm.org/D84195
2020-07-23 09:32:57 +08:00
|
|
|
#include "flang/Lower/Bridge.h"
|
|
|
|
#include "flang/Lower/FIRBuilder.h"
|
|
|
|
#include "flang/Lower/PFTBuilder.h"
|
|
|
|
#include "flang/Parser/parse-tree.h"
|
2020-09-17 23:34:28 +08:00
|
|
|
#include "flang/Semantics/tools.h"
|
|
|
|
#include "mlir/Dialect/OpenACC/OpenACC.h"
|
[flang][openacc] Skeleton for OpenACC construct lowering
Summary:
This patch introduce the basic infrastructure to be able to lower
OpenACC constructs to the future OpenACC dialect.
Reviewers: schweitz, kiranchandramohan, DavidTruby, sscalpone, jdoerfert, ichoyjx
Reviewed By: ichoyjx
Subscribers: ichoyjx, SouraVX, mgorny, jfb, sstefan1, llvm-commits
Tags: #llvm, #flang
Differential Revision: https://reviews.llvm.org/D84195
2020-07-23 09:32:57 +08:00
|
|
|
#include "llvm/Frontend/OpenACC/ACC.h.inc"
|
|
|
|
|
|
|
|
#define TODO() llvm_unreachable("not yet implemented")
|
|
|
|
|
2020-09-17 23:34:28 +08:00
|
|
|
static const Fortran::parser::Name *
|
|
|
|
getDesignatorNameIfDataRef(const Fortran::parser::Designator &designator) {
|
|
|
|
const auto *dataRef{std::get_if<Fortran::parser::DataRef>(&designator.u)};
|
|
|
|
return dataRef ? std::get_if<Fortran::parser::Name>(&dataRef->u) : nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void genObjectList(const Fortran::parser::AccObjectList &objectList,
|
|
|
|
Fortran::lower::AbstractConverter &converter,
|
|
|
|
std::int32_t &objectsCount,
|
|
|
|
SmallVector<Value, 8> &operands) {
|
|
|
|
for (const auto &accObject : objectList.v) {
|
|
|
|
std::visit(
|
|
|
|
Fortran::common::visitors{
|
|
|
|
[&](const Fortran::parser::Designator &designator) {
|
|
|
|
if (const auto *name = getDesignatorNameIfDataRef(designator)) {
|
|
|
|
++objectsCount;
|
|
|
|
const auto variable = converter.getSymbolAddress(*name->symbol);
|
|
|
|
operands.push_back(variable);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
[&](const Fortran::parser::Name &name) {
|
|
|
|
++objectsCount;
|
|
|
|
const auto variable = converter.getSymbolAddress(*name.symbol);
|
|
|
|
operands.push_back(variable);
|
|
|
|
}},
|
|
|
|
accObject.u);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void genACC(Fortran::lower::AbstractConverter &converter,
|
|
|
|
Fortran::lower::pft::Evaluation &eval,
|
|
|
|
const Fortran::parser::OpenACCLoopConstruct &loopConstruct) {
|
|
|
|
|
|
|
|
const auto &beginLoopDirective =
|
|
|
|
std::get<Fortran::parser::AccBeginLoopDirective>(loopConstruct.t);
|
|
|
|
const auto &loopDirective =
|
|
|
|
std::get<Fortran::parser::AccLoopDirective>(beginLoopDirective.t);
|
|
|
|
|
|
|
|
if (loopDirective.v == llvm::acc::ACCD_loop) {
|
|
|
|
auto &firOpBuilder = converter.getFirOpBuilder();
|
|
|
|
auto currentLocation = converter.getCurrentLocation();
|
|
|
|
llvm::ArrayRef<mlir::Type> argTy;
|
|
|
|
|
|
|
|
// Add attribute extracted from clauses.
|
|
|
|
const auto &accClauseList =
|
|
|
|
std::get<Fortran::parser::AccClauseList>(beginLoopDirective.t);
|
|
|
|
|
|
|
|
mlir::Value workerNum;
|
|
|
|
mlir::Value vectorLength;
|
|
|
|
mlir::Value gangNum;
|
|
|
|
mlir::Value gangStatic;
|
|
|
|
std::int32_t tileOperands = 0;
|
|
|
|
std::int32_t privateOperands = 0;
|
|
|
|
std::int32_t reductionOperands = 0;
|
|
|
|
std::int64_t executionMapping = mlir::acc::OpenACCExecMapping::NONE;
|
|
|
|
SmallVector<Value, 8> operands;
|
|
|
|
|
|
|
|
// Lower clauses values mapped to operands.
|
|
|
|
for (const auto &clause : accClauseList.v) {
|
|
|
|
if (const auto *gangClause =
|
|
|
|
std::get_if<Fortran::parser::AccClause::Gang>(&clause.u)) {
|
|
|
|
if (gangClause->v) {
|
|
|
|
const Fortran::parser::AccGangArgument &x = *gangClause->v;
|
|
|
|
if (const auto &gangNumValue =
|
|
|
|
std::get<std::optional<Fortran::parser::ScalarIntExpr>>(
|
|
|
|
x.t)) {
|
|
|
|
gangNum = converter.genExprValue(
|
|
|
|
*Fortran::semantics::GetExpr(gangNumValue.value()));
|
|
|
|
operands.push_back(gangNum);
|
|
|
|
}
|
|
|
|
if (const auto &gangStaticValue =
|
|
|
|
std::get<std::optional<Fortran::parser::AccSizeExpr>>(x.t)) {
|
|
|
|
const auto &expr =
|
|
|
|
std::get<std::optional<Fortran::parser::ScalarIntExpr>>(
|
|
|
|
gangStaticValue.value().t);
|
|
|
|
if (expr) {
|
|
|
|
gangStatic =
|
|
|
|
converter.genExprValue(*Fortran::semantics::GetExpr(*expr));
|
|
|
|
} else {
|
|
|
|
// * was passed as value and will be represented as a -1 constant
|
|
|
|
// integer.
|
|
|
|
gangStatic = firOpBuilder.createIntegerConstant(
|
|
|
|
currentLocation, firOpBuilder.getIntegerType(32),
|
|
|
|
/* STAR */ -1);
|
|
|
|
}
|
|
|
|
operands.push_back(gangStatic);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
executionMapping |= mlir::acc::OpenACCExecMapping::GANG;
|
|
|
|
} else if (const auto *workerClause =
|
|
|
|
std::get_if<Fortran::parser::AccClause::Worker>(
|
|
|
|
&clause.u)) {
|
|
|
|
if (workerClause->v) {
|
|
|
|
workerNum = converter.genExprValue(
|
|
|
|
*Fortran::semantics::GetExpr(*workerClause->v));
|
|
|
|
operands.push_back(workerNum);
|
|
|
|
}
|
|
|
|
executionMapping |= mlir::acc::OpenACCExecMapping::WORKER;
|
|
|
|
} else if (const auto *vectorClause =
|
|
|
|
std::get_if<Fortran::parser::AccClause::Vector>(
|
|
|
|
&clause.u)) {
|
|
|
|
if (vectorClause->v) {
|
|
|
|
vectorLength = converter.genExprValue(
|
|
|
|
*Fortran::semantics::GetExpr(*vectorClause->v));
|
|
|
|
operands.push_back(vectorLength);
|
|
|
|
}
|
|
|
|
executionMapping |= mlir::acc::OpenACCExecMapping::VECTOR;
|
|
|
|
} else if (const auto *tileClause =
|
|
|
|
std::get_if<Fortran::parser::AccClause::Tile>(&clause.u)) {
|
|
|
|
const Fortran::parser::AccTileExprList &accTileExprList = tileClause->v;
|
|
|
|
for (const auto &accTileExpr : accTileExprList.v) {
|
|
|
|
const auto &expr =
|
|
|
|
std::get<std::optional<Fortran::parser::ScalarIntConstantExpr>>(
|
|
|
|
accTileExpr.t);
|
|
|
|
++tileOperands;
|
|
|
|
if (expr) {
|
|
|
|
operands.push_back(
|
|
|
|
converter.genExprValue(*Fortran::semantics::GetExpr(*expr)));
|
|
|
|
} else {
|
|
|
|
// * was passed as value and will be represented as a -1 constant
|
|
|
|
// integer.
|
|
|
|
mlir::Value tileStar = firOpBuilder.createIntegerConstant(
|
|
|
|
currentLocation, firOpBuilder.getIntegerType(32),
|
|
|
|
/* STAR */ -1);
|
|
|
|
operands.push_back(tileStar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (const auto *privateClause =
|
|
|
|
std::get_if<Fortran::parser::AccClause::Private>(
|
|
|
|
&clause.u)) {
|
|
|
|
const Fortran::parser::AccObjectList &accObjectList = privateClause->v;
|
|
|
|
genObjectList(accObjectList, converter, privateOperands, operands);
|
|
|
|
}
|
|
|
|
// Reduction clause is left out for the moment as the clause will probably
|
|
|
|
// end up having its own operation.
|
|
|
|
}
|
|
|
|
|
|
|
|
auto loopOp = firOpBuilder.create<mlir::acc::LoopOp>(currentLocation, argTy,
|
|
|
|
operands);
|
|
|
|
|
|
|
|
firOpBuilder.createBlock(&loopOp.getRegion());
|
|
|
|
auto &block = loopOp.getRegion().back();
|
|
|
|
firOpBuilder.setInsertionPointToStart(&block);
|
|
|
|
// ensure the block is well-formed.
|
|
|
|
firOpBuilder.create<mlir::acc::YieldOp>(currentLocation);
|
|
|
|
|
|
|
|
loopOp.setAttr(mlir::acc::LoopOp::getOperandSegmentSizeAttr(),
|
|
|
|
firOpBuilder.getI32VectorAttr(
|
|
|
|
{gangNum ? 1 : 0, gangStatic ? 1 : 0, workerNum ? 1 : 0,
|
|
|
|
vectorLength ? 1 : 0, tileOperands, privateOperands,
|
|
|
|
reductionOperands}));
|
|
|
|
|
|
|
|
loopOp.setAttr(mlir::acc::LoopOp::getExecutionMappingAttrName(),
|
|
|
|
firOpBuilder.getI64IntegerAttr(executionMapping));
|
|
|
|
|
|
|
|
// Lower clauses mapped to attributes
|
|
|
|
for (const auto &clause : accClauseList.v) {
|
|
|
|
if (const auto *collapseClause =
|
|
|
|
std::get_if<Fortran::parser::AccClause::Collapse>(&clause.u)) {
|
|
|
|
const auto *expr = Fortran::semantics::GetExpr(collapseClause->v);
|
|
|
|
const auto collapseValue = Fortran::evaluate::ToInt64(*expr);
|
|
|
|
if (collapseValue) {
|
|
|
|
loopOp.setAttr(mlir::acc::LoopOp::getCollapseAttrName(),
|
|
|
|
firOpBuilder.getI64IntegerAttr(*collapseValue));
|
|
|
|
}
|
|
|
|
} else if (std::get_if<Fortran::parser::AccClause::Seq>(&clause.u)) {
|
|
|
|
loopOp.setAttr(mlir::acc::LoopOp::getSeqAttrName(),
|
|
|
|
firOpBuilder.getUnitAttr());
|
|
|
|
} else if (std::get_if<Fortran::parser::AccClause::Independent>(
|
|
|
|
&clause.u)) {
|
|
|
|
loopOp.setAttr(mlir::acc::LoopOp::getIndependentAttrName(),
|
|
|
|
firOpBuilder.getUnitAttr());
|
|
|
|
} else if (std::get_if<Fortran::parser::AccClause::Auto>(&clause.u)) {
|
|
|
|
loopOp.setAttr(mlir::acc::LoopOp::getAutoAttrName(),
|
|
|
|
firOpBuilder.getUnitAttr());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Place the insertion point to the start of the first block.
|
|
|
|
firOpBuilder.setInsertionPointToStart(&block);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[flang][openacc] Skeleton for OpenACC construct lowering
Summary:
This patch introduce the basic infrastructure to be able to lower
OpenACC constructs to the future OpenACC dialect.
Reviewers: schweitz, kiranchandramohan, DavidTruby, sscalpone, jdoerfert, ichoyjx
Reviewed By: ichoyjx
Subscribers: ichoyjx, SouraVX, mgorny, jfb, sstefan1, llvm-commits
Tags: #llvm, #flang
Differential Revision: https://reviews.llvm.org/D84195
2020-07-23 09:32:57 +08:00
|
|
|
void Fortran::lower::genOpenACCConstruct(
|
2020-09-17 23:34:28 +08:00
|
|
|
Fortran::lower::AbstractConverter &converter,
|
[flang][openacc] Skeleton for OpenACC construct lowering
Summary:
This patch introduce the basic infrastructure to be able to lower
OpenACC constructs to the future OpenACC dialect.
Reviewers: schweitz, kiranchandramohan, DavidTruby, sscalpone, jdoerfert, ichoyjx
Reviewed By: ichoyjx
Subscribers: ichoyjx, SouraVX, mgorny, jfb, sstefan1, llvm-commits
Tags: #llvm, #flang
Differential Revision: https://reviews.llvm.org/D84195
2020-07-23 09:32:57 +08:00
|
|
|
Fortran::lower::pft::Evaluation &eval,
|
|
|
|
const Fortran::parser::OpenACCConstruct &accConstruct) {
|
|
|
|
|
|
|
|
std::visit(
|
|
|
|
common::visitors{
|
|
|
|
[&](const Fortran::parser::OpenACCBlockConstruct &blockConstruct) {
|
|
|
|
TODO();
|
|
|
|
},
|
|
|
|
[&](const Fortran::parser::OpenACCCombinedConstruct
|
|
|
|
&combinedConstruct) { TODO(); },
|
|
|
|
[&](const Fortran::parser::OpenACCLoopConstruct &loopConstruct) {
|
2020-09-17 23:34:28 +08:00
|
|
|
genACC(converter, eval, loopConstruct);
|
[flang][openacc] Skeleton for OpenACC construct lowering
Summary:
This patch introduce the basic infrastructure to be able to lower
OpenACC constructs to the future OpenACC dialect.
Reviewers: schweitz, kiranchandramohan, DavidTruby, sscalpone, jdoerfert, ichoyjx
Reviewed By: ichoyjx
Subscribers: ichoyjx, SouraVX, mgorny, jfb, sstefan1, llvm-commits
Tags: #llvm, #flang
Differential Revision: https://reviews.llvm.org/D84195
2020-07-23 09:32:57 +08:00
|
|
|
},
|
|
|
|
[&](const Fortran::parser::OpenACCStandaloneConstruct
|
|
|
|
&standaloneConstruct) { TODO(); },
|
|
|
|
[&](const Fortran::parser::OpenACCRoutineConstruct
|
|
|
|
&routineConstruct) { TODO(); },
|
|
|
|
[&](const Fortran::parser::OpenACCCacheConstruct &cacheConstruct) {
|
|
|
|
TODO();
|
|
|
|
},
|
|
|
|
[&](const Fortran::parser::OpenACCWaitConstruct &waitConstruct) {
|
|
|
|
TODO();
|
|
|
|
},
|
|
|
|
[&](const Fortran::parser::OpenACCAtomicConstruct &atomicConstruct) {
|
|
|
|
TODO();
|
|
|
|
},
|
|
|
|
},
|
|
|
|
accConstruct.u);
|
|
|
|
}
|