From 4fd1e5d795dadc7c7a9f21cb28462d01dcd02d4b Mon Sep 17 00:00:00 2001 From: Eric Schweitz Date: Fri, 8 Mar 2019 08:26:37 -0800 Subject: [PATCH] [flang] Address review comments; merge with latest breaking changes on master Original-commit: flang-compiler/f18@ffde96d4866c25c3267332963363d4b6c523325d Reviewed-on: https://github.com/flang-compiler/f18/pull/319 --- flang/lib/FIR/CMakeLists.txt | 1 - flang/lib/FIR/afforestation.cc | 112 +++++++++++++++++++++++---------------- flang/lib/FIR/mixin.h | 13 +++++ flang/lib/semantics/expression.h | 6 --- 4 files changed, 78 insertions(+), 54 deletions(-) diff --git a/flang/lib/FIR/CMakeLists.txt b/flang/lib/FIR/CMakeLists.txt index 011aa26..18b360e 100644 --- a/flang/lib/FIR/CMakeLists.txt +++ b/flang/lib/FIR/CMakeLists.txt @@ -26,5 +26,4 @@ add_library(FortranFIR target_link_libraries(FortranFIR FortranCommon - clangBasic ) diff --git a/flang/lib/FIR/afforestation.cc b/flang/lib/FIR/afforestation.cc index 9b1744d..0d942d0 100644 --- a/flang/lib/FIR/afforestation.cc +++ b/flang/lib/FIR/afforestation.cc @@ -23,10 +23,31 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/raw_ostream.h" +namespace Fortran::howdowedothis { + +// need to be able to convert variable-like things to Expressions, or forego +// using Expressions entirely. The .typedExpr data member is only on +// parser::Expr nodes, which is not sufficient. + +semantics::MaybeExpr AnalyzeVariable( + semantics::SemanticsContext &context, const parser::Variable &var) { + return {}; +} +semantics::MaybeExpr AnalyzeName( + semantics::SemanticsContext &context, const parser::Name &name) { + return {}; +} +semantics::MaybeExpr AnalyzeDataRef( + semantics::SemanticsContext &context, const parser::DataRef &dataRef) { + return {}; +} +} + namespace Fortran::FIR { namespace { -template Expression *ExprRef(const A &a) { - return &a.typedExpr.value(); +Expression *ExprRef(const parser::Expr &a) { return &a.typedExpr.value(); } +Expression *ExprRef(const common::Indirection &a) { + return &a.value().typedExpr.value(); } struct LinearOp; @@ -914,15 +935,15 @@ static std::vector populateSwitchValues( if (range.lower.has_value()) { if (range.upper.has_value()) { valueList.emplace_back(SwitchCaseStmt::InclusiveRange{ - ExprRef(range.lower->thing.thing.value()), - ExprRef(range.upper->thing.thing.value())}); + ExprRef(range.lower->thing.thing), + ExprRef(range.upper->thing.thing)}); } else { valueList.emplace_back(SwitchCaseStmt::InclusiveAbove{ - ExprRef(range.lower->thing.thing.value())}); + ExprRef(range.lower->thing.thing)}); } } else { valueList.emplace_back(SwitchCaseStmt::InclusiveBelow{ - ExprRef(range.upper->thing.thing.value())}); + ExprRef(range.upper->thing.thing)}); } }, }, @@ -983,6 +1004,7 @@ static std::vector populateSwitchValues( } return result; } + static SwitchCaseArguments ComposeSwitchCaseArguments( const parser::CaseConstruct *caseConstruct, const std::vector &refs) { @@ -994,6 +1016,7 @@ static SwitchCaseArguments ComposeSwitchCaseArguments( result.defLab, result.ranges, result.labels); return result; } + static SwitchRankArguments ComposeSwitchRankArguments( const parser::SelectRankConstruct *selectRankConstruct, const std::vector &refs) { @@ -1037,7 +1060,7 @@ static SwitchArguments ComposeSwitchArgs(const LinearSwitch &op) { common::visitors{ [&](const parser::ComputedGotoStmt *c) { const auto &e{std::get(c->t)}; - result.exp = ExprRef(e.thing.thing.value()); + result.exp = ExprRef(e.thing.thing); buildMultiwayDefaultNext(result); }, [&](const parser::ArithmeticIfStmt *c) { @@ -1076,6 +1099,7 @@ const parser::IoUnit *FindReadWriteIoUnit( SEMANTICS_FAILED("no UNIT spec"); return {}; } + const parser::Format *FindReadWriteFormat( const std::optional &format, const std::list &specifiers) { @@ -1086,20 +1110,14 @@ const parser::Format *FindReadWriteFormat( } static Expression AlwaysTrueExpression() { - auto result{common::SearchTypes( - evaluate::TypeKindVisitor{1, true})}; - CHECK(result.has_value()); - return {std::move(*result)}; + using T = evaluate::Type; + return {evaluate::AsGenericExpr(evaluate::Constant{true})}; } // create an integer constant as an expression -static Expression CreateConstant(int value) { - auto result{common::SearchTypes( - evaluate::TypeKindVisitor{value, true})}; - CHECK(result.has_value()); - return {std::move(*result)}; +static Expression CreateConstant(int64_t value) { + using T = evaluate::SubscriptInteger; + return {evaluate::AsGenericExpr(evaluate::Constant{value})}; } static void CreateSwitchHelper(FIRBuilder *builder, const Evaluation &condition, @@ -1345,16 +1363,16 @@ public: } Expression VariableToExpression(const parser::Variable &var) { - auto maybe{semantics::AnalyzeVariable(semanticsContext_, var)}; - return {std::move(*maybe)}; + auto maybe{howdowedothis::AnalyzeVariable(semanticsContext_, var)}; + return {std::move(maybe.value())}; } Expression DataRefToExpression(const parser::DataRef &dr) { - auto maybe{semantics::AnalyzeDataRef(semanticsContext_, dr)}; - return {std::move(*maybe)}; + auto maybe{howdowedothis::AnalyzeDataRef(semanticsContext_, dr)}; + return {std::move(maybe.value())}; } Expression NameToExpression(const parser::Name &name) { - auto maybe{semantics::AnalyzeName(semanticsContext_, name)}; - return {std::move(*maybe)}; + auto maybe{howdowedothis::AnalyzeName(semanticsContext_, name)}; + return {std::move(maybe.value())}; } void handleIntrinsicAssignmentStmt(const parser::AssignmentStmt &stmt) { @@ -1389,10 +1407,10 @@ public: std::visit( common::visitors{ [&](const parser::AllocOpt::Mold &m) { - opts.mold = ExprRef(m.v.value()); + opts.mold = ExprRef(m.v); }, [&](const parser::AllocOpt::Source &s) { - opts.source = ExprRef(s.v.value()); + opts.source = ExprRef(s.v); }, [&](const parser::StatOrErrmsg &var) { std::visit( @@ -1659,6 +1677,19 @@ public: void InitiateConstruct(const parser::ChangeTeamStmt *changeTeamStmt) { // FIXME } + void InitiateConstruct(const parser::IfThenStmt *ifThenStmt) { + const auto &e{std::get(ifThenStmt->t).thing}; + builder_->CreateExpr(ExprRef(e.thing)); + } + void InitiateConstruct(const parser::WhereConstructStmt *whereConstructStmt) { + const auto &e{std::get(whereConstructStmt->t)}; + builder_->CreateExpr(ExprRef(e.thing)); + } + void InitiateConstruct( + const parser::ForallConstructStmt *forallConstructStmt) { + // FIXME + } + void InitiateConstruct(const parser::NonLabelDoStmt *stmt) { auto &ctrl{std::get>(stmt->t)}; if (ctrl.has_value()) { @@ -1668,14 +1699,13 @@ public: auto *var = builder_->CreateAddr( NameToExpression(bounds.name.thing.thing)); // evaluate e1, e2 [, e3] ... - auto *e1{builder_->CreateExpr( - ExprRef(bounds.lower.thing.thing.value()))}; - auto *e2{builder_->CreateExpr( - ExprRef(bounds.upper.thing.thing.value()))}; + auto *e1{ + builder_->CreateExpr(ExprRef(bounds.lower.thing.thing))}; + auto *e2{ + builder_->CreateExpr(ExprRef(bounds.upper.thing.thing))}; Statement *e3; if (bounds.step.has_value()) { - e3 = builder_->CreateExpr( - ExprRef(bounds.step->thing.thing.value())); + e3 = builder_->CreateExpr(ExprRef(bounds.step->thing.thing)); } else { e3 = builder_->CreateExpr(CreateConstant(1)); } @@ -1708,19 +1738,6 @@ public: } } - void InitiateConstruct(const parser::IfThenStmt *ifThenStmt) { - const auto &e{std::get(ifThenStmt->t).thing}; - builder_->CreateExpr(ExprRef(e.thing.value())); - } - void InitiateConstruct(const parser::WhereConstructStmt *whereConstructStmt) { - const auto &e{std::get(whereConstructStmt->t)}; - builder_->CreateExpr(ExprRef(e.thing.value())); - } - void InitiateConstruct( - const parser::ForallConstructStmt *forallConstructStmt) { - // FIXME - } - Statement *BuildLoopLatchExpression(const parser::NonLabelDoStmt *stmt) { auto &loopCtrl{std::get>(stmt->t)}; if (loopCtrl.has_value()) { @@ -1779,8 +1796,7 @@ public: }, [&](const parser::ReturnStmt *s) { if (s->v) { - builder_->CreateReturn( - ExprRef(s->v->thing.thing.value())); + builder_->CreateReturn(ExprRef(s->v->thing.thing)); } else { builder_->CreateRetVoid(); } @@ -2110,10 +2126,12 @@ public: function(builder_, condition, defaultIter->second, cases); } } + Variable *ConvertToVariable(const semantics::Symbol *symbol) { // FIXME: how to convert semantics::Symbol to evaluate::Variable? return new Variable(symbol); } + void AddOrQueueIGoto(AnalysisData &ad, const semantics::Symbol *symbol, const std::vector &labels) { auto useLabels{labels.empty() ? GetAssign(ad, symbol) : labels}; diff --git a/flang/lib/FIR/mixin.h b/flang/lib/FIR/mixin.h index bde2895..d7d4ea4 100644 --- a/flang/lib/FIR/mixin.h +++ b/flang/lib/FIR/mixin.h @@ -15,6 +15,11 @@ #ifndef FORTRAN_FIR_MIXIN_H_ #define FORTRAN_FIR_MIXIN_H_ +// Mixin classes are "partial" classes (not used standalone) that can be used to +// add a repetitive (ad hoc) interface (and implementation) to a class. It's +// better to think of these as "included in" a class, rather than as an +// "inherited from" base class. + #include "llvm/ADT/ilist.h" #include #include @@ -25,6 +30,7 @@ namespace Fortran::FIR { inline constexpr bool has_size(std::size_t size) { return size > 0; } +// implementation of a (moveable) sum type (variant) template struct SumTypeMixin {}; template // T must be std::variant<...> struct SumTypeMixin)>> { @@ -38,6 +44,7 @@ struct SumTypeMixin)>> { T u; }; +// implementation of a copyable sum type template struct SumTypeCopyMixin {}; template // T must be std::variant<...> struct SumTypeCopyMixin)>> { @@ -58,6 +65,7 @@ struct SumTypeCopyMixin)>> { return *this; \ } +// implementation of a (moveable) product type (tuple) template struct ProductTypeMixin {}; template // T must be std::tuple<...> struct ProductTypeMixin)>> { @@ -71,6 +79,7 @@ struct ProductTypeMixin)>> { T t; }; +// implementation of a (moveable) maybe type template struct MaybeMixin {}; template // T must be std::optional<...> struct MaybeMixin struct ChildMixin { protected: P *parent; @@ -97,6 +107,7 @@ public: llvm::iplist &getList() { return parent->getSublist(this); } }; +// zip :: ([a],[b]) -> [(a,b)] template C Zip(C out, A first, A last, B other) { std::transform(first, last, other, out, @@ -105,6 +116,8 @@ C Zip(C out, A first, A last, B other) { }); return out; } + +// unzip :: [(a,b)] -> ([a],[b]) template B &Unzip(B &out, A first, A last) { std::transform(first, last, std::back_inserter(out.first), [](auto &&a) -> decltype(a.first) { return a.first; }); diff --git a/flang/lib/semantics/expression.h b/flang/lib/semantics/expression.h index 1061596..96cdd74 100644 --- a/flang/lib/semantics/expression.h +++ b/flang/lib/semantics/expression.h @@ -302,11 +302,5 @@ public: private: SemanticsContext &context_; }; - -MaybeExpr AnalyzeVariable( - SemanticsContext &context, const parser::Variable &var); -MaybeExpr AnalyzeName(SemanticsContext &context, const parser::Name &name); -MaybeExpr AnalyzeDataRef( - SemanticsContext &context, const parser::DataRef &dataRef); } // namespace Fortran::semantics #endif // FORTRAN_SEMANTICS_EXPRESSION_H_ -- 2.7.4