From: Valentin Clement Date: Thu, 5 Nov 2020 02:15:35 +0000 (-0500) Subject: [flang][openacc] Lower wait directive X-Git-Tag: llvmorg-13-init~7032 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1dad9d4282cc33689b304e87793eff2755b82725;p=platform%2Fupstream%2Fllvm.git [flang][openacc] Lower wait directive This patch upstream the lowering of Wait directive that was initially done in https://github.com/flang-compiler/f18-llvm-project/pull/532 Reviewed By: schweitz Differential Revision: https://reviews.llvm.org/D90489 --- diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index 3db6656..f9a60ca 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -911,6 +911,81 @@ genACC(Fortran::lower::AbstractConverter &converter, } } +static void genACC(Fortran::lower::AbstractConverter &converter, + Fortran::lower::pft::Evaluation &eval, + const Fortran::parser::OpenACCWaitConstruct &waitConstruct) { + + const auto &waitArgument = + std::get>( + waitConstruct.t); + const auto &accClauseList = + std::get(waitConstruct.t); + + mlir::Value ifCond, asyncOperand, waitDevnum, async; + SmallVector waitOperands; + + // Async clause have optional values but can be present with + // no value as well. When there is no value, the op has an attribute to + // represent the clause. + bool addAsyncAttr = false; + + auto &firOpBuilder = converter.getFirOpBuilder(); + auto currentLocation = converter.getCurrentLocation(); + + if (waitArgument) { // wait has a value. + const Fortran::parser::AccWaitArgument &waitArg = *waitArgument; + const std::list &waitList = + std::get>(waitArg.t); + for (const Fortran::parser::ScalarIntExpr &value : waitList) { + mlir::Value v = fir::getBase( + converter.genExprValue(*Fortran::semantics::GetExpr(value))); + waitOperands.push_back(v); + } + + const std::optional &waitDevnumValue = + std::get>(waitArg.t); + if (waitDevnumValue) + waitDevnum = fir::getBase(converter.genExprValue( + *Fortran::semantics::GetExpr(*waitDevnumValue))); + } + + // Lower clauses values mapped to operands. + // Keep track of each group of operands separatly as clauses can appear + // more than once. + for (const auto &clause : accClauseList.v) { + if (const auto *ifClause = + std::get_if(&clause.u)) { + mlir::Value cond = fir::getBase( + converter.genExprValue(*Fortran::semantics::GetExpr(ifClause->v))); + ifCond = firOpBuilder.createConvert(currentLocation, + firOpBuilder.getI1Type(), cond); + } else if (const auto *asyncClause = + std::get_if(&clause.u)) { + const auto &asyncClauseValue = asyncClause->v; + if (asyncClauseValue) { // async has a value. + async = fir::getBase(converter.genExprValue( + *Fortran::semantics::GetExpr(*asyncClauseValue))); + } else { + addAsyncAttr = true; + } + } + } + + // Prepare the operand segement size attribute and the operands value range. + SmallVector operands; + SmallVector operandSegments; + addOperands(operands, operandSegments, waitOperands); + addOperand(operands, operandSegments, async); + addOperand(operands, operandSegments, waitDevnum); + addOperand(operands, operandSegments, ifCond); + + auto waitOp = createSimpleOp(firOpBuilder, currentLocation, + operands, operandSegments); + + if (addAsyncAttr) + waitOp.asyncAttr(firOpBuilder.getUnitAttr()); +} + void Fortran::lower::genOpenACCConstruct( Fortran::lower::AbstractConverter &converter, Fortran::lower::pft::Evaluation &eval, @@ -940,7 +1015,7 @@ void Fortran::lower::genOpenACCConstruct( TODO("OpenACC Cache construct not lowered yet!"); }, [&](const Fortran::parser::OpenACCWaitConstruct &waitConstruct) { - TODO("OpenACC Wait construct not lowered yet!"); + genACC(converter, eval, waitConstruct); }, [&](const Fortran::parser::OpenACCAtomicConstruct &atomicConstruct) { TODO("OpenACC Atomic construct not lowered yet!");