diff options
author | Krzysztof Parzyszek <Krzysztof.Parzyszek@amd.com> | 2024-03-15 14:42:37 -0700 |
---|---|---|
committer | Slava Zakharin <szakharin@nvidia.com> | 2024-03-15 14:42:37 -0700 |
commit | 5758b87969276db859432544508f335c214ce304 (patch) | |
tree | 3bdf8e067ae458e90381d536a2343a4cc718a8f2 | |
parent | 049dc8eb1e2f2734f3662e103efffe17ec1f3d68 (diff) | |
parent | 037a32a9a73286cf6e1bf439c61b03767658b564 (diff) | |
download | llvm-users/vzakhari/spr/main.nfcflang-reorder-const-and-rt_api_attrs.zip llvm-users/vzakhari/spr/main.nfcflang-reorder-const-and-rt_api_attrs.tar.gz llvm-users/vzakhari/spr/main.nfcflang-reorder-const-and-rt_api_attrs.tar.bz2 |
[𝘀𝗽𝗿] changes introduced through rebaseusers/vzakhari/spr/main.nfcflang-reorder-const-and-rt_api_attrs
Created using spr 1.3.4
[skip ci]
-rw-r--r-- | flang/include/flang/Common/visit.h | 5 | ||||
-rw-r--r-- | flang/lib/Lower/OpenMP/Clauses.h | 12 | ||||
-rw-r--r-- | flang/lib/Lower/OpenMP/DataSharingProcessor.cpp | 287 | ||||
-rw-r--r-- | flang/lib/Lower/OpenMP/DataSharingProcessor.h | 12 | ||||
-rw-r--r-- | flang/lib/Lower/OpenMP/OpenMP.cpp | 8 | ||||
-rw-r--r-- | flang/runtime/io-stmt.cpp | 45 | ||||
-rw-r--r-- | flang/runtime/io-stmt.h | 92 | ||||
-rw-r--r-- | llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn | 1 |
8 files changed, 189 insertions, 273 deletions
diff --git a/flang/include/flang/Common/visit.h b/flang/include/flang/Common/visit.h index a6f04c1..d3136be 100644 --- a/flang/include/flang/Common/visit.h +++ b/flang/include/flang/Common/visit.h @@ -42,7 +42,6 @@ #ifndef FORTRAN_COMMON_VISIT_H_ #define FORTRAN_COMMON_VISIT_H_ -#include "flang/Runtime/api-attrs.h" #include <type_traits> #include <variant> @@ -51,7 +50,7 @@ namespace log2visit { template <std::size_t LOW, std::size_t HIGH, typename RESULT, typename VISITOR, typename... VARIANT> -inline RT_API_ATTRS RESULT Log2VisitHelper( +inline RESULT Log2VisitHelper( VISITOR &&visitor, std::size_t which, VARIANT &&...u) { if constexpr (LOW == HIGH) { return visitor(std::get<LOW>(std::forward<VARIANT>(u))...); @@ -68,7 +67,7 @@ inline RT_API_ATTRS RESULT Log2VisitHelper( } template <typename VISITOR, typename... VARIANT> -inline RT_API_ATTRS auto visit(VISITOR &&visitor, VARIANT &&...u) +inline auto visit(VISITOR &&visitor, VARIANT &&...u) -> decltype(visitor(std::get<0>(std::forward<VARIANT>(u))...)) { using Result = decltype(visitor(std::get<0>(std::forward<VARIANT>(u))...)); if constexpr (sizeof...(u) == 1) { diff --git a/flang/lib/Lower/OpenMP/Clauses.h b/flang/lib/Lower/OpenMP/Clauses.h index 1d1a112..3fba593 100644 --- a/flang/lib/Lower/OpenMP/Clauses.h +++ b/flang/lib/Lower/OpenMP/Clauses.h @@ -108,6 +108,12 @@ getBaseObject(const Object &object, Fortran::semantics::SemanticsContext &semaCtx); namespace clause { +using DefinedOperator = tomp::clause::DefinedOperatorT<SymIdent, SymReference>; +using ProcedureDesignator = + tomp::clause::ProcedureDesignatorT<SymIdent, SymReference>; +using ReductionOperator = + tomp::clause::ReductionOperatorT<SymIdent, SymReference>; + #ifdef EMPTY_CLASS #undef EMPTY_CLASS #endif @@ -124,12 +130,6 @@ namespace clause { #undef EMPTY_CLASS #undef WRAPPER_CLASS -using DefinedOperator = tomp::clause::DefinedOperatorT<SymIdent, SymReference>; -using ProcedureDesignator = - tomp::clause::ProcedureDesignatorT<SymIdent, SymReference>; -using ReductionOperator = - tomp::clause::ReductionOperatorT<SymIdent, SymReference>; - // "Requires" clauses are handled early on, and the aggregated information // is stored in the Symbol details of modules, programs, and subprograms. // These clauses are still handled here to cover all alternatives in the diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp index 717b8cc..0d952d4 100644 --- a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp +++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp @@ -81,30 +81,26 @@ void DataSharingProcessor::copyLastPrivateSymbol( } void DataSharingProcessor::collectOmpObjectListSymbol( - const Fortran::parser::OmpObjectList &ompObjectList, + const omp::ObjectList &objects, llvm::SetVector<const Fortran::semantics::Symbol *> &symbolSet) { - for (const Fortran::parser::OmpObject &ompObject : ompObjectList.v) { - Fortran::semantics::Symbol *sym = getOmpObjectSymbol(ompObject); - symbolSet.insert(sym); - } + for (const omp::Object &object : objects) + symbolSet.insert(object.id()); } void DataSharingProcessor::collectSymbolsForPrivatization() { bool hasCollapse = false; - for (const Fortran::parser::OmpClause &clause : opClauseList.v) { + for (const omp::Clause &clause : clauses) { if (const auto &privateClause = - std::get_if<Fortran::parser::OmpClause::Private>(&clause.u)) { + std::get_if<omp::clause::Private>(&clause.u)) { collectOmpObjectListSymbol(privateClause->v, privatizedSymbols); } else if (const auto &firstPrivateClause = - std::get_if<Fortran::parser::OmpClause::Firstprivate>( - &clause.u)) { + std::get_if<omp::clause::Firstprivate>(&clause.u)) { collectOmpObjectListSymbol(firstPrivateClause->v, privatizedSymbols); } else if (const auto &lastPrivateClause = - std::get_if<Fortran::parser::OmpClause::Lastprivate>( - &clause.u)) { + std::get_if<omp::clause::Lastprivate>(&clause.u)) { collectOmpObjectListSymbol(lastPrivateClause->v, privatizedSymbols); hasLastPrivateOp = true; - } else if (std::get_if<Fortran::parser::OmpClause::Collapse>(&clause.u)) { + } else if (std::get_if<omp::clause::Collapse>(&clause.u)) { hasCollapse = true; } } @@ -137,138 +133,135 @@ void DataSharingProcessor::insertBarrier() { void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) { bool cmpCreated = false; mlir::OpBuilder::InsertPoint localInsPt = firOpBuilder.saveInsertionPoint(); - for (const Fortran::parser::OmpClause &clause : opClauseList.v) { - if (std::get_if<Fortran::parser::OmpClause::Lastprivate>(&clause.u)) { - // TODO: Add lastprivate support for simd construct - if (mlir::isa<mlir::omp::SectionOp>(op)) { - if (&eval == &eval.parentConstruct->getLastNestedEvaluation()) { - // For `omp.sections`, lastprivatized variables occur in - // lexically final `omp.section` operation. The following FIR - // shall be generated for the same: - // - // omp.sections lastprivate(...) { - // omp.section {...} - // omp.section {...} - // omp.section { - // fir.allocate for `private`/`firstprivate` - // <More operations here> - // fir.if %true { - // ^%lpv_update_blk - // } - // } - // } - // - // To keep code consistency while handling privatization - // through this control flow, add a `fir.if` operation - // that always evaluates to true, in order to create - // a dedicated sub-region in `omp.section` where - // lastprivate FIR can reside. Later canonicalizations - // will optimize away this operation. - if (!eval.lowerAsUnstructured()) { - auto ifOp = firOpBuilder.create<fir::IfOp>( - op->getLoc(), - firOpBuilder.createIntegerConstant( - op->getLoc(), firOpBuilder.getIntegerType(1), 0x1), - /*else*/ false); - firOpBuilder.setInsertionPointToStart( - &ifOp.getThenRegion().front()); - - const Fortran::parser::OpenMPConstruct *parentOmpConstruct = - eval.parentConstruct->getIf<Fortran::parser::OpenMPConstruct>(); - assert(parentOmpConstruct && - "Expected a valid enclosing OpenMP construct"); - const Fortran::parser::OpenMPSectionsConstruct *sectionsConstruct = - std::get_if<Fortran::parser::OpenMPSectionsConstruct>( - &parentOmpConstruct->u); - assert(sectionsConstruct && - "Expected an enclosing omp.sections construct"); - const Fortran::parser::OmpClauseList §ionsEndClauseList = - std::get<Fortran::parser::OmpClauseList>( - std::get<Fortran::parser::OmpEndSectionsDirective>( - sectionsConstruct->t) - .t); - for (const Fortran::parser::OmpClause &otherClause : - sectionsEndClauseList.v) - if (std::get_if<Fortran::parser::OmpClause::Nowait>( - &otherClause.u)) - // Emit implicit barrier to synchronize threads and avoid data - // races on post-update of lastprivate variables when `nowait` - // clause is present. - firOpBuilder.create<mlir::omp::BarrierOp>( - converter.getCurrentLocation()); - firOpBuilder.setInsertionPointToStart( - &ifOp.getThenRegion().front()); - lastPrivIP = firOpBuilder.saveInsertionPoint(); - firOpBuilder.setInsertionPoint(ifOp); - insPt = firOpBuilder.saveInsertionPoint(); - } else { - // Lastprivate operation is inserted at the end - // of the lexically last section in the sections - // construct - mlir::OpBuilder::InsertPoint unstructuredSectionsIP = - firOpBuilder.saveInsertionPoint(); - mlir::Operation *lastOper = op->getRegion(0).back().getTerminator(); - firOpBuilder.setInsertionPoint(lastOper); - lastPrivIP = firOpBuilder.saveInsertionPoint(); - firOpBuilder.restoreInsertionPoint(unstructuredSectionsIP); - } - } - } else if (mlir::isa<mlir::omp::WsLoopOp>(op)) { - // Update the original variable just before exiting the worksharing - // loop. Conversion as follows: + for (const omp::Clause &clause : clauses) { + if (clause.id != llvm::omp::OMPC_lastprivate) + continue; + // TODO: Add lastprivate support for simd construct + if (mlir::isa<mlir::omp::SectionOp>(op)) { + if (&eval == &eval.parentConstruct->getLastNestedEvaluation()) { + // For `omp.sections`, lastprivatized variables occur in + // lexically final `omp.section` operation. The following FIR + // shall be generated for the same: // - // omp.wsloop { - // omp.wsloop { ... - // ... store - // store ===> %v = arith.addi %iv, %step - // omp.yield %cmp = %step < 0 ? %v < %ub : %v > %ub - // } fir.if %cmp { - // fir.store %v to %loopIV - // ^%lpv_update_blk: - // } - // omp.yield - // } + // omp.sections lastprivate(...) { + // omp.section {...} + // omp.section {...} + // omp.section { + // fir.allocate for `private`/`firstprivate` + // <More operations here> + // fir.if %true { + // ^%lpv_update_blk + // } + // } + // } // - - // Only generate the compare once in presence of multiple LastPrivate - // clauses. - if (cmpCreated) - continue; - cmpCreated = true; - - mlir::Location loc = op->getLoc(); - mlir::Operation *lastOper = op->getRegion(0).back().getTerminator(); - firOpBuilder.setInsertionPoint(lastOper); - - mlir::Value iv = op->getRegion(0).front().getArguments()[0]; - mlir::Value ub = - mlir::dyn_cast<mlir::omp::WsLoopOp>(op).getUpperBound()[0]; - mlir::Value step = mlir::dyn_cast<mlir::omp::WsLoopOp>(op).getStep()[0]; - - // v = iv + step - // cmp = step < 0 ? v < ub : v > ub - mlir::Value v = firOpBuilder.create<mlir::arith::AddIOp>(loc, iv, step); - mlir::Value zero = - firOpBuilder.createIntegerConstant(loc, step.getType(), 0); - mlir::Value negativeStep = firOpBuilder.create<mlir::arith::CmpIOp>( - loc, mlir::arith::CmpIPredicate::slt, step, zero); - mlir::Value vLT = firOpBuilder.create<mlir::arith::CmpIOp>( - loc, mlir::arith::CmpIPredicate::slt, v, ub); - mlir::Value vGT = firOpBuilder.create<mlir::arith::CmpIOp>( - loc, mlir::arith::CmpIPredicate::sgt, v, ub); - mlir::Value cmpOp = firOpBuilder.create<mlir::arith::SelectOp>( - loc, negativeStep, vLT, vGT); - - auto ifOp = firOpBuilder.create<fir::IfOp>(loc, cmpOp, /*else*/ false); - firOpBuilder.setInsertionPointToStart(&ifOp.getThenRegion().front()); - assert(loopIV && "loopIV was not set"); - firOpBuilder.create<fir::StoreOp>(op->getLoc(), v, loopIV); - lastPrivIP = firOpBuilder.saveInsertionPoint(); - } else { - TODO(converter.getCurrentLocation(), - "lastprivate clause in constructs other than " - "simd/worksharing-loop"); + // To keep code consistency while handling privatization + // through this control flow, add a `fir.if` operation + // that always evaluates to true, in order to create + // a dedicated sub-region in `omp.section` where + // lastprivate FIR can reside. Later canonicalizations + // will optimize away this operation. + if (!eval.lowerAsUnstructured()) { + auto ifOp = firOpBuilder.create<fir::IfOp>( + op->getLoc(), + firOpBuilder.createIntegerConstant( + op->getLoc(), firOpBuilder.getIntegerType(1), 0x1), + /*else*/ false); + firOpBuilder.setInsertionPointToStart(&ifOp.getThenRegion().front()); + + const Fortran::parser::OpenMPConstruct *parentOmpConstruct = + eval.parentConstruct->getIf<Fortran::parser::OpenMPConstruct>(); + assert(parentOmpConstruct && + "Expected a valid enclosing OpenMP construct"); + const Fortran::parser::OpenMPSectionsConstruct *sectionsConstruct = + std::get_if<Fortran::parser::OpenMPSectionsConstruct>( + &parentOmpConstruct->u); + assert(sectionsConstruct && + "Expected an enclosing omp.sections construct"); + const Fortran::parser::OmpClauseList §ionsEndClauseList = + std::get<Fortran::parser::OmpClauseList>( + std::get<Fortran::parser::OmpEndSectionsDirective>( + sectionsConstruct->t) + .t); + for (const Fortran::parser::OmpClause &otherClause : + sectionsEndClauseList.v) + if (std::get_if<Fortran::parser::OmpClause::Nowait>(&otherClause.u)) + // Emit implicit barrier to synchronize threads and avoid data + // races on post-update of lastprivate variables when `nowait` + // clause is present. + firOpBuilder.create<mlir::omp::BarrierOp>( + converter.getCurrentLocation()); + firOpBuilder.setInsertionPointToStart(&ifOp.getThenRegion().front()); + lastPrivIP = firOpBuilder.saveInsertionPoint(); + firOpBuilder.setInsertionPoint(ifOp); + insPt = firOpBuilder.saveInsertionPoint(); + } else { + // Lastprivate operation is inserted at the end + // of the lexically last section in the sections + // construct + mlir::OpBuilder::InsertPoint unstructuredSectionsIP = + firOpBuilder.saveInsertionPoint(); + mlir::Operation *lastOper = op->getRegion(0).back().getTerminator(); + firOpBuilder.setInsertionPoint(lastOper); + lastPrivIP = firOpBuilder.saveInsertionPoint(); + firOpBuilder.restoreInsertionPoint(unstructuredSectionsIP); + } } + } else if (mlir::isa<mlir::omp::WsLoopOp>(op)) { + // Update the original variable just before exiting the worksharing + // loop. Conversion as follows: + // + // omp.wsloop { + // omp.wsloop { ... + // ... store + // store ===> %v = arith.addi %iv, %step + // omp.yield %cmp = %step < 0 ? %v < %ub : %v > %ub + // } fir.if %cmp { + // fir.store %v to %loopIV + // ^%lpv_update_blk: + // } + // omp.yield + // } + // + + // Only generate the compare once in presence of multiple LastPrivate + // clauses. + if (cmpCreated) + continue; + cmpCreated = true; + + mlir::Location loc = op->getLoc(); + mlir::Operation *lastOper = op->getRegion(0).back().getTerminator(); + firOpBuilder.setInsertionPoint(lastOper); + + mlir::Value iv = op->getRegion(0).front().getArguments()[0]; + mlir::Value ub = + mlir::dyn_cast<mlir::omp::WsLoopOp>(op).getUpperBound()[0]; + mlir::Value step = mlir::dyn_cast<mlir::omp::WsLoopOp>(op).getStep()[0]; + + // v = iv + step + // cmp = step < 0 ? v < ub : v > ub + mlir::Value v = firOpBuilder.create<mlir::arith::AddIOp>(loc, iv, step); + mlir::Value zero = + firOpBuilder.createIntegerConstant(loc, step.getType(), 0); + mlir::Value negativeStep = firOpBuilder.create<mlir::arith::CmpIOp>( + loc, mlir::arith::CmpIPredicate::slt, step, zero); + mlir::Value vLT = firOpBuilder.create<mlir::arith::CmpIOp>( + loc, mlir::arith::CmpIPredicate::slt, v, ub); + mlir::Value vGT = firOpBuilder.create<mlir::arith::CmpIOp>( + loc, mlir::arith::CmpIPredicate::sgt, v, ub); + mlir::Value cmpOp = firOpBuilder.create<mlir::arith::SelectOp>( + loc, negativeStep, vLT, vGT); + + auto ifOp = firOpBuilder.create<fir::IfOp>(loc, cmpOp, /*else*/ false); + firOpBuilder.setInsertionPointToStart(&ifOp.getThenRegion().front()); + assert(loopIV && "loopIV was not set"); + firOpBuilder.create<fir::StoreOp>(op->getLoc(), v, loopIV); + lastPrivIP = firOpBuilder.saveInsertionPoint(); + } else { + TODO(converter.getCurrentLocation(), + "lastprivate clause in constructs other than " + "simd/worksharing-loop"); } } firOpBuilder.restoreInsertionPoint(localInsPt); @@ -292,14 +285,12 @@ void DataSharingProcessor::collectSymbols( } void DataSharingProcessor::collectDefaultSymbols() { - for (const Fortran::parser::OmpClause &clause : opClauseList.v) { - if (const auto &defaultClause = - std::get_if<Fortran::parser::OmpClause::Default>(&clause.u)) { - if (defaultClause->v.v == - Fortran::parser::OmpDefaultClause::Type::Private) + for (const omp::Clause &clause : clauses) { + if (const auto *defaultClause = + std::get_if<omp::clause::Default>(&clause.u)) { + if (defaultClause->v == omp::clause::Default::Type::Private) collectSymbols(Fortran::semantics::Symbol::Flag::OmpPrivate); - else if (defaultClause->v.v == - Fortran::parser::OmpDefaultClause::Type::Firstprivate) + else if (defaultClause->v == omp::clause::Default::Type::Firstprivate) collectSymbols(Fortran::semantics::Symbol::Flag::OmpFirstPrivate); } } diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.h b/flang/lib/Lower/OpenMP/DataSharingProcessor.h index 9f7301d..226abe9 100644 --- a/flang/lib/Lower/OpenMP/DataSharingProcessor.h +++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.h @@ -12,6 +12,7 @@ #ifndef FORTRAN_LOWER_DATASHARINGPROCESSOR_H #define FORTRAN_LOWER_DATASHARINGPROCESSOR_H +#include "Clauses.h" #include "flang/Lower/AbstractConverter.h" #include "flang/Lower/OpenMP.h" #include "flang/Optimizer/Builder/FIRBuilder.h" @@ -52,7 +53,7 @@ private: llvm::SetVector<const Fortran::semantics::Symbol *> symbolsInParentRegions; Fortran::lower::AbstractConverter &converter; fir::FirOpBuilder &firOpBuilder; - const Fortran::parser::OmpClauseList &opClauseList; + omp::List<omp::Clause> clauses; Fortran::lower::pft::Evaluation &eval; bool useDelayedPrivatization; Fortran::lower::SymMap *symTable; @@ -61,7 +62,7 @@ private: bool needBarrier(); void collectSymbols(Fortran::semantics::Symbol::Flag flag); void collectOmpObjectListSymbol( - const Fortran::parser::OmpObjectList &ompObjectList, + const omp::ObjectList &objects, llvm::SetVector<const Fortran::semantics::Symbol *> &symbolSet); void collectSymbolsForPrivatization(); void insertBarrier(); @@ -81,14 +82,15 @@ private: public: DataSharingProcessor(Fortran::lower::AbstractConverter &converter, + Fortran::semantics::SemanticsContext &semaCtx, const Fortran::parser::OmpClauseList &opClauseList, Fortran::lower::pft::Evaluation &eval, bool useDelayedPrivatization = false, Fortran::lower::SymMap *symTable = nullptr) : hasLastPrivateOp(false), converter(converter), - firOpBuilder(converter.getFirOpBuilder()), opClauseList(opClauseList), - eval(eval), useDelayedPrivatization(useDelayedPrivatization), - symTable(symTable) {} + firOpBuilder(converter.getFirOpBuilder()), + clauses(omp::makeList(opClauseList, semaCtx)), eval(eval), + useDelayedPrivatization(useDelayedPrivatization), symTable(symTable) {} // Privatisation is split into two steps. // Step1 performs cloning of all privatisation clauses and copying for diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 5d4db06..7b384d8 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -373,7 +373,7 @@ static void createBodyOfOp(Op &op, OpWithBodyGenInfo &info) { std::optional<DataSharingProcessor> tempDsp; if (privatize) { if (!info.dsp) { - tempDsp.emplace(info.converter, *info.clauses, info.eval); + tempDsp.emplace(info.converter, info.semaCtx, *info.clauses, info.eval); tempDsp->processStep1(); } } @@ -627,7 +627,7 @@ genParallelOp(Fortran::lower::AbstractConverter &converter, } bool privatize = !outerCombined; - DataSharingProcessor dsp(converter, clauseList, eval, + DataSharingProcessor dsp(converter, semaCtx, clauseList, eval, /*useDelayedPrivatization=*/true, &symTable); if (privatize) @@ -1575,7 +1575,7 @@ createSimdLoop(Fortran::lower::AbstractConverter &converter, const Fortran::parser::OmpClauseList &loopOpClauseList, mlir::Location loc) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - DataSharingProcessor dsp(converter, loopOpClauseList, eval); + DataSharingProcessor dsp(converter, semaCtx, loopOpClauseList, eval); dsp.processStep1(); Fortran::lower::StatementContext stmtCtx; @@ -1634,7 +1634,7 @@ static void createWsLoop(Fortran::lower::AbstractConverter &converter, const Fortran::parser::OmpClauseList *endClauseList, mlir::Location loc) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - DataSharingProcessor dsp(converter, beginClauseList, eval); + DataSharingProcessor dsp(converter, semaCtx, beginClauseList, eval); dsp.processStep1(); Fortran::lower::StatementContext stmtCtx; diff --git a/flang/runtime/io-stmt.cpp b/flang/runtime/io-stmt.cpp index c42af0a..075d7b5 100644 --- a/flang/runtime/io-stmt.cpp +++ b/flang/runtime/io-stmt.cpp @@ -467,67 +467,69 @@ int ExternalFormattedIoStatementState<DIR, CHAR>::EndIoStatement() { } Fortran::common::optional<DataEdit> IoStatementState::GetNextDataEdit(int n) { - return visitIo( + return common::visit( [&](auto &x) { return x.get().GetNextDataEdit(*this, n); }, u_); } bool IoStatementState::Emit( const char *data, std::size_t bytes, std::size_t elementBytes) { - return visitIo( + return common::visit( [=](auto &x) { return x.get().Emit(data, bytes, elementBytes); }, u_); } bool IoStatementState::Receive( char *data, std::size_t n, std::size_t elementBytes) { - return visitIo( + return common::visit( [=](auto &x) { return x.get().Receive(data, n, elementBytes); }, u_); } std::size_t IoStatementState::GetNextInputBytes(const char *&p) { - return visitIo([&](auto &x) { return x.get().GetNextInputBytes(p); }, u_); + return common::visit( + [&](auto &x) { return x.get().GetNextInputBytes(p); }, u_); } bool IoStatementState::AdvanceRecord(int n) { - return visitIo([=](auto &x) { return x.get().AdvanceRecord(n); }, u_); + return common::visit([=](auto &x) { return x.get().AdvanceRecord(n); }, u_); } void IoStatementState::BackspaceRecord() { - visitIo([](auto &x) { x.get().BackspaceRecord(); }, u_); + common::visit([](auto &x) { x.get().BackspaceRecord(); }, u_); } void IoStatementState::HandleRelativePosition(std::int64_t n) { - visitIo([=](auto &x) { x.get().HandleRelativePosition(n); }, u_); + common::visit([=](auto &x) { x.get().HandleRelativePosition(n); }, u_); } void IoStatementState::HandleAbsolutePosition(std::int64_t n) { - visitIo([=](auto &x) { x.get().HandleAbsolutePosition(n); }, u_); + common::visit([=](auto &x) { x.get().HandleAbsolutePosition(n); }, u_); } void IoStatementState::CompleteOperation() { - visitIo([](auto &x) { x.get().CompleteOperation(); }, u_); + common::visit([](auto &x) { x.get().CompleteOperation(); }, u_); } int IoStatementState::EndIoStatement() { - return visitIo([](auto &x) { return x.get().EndIoStatement(); }, u_); + return common::visit([](auto &x) { return x.get().EndIoStatement(); }, u_); } ConnectionState &IoStatementState::GetConnectionState() { - return visitIo( + return common::visit( [](auto &x) -> ConnectionState & { return x.get().GetConnectionState(); }, u_); } MutableModes &IoStatementState::mutableModes() { - return visitIo( + return common::visit( [](auto &x) -> MutableModes & { return x.get().mutableModes(); }, u_); } bool IoStatementState::BeginReadingRecord() { - return visitIo([](auto &x) { return x.get().BeginReadingRecord(); }, u_); + return common::visit( + [](auto &x) { return x.get().BeginReadingRecord(); }, u_); } IoErrorHandler &IoStatementState::GetIoErrorHandler() const { - return visitIo( + return common::visit( [](auto &x) -> IoErrorHandler & { return static_cast<IoErrorHandler &>(x.get()); }, @@ -535,7 +537,8 @@ IoErrorHandler &IoStatementState::GetIoErrorHandler() const { } ExternalFileUnit *IoStatementState::GetExternalFileUnit() const { - return visitIo([](auto &x) { return x.get().GetExternalFileUnit(); }, u_); + return common::visit( + [](auto &x) { return x.get().GetExternalFileUnit(); }, u_); } Fortran::common::optional<char32_t> IoStatementState::GetCurrentChar( @@ -661,26 +664,28 @@ bool IoStatementState::CheckForEndOfRecord(std::size_t afterReading) { bool IoStatementState::Inquire( InquiryKeywordHash inquiry, char *out, std::size_t chars) { - return visitIo( + return common::visit( [&](auto &x) { return x.get().Inquire(inquiry, out, chars); }, u_); } bool IoStatementState::Inquire(InquiryKeywordHash inquiry, bool &out) { - return visitIo([&](auto &x) { return x.get().Inquire(inquiry, out); }, u_); + return common::visit( + [&](auto &x) { return x.get().Inquire(inquiry, out); }, u_); } bool IoStatementState::Inquire( InquiryKeywordHash inquiry, std::int64_t id, bool &out) { - return visitIo( + return common::visit( [&](auto &x) { return x.get().Inquire(inquiry, id, out); }, u_); } bool IoStatementState::Inquire(InquiryKeywordHash inquiry, std::int64_t &n) { - return visitIo([&](auto &x) { return x.get().Inquire(inquiry, n); }, u_); + return common::visit( + [&](auto &x) { return x.get().Inquire(inquiry, n); }, u_); } std::int64_t IoStatementState::InquirePos() { - return visitIo([&](auto &x) { return x.get().InquirePos(); }, u_); + return common::visit([&](auto &x) { return x.get().InquirePos(); }, u_); } void IoStatementState::GotChar(int n) { diff --git a/flang/runtime/io-stmt.h b/flang/runtime/io-stmt.h index 4e17cee2..e00d549 100644 --- a/flang/runtime/io-stmt.h +++ b/flang/runtime/io-stmt.h @@ -16,19 +16,15 @@ #include "format.h" #include "internal-unit.h" #include "io-error.h" -#include "flang/Common/idioms.h" #include "flang/Common/optional.h" #include "flang/Common/reference-wrapper.h" +#include "flang/Common/visit.h" #include "flang/Runtime/descriptor.h" #include "flang/Runtime/io-api.h" #include <functional> #include <type_traits> #include <variant> -// I/O statement state classes that may be instantiated during execution -// on an offload device have this trait: -CLASS_TRAIT(AvailableOnDevice) - namespace Fortran::runtime::io { class ExternalFileUnit; @@ -56,23 +52,15 @@ template <Direction> class ChildListIoStatementState; template <Direction> class ChildUnformattedIoStatementState; struct InputStatementState {}; -struct OutputStatementState { - using AvailableOnDevice = std::true_type; -}; +struct OutputStatementState {}; template <Direction D> using IoDirectionState = std::conditional_t<D == Direction::Input, InputStatementState, OutputStatementState>; // Common state for all kinds of formatted I/O template <Direction D> class FormattedIoStatementState {}; -template <> class FormattedIoStatementState<Direction::Output> { -public: - using AvailableOnDevice = std::true_type; -}; - template <> class FormattedIoStatementState<Direction::Input> { public: - using AvailableOnDevice = std::true_type; std::size_t GetEditDescriptorChars() const; void GotChar(int); @@ -125,19 +113,10 @@ public: // N.B.: this also works with base classes template <typename A> A *get_if() const { - [[maybe_unused]] std::size_t index{u_.index()}; - return Fortran::common::visit( - [=](auto &x) -> A * { + return common::visit( + [](auto &x) -> A * { if constexpr (std::is_convertible_v<decltype(x.get()), A &>) { -#if defined(RT_DEVICE_COMPILATION) - if constexpr (!AvailableOnDevice<std::decay_t<A>>) { - terminateOnDevice(__FILE__, __LINE__, index); - } else { -#endif - return &x.get(); -#if defined(RT_DEVICE_COMPILATION) - } -#endif + return &x.get(); } return nullptr; }, @@ -232,40 +211,6 @@ public: } private: -#if RT_DEVICE_COMPILATION - static RT_API_ATTRS void terminateOnDevice( - const char *sourceFile, int sourceLine, std::size_t index) { - // %zd is not supported by device printf. - Terminator{sourceFile, sourceLine}.Crash( - "Unexpected IO statement variant (index %d) during device execution", - static_cast<int>(index)); - } -#endif - - // Define special visitor for the variants of IoStatementState. - // During the device code compilation the visitor only allows - // visiting those variants that have AvailableOnDevice trait - // are supported on the device. - template <typename VISITOR, typename VARIANT> - static inline RT_API_ATTRS auto visitIo(VISITOR &&visitor, VARIANT &&u) - -> decltype(visitor(std::get<0>(std::forward<VARIANT>(u)))) { - using Result = decltype(visitor(std::get<0>(std::forward<VARIANT>(u)))); - [[maybe_unused]] std::size_t index{u.index()}; - return Fortran::common::visit( - [&](auto &x) -> Result { -#if defined(RT_DEVICE_COMPILATION) - if constexpr (!AvailableOnDevice<std::decay_t<decltype(x.get())>>) { - terminateOnDevice(__FILE__, __LINE__, index); - } else { -#endif - return visitor(x); -#if defined(RT_DEVICE_COMPILATION) - } -#endif - }, - std::forward<VARIANT>(u)); - } - std::variant<Fortran::common::reference_wrapper<OpenStatementState>, Fortran::common::reference_wrapper<CloseStatementState>, Fortran::common::reference_wrapper<NoopStatementState>, @@ -351,7 +296,6 @@ template <> class ListDirectedStatementState<Direction::Output> : public FormattedIoStatementState<Direction::Output> { public: - using AvailableOnDevice = std::true_type; bool EmitLeadingSpaceOrAdvance( IoStatementState &, std::size_t = 1, bool isCharacter = false); Fortran::common::optional<DataEdit> GetNextDataEdit( @@ -370,7 +314,6 @@ template <> class ListDirectedStatementState<Direction::Input> : public FormattedIoStatementState<Direction::Input> { public: - using AvailableOnDevice = std::false_type; bool inNamelistSequence() const { return inNamelistSequence_; } int EndIoStatement(); @@ -408,8 +351,6 @@ template <Direction DIR> class InternalIoStatementState : public IoStatementBase, public IoDirectionState<DIR> { public: - using AvailableOnDevice = std::conditional_t<DIR == Direction::Output, - std::true_type, std::false_type>; using Buffer = std::conditional_t<DIR == Direction::Input, const char *, char *>; InternalIoStatementState(Buffer, std::size_t, @@ -438,8 +379,6 @@ class InternalFormattedIoStatementState : public InternalIoStatementState<DIR>, public FormattedIoStatementState<DIR> { public: - using AvailableOnDevice = std::conditional_t<DIR == Direction::Output, - std::true_type, std::false_type>; using CharType = CHAR; using typename InternalIoStatementState<DIR>::Buffer; InternalFormattedIoStatementState(Buffer internal, std::size_t internalLength, @@ -468,8 +407,6 @@ template <Direction DIR> class InternalListIoStatementState : public InternalIoStatementState<DIR>, public ListDirectedStatementState<DIR> { public: - using AvailableOnDevice = std::conditional_t<DIR == Direction::Output, - std::true_type, std::false_type>; using typename InternalIoStatementState<DIR>::Buffer; InternalListIoStatementState(Buffer internal, std::size_t internalLength, const char *sourceFile = nullptr, int sourceLine = 0); @@ -487,7 +424,6 @@ private: class ExternalIoStatementBase : public IoStatementBase { public: - using AvailableOnDevice = std::false_type; ExternalIoStatementBase( ExternalFileUnit &, const char *sourceFile = nullptr, int sourceLine = 0); ExternalFileUnit &unit() { return unit_; } @@ -508,7 +444,6 @@ template <Direction DIR> class ExternalIoStatementState : public ExternalIoStatementBase, public IoDirectionState<DIR> { public: - using AvailableOnDevice = std::false_type; ExternalIoStatementState( ExternalFileUnit &, const char *sourceFile = nullptr, int sourceLine = 0); MutableModes &mutableModes() { return mutableModes_; } @@ -535,7 +470,6 @@ class ExternalFormattedIoStatementState : public ExternalIoStatementState<DIR>, public FormattedIoStatementState<DIR> { public: - using AvailableOnDevice = std::false_type; using CharType = CHAR; ExternalFormattedIoStatementState(ExternalFileUnit &, const CharType *format, std::size_t formatLength, const Descriptor *formatDescriptor = nullptr, @@ -555,7 +489,6 @@ template <Direction DIR> class ExternalListIoStatementState : public ExternalIoStatementState<DIR>, public ListDirectedStatementState<DIR> { public: - using AvailableOnDevice = std::false_type; using ExternalIoStatementState<DIR>::ExternalIoStatementState; using ListDirectedStatementState<DIR>::GetNextDataEdit; int EndIoStatement(); @@ -565,7 +498,6 @@ template <Direction DIR> class ExternalUnformattedIoStatementState : public ExternalIoStatementState<DIR> { public: - using AvailableOnDevice = std::false_type; using ExternalIoStatementState<DIR>::ExternalIoStatementState; bool Receive(char *, std::size_t, std::size_t elementBytes = 0); }; @@ -574,7 +506,6 @@ template <Direction DIR> class ChildIoStatementState : public IoStatementBase, public IoDirectionState<DIR> { public: - using AvailableOnDevice = std::false_type; ChildIoStatementState( ChildIo &, const char *sourceFile = nullptr, int sourceLine = 0); ChildIo &child() { return child_; } @@ -595,7 +526,6 @@ template <Direction DIR, typename CHAR> class ChildFormattedIoStatementState : public ChildIoStatementState<DIR>, public FormattedIoStatementState<DIR> { public: - using AvailableOnDevice = std::false_type; using CharType = CHAR; ChildFormattedIoStatementState(ChildIo &, const CharType *format, std::size_t formatLength, const Descriptor *formatDescriptor = nullptr, @@ -618,7 +548,6 @@ template <Direction DIR> class ChildListIoStatementState : public ChildIoStatementState<DIR>, public ListDirectedStatementState<DIR> { public: - using AvailableOnDevice = std::false_type; using ChildIoStatementState<DIR>::ChildIoStatementState; using ListDirectedStatementState<DIR>::GetNextDataEdit; int EndIoStatement(); @@ -627,7 +556,6 @@ public: template <Direction DIR> class ChildUnformattedIoStatementState : public ChildIoStatementState<DIR> { public: - using AvailableOnDevice = std::false_type; using ChildIoStatementState<DIR>::ChildIoStatementState; bool Receive(char *, std::size_t, std::size_t elementBytes = 0); }; @@ -635,7 +563,6 @@ public: // OPEN class OpenStatementState : public ExternalIoStatementBase { public: - using AvailableOnDevice = std::false_type; OpenStatementState(ExternalFileUnit &unit, bool wasExtant, bool isNewUnit, const char *sourceFile = nullptr, int sourceLine = 0) : ExternalIoStatementBase{unit, sourceFile, sourceLine}, @@ -667,7 +594,6 @@ private: class CloseStatementState : public ExternalIoStatementBase { public: - using AvailableOnDevice = std::false_type; CloseStatementState(ExternalFileUnit &unit, const char *sourceFile = nullptr, int sourceLine = 0) : ExternalIoStatementBase{unit, sourceFile, sourceLine} {} @@ -682,7 +608,6 @@ private: // and recoverable BACKSPACE(bad unit) class NoUnitIoStatementState : public IoStatementBase { public: - using AvailableOnDevice = std::false_type; IoStatementState &ioStatementState() { return ioStatementState_; } MutableModes &mutableModes() { return connection_.modes; } ConnectionState &GetConnectionState() { return connection_; } @@ -705,7 +630,6 @@ private: class NoopStatementState : public NoUnitIoStatementState { public: - using AvailableOnDevice = std::false_type; NoopStatementState( const char *sourceFile = nullptr, int sourceLine = 0, int unitNumber = -1) : NoUnitIoStatementState{*this, sourceFile, sourceLine, unitNumber} {} @@ -750,7 +674,6 @@ extern template class FormatControl< class InquireUnitState : public ExternalIoStatementBase { public: - using AvailableOnDevice = std::false_type; InquireUnitState(ExternalFileUnit &unit, const char *sourceFile = nullptr, int sourceLine = 0); bool Inquire(InquiryKeywordHash, char *, std::size_t); @@ -761,7 +684,6 @@ public: class InquireNoUnitState : public NoUnitIoStatementState { public: - using AvailableOnDevice = std::false_type; InquireNoUnitState(const char *sourceFile = nullptr, int sourceLine = 0, int badUnitNumber = -1); bool Inquire(InquiryKeywordHash, char *, std::size_t); @@ -772,7 +694,6 @@ public: class InquireUnconnectedFileState : public NoUnitIoStatementState { public: - using AvailableOnDevice = std::false_type; InquireUnconnectedFileState(OwningPtr<char> &&path, const char *sourceFile = nullptr, int sourceLine = 0); bool Inquire(InquiryKeywordHash, char *, std::size_t); @@ -787,7 +708,6 @@ private: class InquireIOLengthState : public NoUnitIoStatementState, public OutputStatementState { public: - using AvailableOnDevice = std::false_type; InquireIOLengthState(const char *sourceFile = nullptr, int sourceLine = 0); std::size_t bytes() const { return bytes_; } bool Emit(const char *, std::size_t bytes, std::size_t elementBytes = 0); @@ -798,7 +718,6 @@ private: class ExternalMiscIoStatementState : public ExternalIoStatementBase { public: - using AvailableOnDevice = std::false_type; enum Which { Flush, Backspace, Endfile, Rewind, Wait }; ExternalMiscIoStatementState(ExternalFileUnit &unit, Which which, const char *sourceFile = nullptr, int sourceLine = 0) @@ -812,7 +731,6 @@ private: class ErroneousIoStatementState : public IoStatementBase { public: - using AvailableOnDevice = std::false_type; explicit ErroneousIoStatementState(Iostat iostat, ExternalFileUnit *unit = nullptr, const char *sourceFile = nullptr, int sourceLine = 0) diff --git a/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn index 7c00aaf..93976d3 100644 --- a/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn @@ -256,6 +256,7 @@ copy("Headers") { "ppc_wrappers/xmmintrin.h", "prfchiintrin.h", "prfchwintrin.h", + "ptrauth.h", "ptwriteintrin.h", "raointintrin.h", "rdpruintrin.h", |