[flang] Commit changes made while at Portland. Some of them will disapear

Original-commit: flang-compiler/f18@0972ffe185
Reviewed-on: https://github.com/flang-compiler/f18/pull/24
Tree-same-pre-rewrite: false
This commit is contained in:
Stephane Chauveau 2018-03-26 01:04:40 -07:00 committed by GitHub
parent a7cf13c738
commit eb766702f1
7 changed files with 149 additions and 89 deletions

View File

@ -4,8 +4,7 @@
#include <string>
#include <optional>
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<std::string>
static const Identifier *get(std::optional<std::string> n) {
return n ? Identifier::get(n.value()) : nullptr ;
}
};
#endif
} // namespace semantics
} // namespace Fortran
#endif
#endif // of FLANG_SEMA_IDENTIFIER_H

View File

@ -238,4 +238,4 @@ public:
} // namespace Fortran::semantics
#endif // FLANG_SEMA_SCOPE_H
#endif // of FLANG_SEMA_SCOPE_H

View File

@ -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<Entry> entries_;
std::map<Index, int> 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

View File

@ -62,4 +62,4 @@ constexpr const char *StmtClassText(StmtClass sc) {
} // end of namespace Fortran::semantics
#endif
#endif // of FLANG_SEMA_STMT_H

View File

@ -317,4 +317,4 @@ private:
// NOTE: Support for EQUIVALENCE ...
#endif
#endif // of FLANG_SEMA_SYMBOL_H

View File

@ -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;
// }

View File

@ -92,6 +92,20 @@ template <typename T> sm::Semantic<T> & getSema(const T &node) {
#include <string>
#include <stddef.h>
// 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<std::list<Statement<Indirection<UseStmt>>>&>(const_use_list);
// Using unconst:
// auto &uses = unconst(const_uses);
//
static inline template <typename T> T& unconst(const T&x) {
return std::const_cast<T&>(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<SpecificationPart>(x.t) ;
auto &const_decl_list = std::get< std::list<DeclarationConstruct> >(specif_part.t);
// Reminder: ExecutionPart = std::list<ExecutionPartConstruct>
auto &const_exec_list = std::get< std::list<ExecutionPartConstruct> >(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<Indirection<StmtFunctionStmt>>> StmtFunctionStmt_type;
while (true) {
if (decl_list.empty())
break ;
DeclarationConstruct &last = decl_list.back() ;
if ( ! std::holds_alternative<StmtFunctionStmt_type>(last.v) )
break ;
auto & func_stmt = GetValue( std::get<StmtFunctionStmt_type>(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<SectionSubscript> 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) {