From eb766702f149ced116a3ec265536aabe017aa243 Mon Sep 17 00:00:00 2001 From: Stephane Chauveau Date: Mon, 26 Mar 2018 01:04:40 -0700 Subject: [PATCH] [flang] Commit changes made while at Portland. Some of them will disapear Original-commit: flang-compiler/f18@0972ffe1852257203a0c2aa32e8f1603dd1411f7 Reviewed-on: https://github.com/flang-compiler/f18/pull/24 Tree-same-pre-rewrite: false --- flang/include/flang/Sema/Identifier.h | 40 +--------- flang/include/flang/Sema/Scope.h | 2 +- flang/include/flang/Sema/StatementMap.h | 43 +++++------ flang/include/flang/Sema/Stmt.h | 2 +- flang/include/flang/Sema/Symbol.h | 2 +- flang/lib/Sema/StatementMap.cc | 50 ++++++------- flang/tools/f18/sema-impl.cc | 99 ++++++++++++++++++++++++- 7 files changed, 149 insertions(+), 89 deletions(-) diff --git a/flang/include/flang/Sema/Identifier.h b/flang/include/flang/Sema/Identifier.h index edb0ad565c0d..129b39f0b49d 100644 --- a/flang/include/flang/Sema/Identifier.h +++ b/flang/include/flang/Sema/Identifier.h @@ -4,8 +4,7 @@ #include #include -namespace Fortran { -namespace semantics { +namespace Fortran::semantics { // A class describing an identifier. @@ -87,39 +86,6 @@ public: }; +} // namespace Fortran::semantics - -#if 0 -// A class describing an identifier. -// -// For each name, there is one and only one identifier. -// -// Also, identifiers are immutable and are never destroyed. -// -// The comparison of two 'Identifier*' is expected to return -// true iff their name are identical. -// -class Identifier { -private: - Identifier(Identifier &&) = delete; - ~Identifier() = delete; - Identifier(std::string n) : name_(n) {} - -private: - std::string name_; - -public: - std::string name() const { return name_; } - static const Identifier *get(std::string n); - - // In the Parse-tree, there are a lot of optional - static const Identifier *get(std::optional n) { - return n ? Identifier::get(n.value()) : nullptr ; - } -}; -#endif - -} // namespace semantics -} // namespace Fortran - -#endif +#endif // of FLANG_SEMA_IDENTIFIER_H diff --git a/flang/include/flang/Sema/Scope.h b/flang/include/flang/Sema/Scope.h index e88442b10e9a..04566c0d746d 100644 --- a/flang/include/flang/Sema/Scope.h +++ b/flang/include/flang/Sema/Scope.h @@ -238,4 +238,4 @@ public: } // namespace Fortran::semantics -#endif // FLANG_SEMA_SCOPE_H +#endif // of FLANG_SEMA_SCOPE_H diff --git a/flang/include/flang/Sema/StatementMap.h b/flang/include/flang/Sema/StatementMap.h index 580597c2cf0a..5b394c3b400a 100644 --- a/flang/include/flang/Sema/StatementMap.h +++ b/flang/include/flang/Sema/StatementMap.h @@ -8,6 +8,7 @@ namespace Fortran::semantics { + // // A StatementMap describes the relations between statements in a program unit // and also hold information that are common to each statement (label, provenance, @@ -92,16 +93,16 @@ namespace Fortran::semantics { class StatementMap { public: typedef int Index; // should become an opaque type. - + static constexpr Index None = 0; - + private: struct Entry { StmtClass sclass; StmtGroup group; - + int label; // The label associated to the statement (1..99999) or 0 - + // Relations to other statements. Index parent; Index prev_in_body; @@ -109,14 +110,14 @@ private: Index prev_in_construct; Index next_in_construct; }; - + std::vector entries_; std::map label_do_map_; -private: - Entry &Get(Index index); - const Entry &Get(Index index) const; + + Entry &at(Index index); + const Entry &at(Index index) const; public: // Add a statement to the map. @@ -151,16 +152,16 @@ public: // void Specialize(Index index, StmtClass oldclass, StmtClass newclass); - StmtClass GetClass(Index index) const { return Get(index).sclass; } + StmtClass GetClass(Index index) const { return at(index).sclass; } - StmtGroup GetGroup(Index index) const { return Get(index).group; } + StmtGroup GetGroup(Index index) const { return at(index).group; } // Provide the numerical label associated to that statement or 0. // Be aware that labels are not necessarily unique and so cannot // be used to identify a statement within the whole map. - int GetLabel(Index index) const { return Get(index).label; } + int GetLabel(Index index) const { return at(index).label; } - Index GetParent(Index index) const { return Get(index).parent; } + Index GetParent(Index index) const { return at(index).parent; } // Dump all the statements in the map in sequence so without @@ -169,25 +170,25 @@ public: void DumpFlat(std::ostream &out, bool verbose = true) const; void DumpBody(std::ostream &out, Index index, bool rec = true, int level = 0, - bool verbose = false) const; + bool verbose = false) const; void DumpStmt(std::ostream &out, Index index, bool verbose = false) const; void Dump(std::ostream &out, Index index, bool rec = true, int level = 0, - bool verbose = false) const; - + bool verbose = false) const; + void CheckIndex(Index index) const; - + Index Next(Index index) const; Index Prev(Index index) const; - + bool EmptyBody(Index index) const; - + Index FirstInBody(Index index) const; Index LastInBody(Index index) const; - + // Functionally equivalent to LastInBody(PreviousPartOfConstruct(index)) Index LastInPreviousBody(Index index) const; Index FindPrevInConstruct(Index index, StmtClass sclass) const; - + Index FindNextInConstruct(Index index, StmtClass sclass) const; Index PrevInConstruct(Index index) const; @@ -224,4 +225,4 @@ public: } // namespace Fortran::semantics -#endif +#endif // of FLANG_SEMA_STATEMENT_MAP_H diff --git a/flang/include/flang/Sema/Stmt.h b/flang/include/flang/Sema/Stmt.h index 57d3e0f6e543..b37d9a35e8d9 100644 --- a/flang/include/flang/Sema/Stmt.h +++ b/flang/include/flang/Sema/Stmt.h @@ -62,4 +62,4 @@ constexpr const char *StmtClassText(StmtClass sc) { } // end of namespace Fortran::semantics -#endif +#endif // of FLANG_SEMA_STMT_H diff --git a/flang/include/flang/Sema/Symbol.h b/flang/include/flang/Sema/Symbol.h index b6ff9202700c..0b6c9eff489d 100644 --- a/flang/include/flang/Sema/Symbol.h +++ b/flang/include/flang/Sema/Symbol.h @@ -317,4 +317,4 @@ private: // NOTE: Support for EQUIVALENCE ... -#endif +#endif // of FLANG_SEMA_SYMBOL_H diff --git a/flang/lib/Sema/StatementMap.cc b/flang/lib/Sema/StatementMap.cc index dce0c6a1c4ae..a5e929dec2e2 100644 --- a/flang/lib/Sema/StatementMap.cc +++ b/flang/lib/Sema/StatementMap.cc @@ -16,7 +16,7 @@ namespace Fortran::semantics { -StatementMap::Entry &StatementMap::Get(Index index) { +StatementMap::Entry &StatementMap::at(Index index) { if (!(( First() <= index) && (index <= Last()))) { FAIL("Illegal Stmt index " << index << " (expect " << First() << " .." << Last() << ")"); @@ -25,7 +25,7 @@ StatementMap::Entry &StatementMap::Get(Index index) { return entries_[index - 1]; } -const StatementMap::Entry &StatementMap::Get(Index index) const { +const StatementMap::Entry &StatementMap::at(Index index) const { if (!((First() <= index) && (index <= Last()))) { FAIL("Illegal Stmt index " << index << " (expect " << First() << ".." << Last() << ")"); @@ -55,7 +55,7 @@ StatementMap::Index StatementMap::Add(StmtClass sclass, int label) { } Index prev_index = self_index - 1; - auto prev_group = Get(prev_index).group; + auto prev_group = at(prev_index).group; if (prev_group == StmtGroup::End) { // When inserting after a closed construct, do as if // that was after a single statement @@ -63,7 +63,7 @@ StatementMap::Index StatementMap::Add(StmtClass sclass, int label) { prev_group = StmtGroup::Single; } - Entry &prev = Get(prev_index); + Entry &prev = at(prev_index); if (self.group == StmtGroup::Single || self.group == StmtGroup::Start) { if (prev_group == StmtGroup::Start || prev_group == StmtGroup::Part) { @@ -90,7 +90,7 @@ StatementMap::Index StatementMap::Add(StmtClass sclass, int label) { DumpFlat(std::cerr); } assert(prev.parent != None); - Get(prev.parent).next_in_construct = self_index; + at(prev.parent).next_in_construct = self_index; self.prev_in_construct = prev.parent; } else { INTERNAL_ERROR; @@ -124,9 +124,9 @@ StatementMap::Index StatementMap::Add(StmtClass sclass, int label) { void StatementMap::AssertNextInConstruct(Index prev_index) const { if (prev_index == None) return; - auto &prev = Get(prev_index); + auto &prev = at(prev_index); if (prev.next_in_construct == None) return; - auto &next = Get(prev.next_in_construct); + auto &next = at(prev.next_in_construct); #define ORDER(A, B) (prev.sclass == StmtClass::A && next.sclass == StmtClass::B) @@ -238,7 +238,7 @@ int StatementMap::Size() const { return entries_.size(); } // // void StatementMap::Specialize( Index index, StmtClass oldc, StmtClass newc) { - Entry &self = Get(index); + Entry &self = at(index); if (self.sclass != oldc) { INTERNAL_ERROR; @@ -289,7 +289,7 @@ void StatementMap::DumpBody( void StatementMap::DumpStmt( std::ostream &out, Index index, bool verbose) const { - const auto &stmt = Get(index); + const auto &stmt = at(index); switch (stmt.group) { case StmtGroup::Single: out << "| "; break; @@ -316,7 +316,7 @@ void StatementMap::DumpStmt( void StatementMap::Dump( std::ostream &out, Index index, bool rec, int level, bool verbose) const { while (index != None) { - const auto &stmt = Get(index); + const auto &stmt = at(index); out << std::setw(4) << std::right << index << ": "; for (int i = 0; i < level; i++) @@ -339,7 +339,7 @@ void StatementMap::CheckIndex(Index index) const { } StatementMap::Index StatementMap::Next(Index index) const { - auto &e = Get(index); + auto &e = at(index); if (e.group == StmtGroup::Single) { return e.next_in_body; } else if (e.group == StmtGroup::Start) { @@ -351,7 +351,7 @@ StatementMap::Index StatementMap::Next(Index index) const { } StatementMap::Index StatementMap::Prev(Index index) const { - auto &e = Get(index); + auto &e = at(index); if (e.group == StmtGroup::Single) { return e.prev_in_body; } else if (e.group == StmtGroup::Start) { @@ -363,7 +363,7 @@ StatementMap::Index StatementMap::Prev(Index index) const { } bool StatementMap::EmptyBody(Index index) const { - auto &e = Get(index); + auto &e = at(index); if (e.group == StmtGroup::Start) { if (e.next_in_construct == None) { // The body construction is not finished yet @@ -386,7 +386,7 @@ bool StatementMap::EmptyBody(Index index) const { } StatementMap::Index StatementMap::FirstInBody(StatementMap::Index index) const { - auto &e = Get(index); + auto &e = at(index); if (e.group == StmtGroup::Start) { if (e.next_in_construct == index + 1) return None; // an empty body @@ -405,7 +405,7 @@ StatementMap::Index StatementMap::FirstInBody(StatementMap::Index index) const { StatementMap::Index StatementMap::LastInBody(StatementMap::Index index) const { CheckIndex(index); - auto &stmt = Get(index); + auto &stmt = at(index); if (stmt.group == StmtGroup::Start) { if (stmt.next_in_construct == index + 1) { return None; // empty body @@ -435,9 +435,9 @@ StatementMap::Index StatementMap::LastInBody(StatementMap::Index index) const { // Functionnally equivalent to LastInBody(PreviousPartOfConstruct(index)) StatementMap::Index StatementMap::LastInPreviousBody( StatementMap::Index index) const { - auto &stmt = Get(index); + auto &stmt = at(index); if (stmt.group == StmtGroup::Part || stmt.group == StmtGroup::End) { - auto &prev = Get(index - 1); + auto &prev = at(index - 1); if (prev.group == StmtGroup::Single) { return index - 1; } else if (prev.group == StmtGroup::End) { @@ -461,7 +461,7 @@ StatementMap::Index StatementMap::FindPrevInConstruct( while (true) { index = PrevInConstruct(index); if (index == None) return None; - if (Get(index).sclass == sclass) return index; + if (at(index).sclass == sclass) return index; } } @@ -470,13 +470,13 @@ StatementMap::Index StatementMap::FindNextInConstruct( while (true) { index = NextInConstruct(index); if (index == None) return None; - if (Get(index).sclass == sclass) return index; + if (at(index).sclass == sclass) return index; } } StatementMap::Index StatementMap::PrevInConstruct( StatementMap::Index index) const { - auto &stmt = Get(index); + auto &stmt = at(index); if (stmt.group == StmtGroup::Start) { return None; } else if (stmt.group == StmtGroup::Part) { @@ -491,7 +491,7 @@ StatementMap::Index StatementMap::PrevInConstruct( StatementMap::Index StatementMap::NextInConstruct( StatementMap::Index index) const { - auto &stmt = Get(index); + auto &stmt = at(index); if (stmt.group == StmtGroup::Start) { return stmt.next_in_construct; } else if (stmt.group == StmtGroup::Part) { @@ -508,7 +508,7 @@ StatementMap::Index StatementMap::NextInConstruct( // any of its component. StatementMap::Index StatementMap::StartOfConstruct( StatementMap::Index index) const { - auto &stmt = Get(index); + auto &stmt = at(index); if (stmt.group == StmtGroup::Start) { return index; } else if (stmt.group == StmtGroup::Part || stmt.group == StmtGroup::End) { @@ -524,7 +524,7 @@ StatementMap::Index StatementMap::StartOfConstruct( StatementMap::Index StatementMap::EndOfConstruct( StatementMap::Index index) const { while (true) { - auto &stmt = Get(index); + auto &stmt = at(index); if (stmt.group == StmtGroup::Start || stmt.group == StmtGroup::Part) { index = stmt.next_in_construct; } else if (stmt.group == StmtGroup::End) { @@ -545,7 +545,7 @@ StatementMap::Index StatementMap::EndOfConstruct( StatementMap::Index StatementMap::LastOfConstruct( StatementMap::Index index) const { while (true) { - auto &stmt = Get(index); + auto &stmt = at(index); if (stmt.group == StmtGroup::Start || stmt.group == StmtGroup::Part) { if (stmt.next_in_construct == None) return index; // end of an incomplete construct @@ -590,7 +590,7 @@ void StatementMap::VisitConstructRev( // // Set the label required to close a LabelDo // void StatementMap::SetLabelDoLabel(Index do_stmt, int label) { -// assert(Get(do_stmt).sclass == StmtClass::LabelDo); +// assert(at(do_stmt).sclass == StmtClass::LabelDo); // assert(label != 0); // label_do_map_[do_stmt] = label; // } diff --git a/flang/tools/f18/sema-impl.cc b/flang/tools/f18/sema-impl.cc index 20584aa8bcb9..8ec184de5f3e 100644 --- a/flang/tools/f18/sema-impl.cc +++ b/flang/tools/f18/sema-impl.cc @@ -92,6 +92,20 @@ template sm::Semantic & getSema(const T &node) { #include #include +// A simple convenient function to remove 'const' without having to +// make the type explicit (which can be anonoying since combined +// types can be quite long in the parse-tree) +// +// For example. +// Using std::const_cast: +// auto &uses = std::const_cast>>&>(const_use_list); +// Using unconst: +// auto &uses = unconst(const_uses); +// +static inline template T& unconst(const T&x) { + return std::const_cast(x) ; +} + namespace Fortran::semantics { @@ -1366,8 +1380,9 @@ public: current_label_=-1 ; } } + - // ========== ProgramUnit =========== + // ========== ProgramUnit =========== bool Pre(const ProgramUnit &x) { TRACE_CALL() ; @@ -1387,11 +1402,77 @@ public: void Post(const ProgramUnit &x) { TRACE_CALL() ; std::cerr << "DUMP STMT " << GetStatementMap().Size() << "\n"; - // GetStatementMap().DumpFlat(std::cerr); - //std::cerr << "========================\n"; + // GetStatementMap().DumpFlat(std::cerr); + // std::cerr << "========================\n"; GetStatementMap().Dump(std::cerr,1,true); current_smap_ = 0; + // #### rewrite StmtFunctionStmt into AssignmentStmt + + const SpecificationPart & specif_part = std::get(x.t) ; + auto &const_decl_list = std::get< std::list >(specif_part.t); + // Reminder: ExecutionPart = std::list + auto &const_exec_list = std::get< std::list >(x.t); + + // We are going to move elements from decl_list to exec_list so get rid of the const. + auto &decl_list = unconst(const_decl_list); + auto &exec_part = unconst(const_exec_part); + + // The goal is to remove some StmtFunctionStmt at the end of decl_list + // and to insert them in the same order at the begining of excl_part + // + // for instance: + // + // - Before: + // ! decl_list contains 4 elements + // integer,intent(in) :: i,n + // integer :: a,b(n),c(n) + // b(i) = i*10 ! StmtFunctionStmt + // c(i) = i*i ! StmtFunctionStmt + // ! exec_part contains 1 element + // print *, "hello" , b(1), c(1) + // + // - After: + // ! decl_list contains 2 elements + // integer,intent(in) :: i,n + // integer :: a, b(n), c(n) + // ! exec_part contains 3 element + // b(i) = i*10 + // c(i) = i*i + // print *, "hello" , b(1), c(1) + // + + // For the purpose of that experiment, convert all StmtFunctionStmt + // found at the end of decl_list. + // The final code shall be more selective. + + // A stupid alias for readability purpose + typedef Statement>> StmtFunctionStmt_type; + + while (true) { + if (decl_list.empty()) + break ; + DeclarationConstruct &last = decl_list.back() ; + if ( ! std::holds_alternative(last.v) ) + break ; + auto & func_stmt = GetValue( std::get(last.v) ) ; + + auto & funcname = unconst(func_stmt.name()); + auto & arglist = unconst(func_stmt.args()); + auto & rhs = GetValue(unconst(func_stmt.expr())); + + psr::DataReference base(???); + std::list sslist; + for ( Name &index : arglist ){ + // SectionSubscript -> Expr -> Designator -> DataReference -> Name = index + SectionSubscript ss(???); + sslist.push_back(ss); + } + psr::ArrayElement elem(base,sslist); + ExecutionPartConstruct(ExecutableConstruct(StatementActionStmt( + decl_list.pop_back() ; + } + ClearConstructNames() ; } @@ -3362,6 +3443,18 @@ public: TRACE_CALL() ; } + // =========== StmtFunctionStmt =========== + + bool Pre(const StmtFunctionStmt &x) { + TRACE_CALL() ; + InitStmt(x, StmtClass::Rewind); + return true ; + } + + void Post(const StmtFunctionStmt &x) { + TRACE_CALL() ; + } + // =========== StopStmt =========== bool Pre(const StopStmt &x) {