diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -147,7 +147,7 @@ } static void genDeviceTypeClause( - Fortran::lower::AbstractConverter &converter, + Fortran::lower::AbstractConverter &converter, mlir::Location clauseLocation, const Fortran::parser::AccClause::DeviceType *deviceTypeClause, llvm::SmallVectorImpl &operands, Fortran::lower::StatementContext &stmtCtx) { @@ -157,27 +157,28 @@ const auto &expr = std::get>( deviceTypeExpr.t); if (expr) { - operands.push_back(fir::getBase( - converter.genExprValue(*Fortran::semantics::GetExpr(expr), stmtCtx))); + operands.push_back(fir::getBase(converter.genExprValue( + *Fortran::semantics::GetExpr(expr), stmtCtx, &clauseLocation))); } else { // * was passed as value and will be represented as a special constant. fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); mlir::Value star = firOpBuilder.createIntegerConstant( - converter.getCurrentLocation(), firOpBuilder.getIndexType(), starCst); + clauseLocation, firOpBuilder.getIndexType(), starCst); operands.push_back(star); } } } static void genIfClause(Fortran::lower::AbstractConverter &converter, + mlir::Location clauseLocation, const Fortran::parser::AccClause::If *ifClause, mlir::Value &ifCond, Fortran::lower::StatementContext &stmtCtx) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); mlir::Value cond = fir::getBase(converter.genExprValue( - *Fortran::semantics::GetExpr(ifClause->v), stmtCtx)); - ifCond = firOpBuilder.createConvert(converter.getCurrentLocation(), - firOpBuilder.getI1Type(), cond); + *Fortran::semantics::GetExpr(ifClause->v), stmtCtx, &clauseLocation)); + ifCond = firOpBuilder.createConvert(clauseLocation, firOpBuilder.getI1Type(), + cond); } static void genWaitClause(Fortran::lower::AbstractConverter &converter, @@ -208,9 +209,9 @@ static mlir::acc::LoopOp createLoopOp(Fortran::lower::AbstractConverter &converter, + mlir::Location currentLocation, const Fortran::parser::AccClauseList &accClauseList) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - mlir::Location currentLocation = converter.getCurrentLocation(); Fortran::lower::StatementContext stmtCtx; mlir::Value workerNum; @@ -222,6 +223,7 @@ std::int64_t executionMapping = mlir::acc::OpenACCExecMapping::NONE; for (const Fortran::parser::AccClause &clause : accClauseList.v) { + mlir::Location clauseLocation = converter.genLocation(clause.source); if (const auto *gangClause = std::get_if(&clause.u)) { if (gangClause->v) { @@ -243,7 +245,7 @@ // * was passed as value and will be represented as a special // constant. gangStatic = firOpBuilder.createIntegerConstant( - currentLocation, firOpBuilder.getIndexType(), starCst); + clauseLocation, firOpBuilder.getIndexType(), starCst); } } } @@ -276,7 +278,7 @@ // * was passed as value and will be represented as a -1 constant // integer. mlir::Value tileStar = firOpBuilder.createIntegerConstant( - currentLocation, firOpBuilder.getIntegerType(32), + clauseLocation, firOpBuilder.getIntegerType(32), /* STAR */ -1); tileOperands.push_back(tileStar); } @@ -342,15 +344,19 @@ const auto &loopDirective = std::get(beginLoopDirective.t); + mlir::Location currentLocation = + converter.genLocation(beginLoopDirective.source); + if (loopDirective.v == llvm::acc::ACCD_loop) { const auto &accClauseList = std::get(beginLoopDirective.t); - createLoopOp(converter, accClauseList); + createLoopOp(converter, currentLocation, accClauseList); } } static mlir::acc::ParallelOp createParallelOp(Fortran::lower::AbstractConverter &converter, + mlir::Location currentLocation, const Fortran::parser::AccClauseList &accClauseList) { // Parallel operation operands @@ -375,13 +381,13 @@ bool addSelfAttr = false; fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - mlir::Location currentLocation = converter.getCurrentLocation(); Fortran::lower::StatementContext stmtCtx; // Lower clauses values mapped to operands. // Keep track of each group of operands separatly as clauses can appear // more than once. for (const Fortran::parser::AccClause &clause : accClauseList.v) { + mlir::Location clauseLocation = converter.genLocation(clause.source); if (const auto *asyncClause = std::get_if(&clause.u)) { genAsyncClause(converter, asyncClause, async, addAsyncAttr, stmtCtx); @@ -406,7 +412,7 @@ *Fortran::semantics::GetExpr(vectorLengthClause->v), stmtCtx)); } else if (const auto *ifClause = std::get_if(&clause.u)) { - genIfClause(converter, ifClause, ifCond, stmtCtx); + genIfClause(converter, clauseLocation, ifClause, ifCond, stmtCtx); } else if (const auto *selfClause = std::get_if(&clause.u)) { const std::optional &accSelfClause = @@ -419,7 +425,7 @@ mlir::Value cond = fir::getBase(converter.genExprValue( *Fortran::semantics::GetExpr(*optCondition), stmtCtx)); selfCond = firOpBuilder.createConvert( - currentLocation, firOpBuilder.getI1Type(), cond); + clauseLocation, firOpBuilder.getI1Type(), cond); } } else if (const auto *accClauseList = std::get_if( @@ -432,7 +438,7 @@ if (const auto *name = getDesignatorNameIfDataRef(*designator)) { auto cond = converter.getSymbolAddress(*name->symbol); selfCond = firOpBuilder.createConvert( - currentLocation, firOpBuilder.getI1Type(), cond); + clauseLocation, firOpBuilder.getI1Type(), cond); } } } @@ -532,11 +538,13 @@ static void genACCParallelOp(Fortran::lower::AbstractConverter &converter, + mlir::Location currentLocation, const Fortran::parser::AccClauseList &accClauseList) { - createParallelOp(converter, accClauseList); + createParallelOp(converter, currentLocation, accClauseList); } static void genACCDataOp(Fortran::lower::AbstractConverter &converter, + mlir::Location currentLocation, const Fortran::parser::AccClauseList &accClauseList) { mlir::Value ifCond; llvm::SmallVector copyOperands, copyinOperands, @@ -545,16 +553,16 @@ deviceptrOperands, attachOperands; fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - mlir::Location currentLocation = converter.getCurrentLocation(); Fortran::lower::StatementContext stmtCtx; // Lower clauses values mapped to operands. // Keep track of each group of operands separatly as clauses can appear // more than once. for (const Fortran::parser::AccClause &clause : accClauseList.v) { + mlir::Location clauseLocation = converter.genLocation(clause.source); if (const auto *ifClause = std::get_if(&clause.u)) { - genIfClause(converter, ifClause, ifCond, stmtCtx); + genIfClause(converter, clauseLocation, ifClause, ifCond, stmtCtx); } else if (const auto *copyClause = std::get_if(&clause.u)) { genObjectList(copyClause->v, converter, copyOperands); @@ -626,18 +634,21 @@ const auto &accClauseList = std::get(beginBlockDirective.t); + mlir::Location currentLocation = converter.genLocation(blockDirective.source); + if (blockDirective.v == llvm::acc::ACCD_parallel) { - genACCParallelOp(converter, accClauseList); + genACCParallelOp(converter, currentLocation, accClauseList); } else if (blockDirective.v == llvm::acc::ACCD_data) { - genACCDataOp(converter, accClauseList); + genACCDataOp(converter, currentLocation, accClauseList); } } static void genACCParallelLoopOps(Fortran::lower::AbstractConverter &converter, + mlir::Location currentLocation, const Fortran::parser::AccClauseList &accClauseList) { - createParallelOp(converter, accClauseList); - createLoopOp(converter, accClauseList); + createParallelOp(converter, currentLocation, accClauseList); + createLoopOp(converter, currentLocation, accClauseList); } static void @@ -651,14 +662,15 @@ const auto &accClauseList = std::get(beginCombinedDirective.t); + mlir::Location currentLocation = + converter.genLocation(beginCombinedDirective.source); + if (combinedDirective.v == llvm::acc::ACCD_kernels_loop) { - TODO(converter.getCurrentLocation(), - "OpenACC Kernels Loop construct not lowered yet!"); + TODO(currentLocation, "OpenACC Kernels Loop construct not lowered yet!"); } else if (combinedDirective.v == llvm::acc::ACCD_parallel_loop) { - genACCParallelLoopOps(converter, accClauseList); + genACCParallelLoopOps(converter, currentLocation, accClauseList); } else if (combinedDirective.v == llvm::acc::ACCD_serial_loop) { - TODO(converter.getCurrentLocation(), - "OpenACC Serial Loop construct not lowered yet!"); + TODO(currentLocation, "OpenACC Serial Loop construct not lowered yet!"); } else { llvm::report_fatal_error("Unknown combined construct encountered"); } @@ -666,6 +678,7 @@ static void genACCEnterDataOp(Fortran::lower::AbstractConverter &converter, + mlir::Location currentLocation, const Fortran::parser::AccClauseList &accClauseList) { mlir::Value ifCond, async, waitDevnum; llvm::SmallVector copyinOperands, createOperands, @@ -678,16 +691,16 @@ bool addWaitAttr = false; fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - mlir::Location currentLocation = converter.getCurrentLocation(); Fortran::lower::StatementContext stmtCtx; // Lower clauses values mapped to operands. // Keep track of each group of operands separatly as clauses can appear // more than once. for (const Fortran::parser::AccClause &clause : accClauseList.v) { + mlir::Location clauseLocation = converter.genLocation(clause.source); if (const auto *ifClause = std::get_if(&clause.u)) { - genIfClause(converter, ifClause, ifCond, stmtCtx); + genIfClause(converter, clauseLocation, ifClause, ifCond, stmtCtx); } else if (const auto *asyncClause = std::get_if(&clause.u)) { genAsyncClause(converter, asyncClause, async, addAsyncAttr, stmtCtx); @@ -740,6 +753,7 @@ static void genACCExitDataOp(Fortran::lower::AbstractConverter &converter, + mlir::Location currentLocation, const Fortran::parser::AccClauseList &accClauseList) { mlir::Value ifCond, async, waitDevnum; llvm::SmallVector copyoutOperands, deleteOperands, @@ -753,16 +767,16 @@ bool addFinalizeAttr = false; fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - mlir::Location currentLocation = converter.getCurrentLocation(); Fortran::lower::StatementContext stmtCtx; // Lower clauses values mapped to operands. // Keep track of each group of operands separatly as clauses can appear // more than once. for (const Fortran::parser::AccClause &clause : accClauseList.v) { + mlir::Location clauseLocation = converter.genLocation(clause.source); if (const auto *ifClause = std::get_if(&clause.u)) { - genIfClause(converter, ifClause, ifCond, stmtCtx); + genIfClause(converter, clauseLocation, ifClause, ifCond, stmtCtx); } else if (const auto *asyncClause = std::get_if(&clause.u)) { genAsyncClause(converter, asyncClause, async, addAsyncAttr, stmtCtx); @@ -814,21 +828,22 @@ template static void genACCInitShutdownOp(Fortran::lower::AbstractConverter &converter, + mlir::Location currentLocation, const Fortran::parser::AccClauseList &accClauseList) { mlir::Value ifCond, deviceNum; llvm::SmallVector deviceTypeOperands; fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - mlir::Location currentLocation = converter.getCurrentLocation(); Fortran::lower::StatementContext stmtCtx; // Lower clauses values mapped to operands. // Keep track of each group of operands separatly as clauses can appear // more than once. for (const Fortran::parser::AccClause &clause : accClauseList.v) { + mlir::Location clauseLocation = converter.genLocation(clause.source); if (const auto *ifClause = std::get_if(&clause.u)) { - genIfClause(converter, ifClause, ifCond, stmtCtx); + genIfClause(converter, clauseLocation, ifClause, ifCond, stmtCtx); } else if (const auto *deviceNumClause = std::get_if( &clause.u)) { @@ -837,8 +852,8 @@ } else if (const auto *deviceTypeClause = std::get_if( &clause.u)) { - genDeviceTypeClause(converter, deviceTypeClause, deviceTypeOperands, - stmtCtx); + genDeviceTypeClause(converter, clauseLocation, deviceTypeClause, + deviceTypeOperands, stmtCtx); } } @@ -854,6 +869,7 @@ static void genACCUpdateOp(Fortran::lower::AbstractConverter &converter, + mlir::Location currentLocation, const Fortran::parser::AccClauseList &accClauseList) { mlir::Value ifCond, async, waitDevnum; llvm::SmallVector hostOperands, deviceOperands, waitOperands, @@ -867,16 +883,16 @@ bool addIfPresentAttr = false; fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - mlir::Location currentLocation = converter.getCurrentLocation(); Fortran::lower::StatementContext stmtCtx; // Lower clauses values mapped to operands. // Keep track of each group of operands separatly as clauses can appear // more than once. for (const Fortran::parser::AccClause &clause : accClauseList.v) { + mlir::Location clauseLocation = converter.genLocation(clause.source); if (const auto *ifClause = std::get_if(&clause.u)) { - genIfClause(converter, ifClause, ifCond, stmtCtx); + genIfClause(converter, clauseLocation, ifClause, ifCond, stmtCtx); } else if (const auto *asyncClause = std::get_if(&clause.u)) { genAsyncClause(converter, asyncClause, async, addAsyncAttr, stmtCtx); @@ -887,8 +903,8 @@ } else if (const auto *deviceTypeClause = std::get_if( &clause.u)) { - genDeviceTypeClause(converter, deviceTypeClause, deviceTypeOperands, - stmtCtx); + genDeviceTypeClause(converter, clauseLocation, deviceTypeClause, + deviceTypeOperands, stmtCtx); } else if (const auto *hostClause = std::get_if(&clause.u)) { genObjectList(hostClause->v, converter, hostOperands); @@ -929,19 +945,23 @@ const auto &accClauseList = std::get(standaloneConstruct.t); + mlir::Location currentLocation = + converter.genLocation(standaloneDirective.source); + if (standaloneDirective.v == llvm::acc::Directive::ACCD_enter_data) { - genACCEnterDataOp(converter, accClauseList); + genACCEnterDataOp(converter, currentLocation, accClauseList); } else if (standaloneDirective.v == llvm::acc::Directive::ACCD_exit_data) { - genACCExitDataOp(converter, accClauseList); + genACCExitDataOp(converter, currentLocation, accClauseList); } else if (standaloneDirective.v == llvm::acc::Directive::ACCD_init) { - genACCInitShutdownOp(converter, accClauseList); + genACCInitShutdownOp(converter, currentLocation, + accClauseList); } else if (standaloneDirective.v == llvm::acc::Directive::ACCD_shutdown) { - genACCInitShutdownOp(converter, accClauseList); + genACCInitShutdownOp(converter, currentLocation, + accClauseList); } else if (standaloneDirective.v == llvm::acc::Directive::ACCD_set) { - TODO(converter.getCurrentLocation(), - "OpenACC set directive not lowered yet!"); + TODO(currentLocation, "OpenACC set directive not lowered yet!"); } else if (standaloneDirective.v == llvm::acc::Directive::ACCD_update) { - genACCUpdateOp(converter, accClauseList); + genACCUpdateOp(converter, currentLocation, accClauseList); } } @@ -964,7 +984,7 @@ bool addAsyncAttr = false; fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - mlir::Location currentLocation = converter.getCurrentLocation(); + mlir::Location currentLocation = converter.genLocation(waitConstruct.source); Fortran::lower::StatementContext stmtCtx; if (waitArgument) { // wait has a value. @@ -988,9 +1008,10 @@ // Keep track of each group of operands separatly as clauses can appear // more than once. for (const Fortran::parser::AccClause &clause : accClauseList.v) { + mlir::Location clauseLocation = converter.genLocation(clause.source); if (const auto *ifClause = std::get_if(&clause.u)) { - genIfClause(converter, ifClause, ifCond, stmtCtx); + genIfClause(converter, clauseLocation, ifClause, ifCond, stmtCtx); } else if (const auto *asyncClause = std::get_if(&clause.u)) { genAsyncClause(converter, asyncClause, async, addAsyncAttr, stmtCtx); @@ -1034,14 +1055,14 @@ genACC(converter, eval, standaloneConstruct); }, [&](const Fortran::parser::OpenACCCacheConstruct &cacheConstruct) { - TODO(converter.getCurrentLocation(), + TODO(converter.genLocation(cacheConstruct.source), "OpenACC Cache construct not lowered yet!"); }, [&](const Fortran::parser::OpenACCWaitConstruct &waitConstruct) { genACC(converter, eval, waitConstruct); }, [&](const Fortran::parser::OpenACCAtomicConstruct &atomicConstruct) { - TODO(converter.getCurrentLocation(), + TODO(converter.genLocation(atomicConstruct.source), "OpenACC Atomic construct not lowered yet!"); }, }, @@ -1057,12 +1078,12 @@ common::visitors{ [&](const Fortran::parser::OpenACCStandaloneDeclarativeConstruct &standaloneDeclarativeConstruct) { - TODO(converter.getCurrentLocation(), + TODO(converter.genLocation(standaloneDeclarativeConstruct.source), "OpenACC Standalone Declarative construct not lowered yet!"); }, [&](const Fortran::parser::OpenACCRoutineConstruct &routineConstruct) { - TODO(converter.getCurrentLocation(), + TODO(converter.genLocation(routineConstruct.source), "OpenACC Routine construct not lowered yet!"); }, }, diff --git a/flang/test/Lower/OpenACC/locations.f90 b/flang/test/Lower/OpenACC/locations.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Lower/OpenACC/locations.f90 @@ -0,0 +1,108 @@ +! This test checks correct propagation of location information in OpenACC +! operations. + +! RUN: bbc -fopenacc -emit-fir --mlir-print-debuginfo --mlir-print-local-scope %s -o - | FileCheck %s + +module acc_locations + implicit none + + contains + + subroutine standalone_data_directive_locations(arr) + real, dimension(10) :: arr + + !$acc enter data create(arr) + !CHECK-LABEL: acc.enter_data + !CHECK-SAME: loc("{{.*}}locations.f90":14:11) + + !$acc update device(arr) + !CHECK-LABEL: acc.update device + !CHECK-SAME: loc("{{.*}}locations.f90":18:11) + + !$acc update host(arr) + !CHECK-LABEL: acc.update host + !CHECK-SAME: loc("{{.*}}locations.f90":22:11) + + !$acc exit data delete(arr) + !CHECK-LABEL: acc.exit_data + !CHECK-SAME: loc("{{.*}}locations.f90":26:11) + + end subroutine + + subroutine nested_acc_locations(arr1d) + real, dimension(10) :: arr1d + integer :: i + + !$acc data copy(arr1d) + !$acc parallel + !$acc loop + do i = 1, 10 + arr1d(i) = arr1d(i) * 2 + end do + !$acc end parallel + !$acc end data + + !CHECK: acc.data + !CHECK: acc.parallel + !CHECK: acc.loop + + !CHECK: acc.yield loc("{{.*}}locations.f90":38:11) + !CHECK-NEXT: } loc("{{.*}}locations.f90":38:11) + + !CHECK: acc.yield loc("{{.*}}locations.f90":37:11) + !CHECK-NEXT: } loc("{{.*}}locations.f90":37:11) + + !CHECK-NEXT: acc.terminator loc("{{.*}}locations.f90":36:11) + !CHECK-NEXT: } loc("{{.*}}locations.f90":36:11) + + end subroutine + + subroutine runtime_directive() + + !$acc init + !CHECK-LABEL: acc.init + !CHECK-SAME: loc("{{.*}}locations.f90":62:11) + + !$acc shutdown + !CHECK-LABEL: acc.shutdown + !CHECK-SAME: loc("{{.*}}locations.f90":66:11) + + end subroutine + + subroutine combined_directive_locations(arr) + real :: arr(:) + integer :: i + + !$acc parallel loop + do i = 1, size(arr) + arr(i) = arr(i) * arr(i) + end do + + !CHECK: acc.parallel + !CHECK: acc.loop + !CHECK: acc.yield loc("{{.*}}locations.f90":76:11) + !CHECK-NEXT: } loc("{{.*}}locations.f90":76:11) + !CHECK: acc.yield loc("{{.*}}locations.f90":76:11) + !CHECK-NEXT: } loc("{{.*}}locations.f90":76:11) + end subroutine + + subroutine if_clause_expr_location(arr) + real :: arr(:) + integer :: i + + !$acc parallel loop if(.true.) + do i = 1, size(arr) + arr(i) = arr(i) * arr(i) + end do + + !CHECK: %{{.*}} = arith.constant true loc("{{.*}}locations.f90":93:25) + + !CHECK: acc.parallel + !CHECK: acc.loop + !CHECK: acc.yield loc("{{.*}}locations.f90":93:11) + !CHECK-NEXT: } loc("{{.*}}locations.f90":93:11) + !CHECK: acc.yield loc("{{.*}}locations.f90":93:11) + !CHECK-NEXT: } loc("{{.*}}locations.f90":93:11) + end subroutine + +end module diff --git a/flang/tools/bbc/bbc.cpp b/flang/tools/bbc/bbc.cpp --- a/flang/tools/bbc/bbc.cpp +++ b/flang/tools/bbc/bbc.cpp @@ -278,6 +278,7 @@ registerAllPasses(); mlir::registerMLIRContextCLOptions(); + mlir::registerAsmPrinterCLOptions(); mlir::registerPassManagerCLOptions(); mlir::PassPipelineCLParser passPipe("", "Compiler passes to run"); llvm::cl::ParseCommandLineOptions(argc, argv, "Burnside Bridge Compiler\n");