[𝘀𝗽𝗿] changes introduced through rebase
Created using spr 1.3.4
[skip ci]
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 @@
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 @@
}
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 @@
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 @@
#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::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::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());
+ 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.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);
- }
+ 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");
}
+ } 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::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 @@
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 @@
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 @@
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 @@
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 @@
}
bool privatize = !outerCombined;
- DataSharingProcessor dsp(converter, clauseList, eval,
+ DataSharingProcessor dsp(converter, semaCtx, clauseList, eval,
/*useDelayedPrivatization=*/true, &symTable);
if (privatize)
@@ -1575,7 +1575,7 @@
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 @@
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 @@
}
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 @@
}
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::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 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 @@
// 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 @@
}
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 @@
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 @@
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 @@
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 @@
: 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 @@
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 @@
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 @@
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 @@
: 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
"ppc_wrappers/xmmintrin.h",
"prfchiintrin.h",
"prfchwintrin.h",
+ "ptrauth.h",
"ptwriteintrin.h",
"raointintrin.h",
"rdpruintrin.h",