From 72f1e5a692a66e6255bc68de30272e3eaf01c84f Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sun, 15 Aug 2010 21:52:58 +0100 Subject: [PATCH] Add find_vars method to VHDL syntax objects Finds set of read and written variables. For use in post-processing the syntax tree for cleanup. --- tgt-vhdl/vhdl_syntax.cc | 111 ++++++++++++++++++++++++++++++++++++++++ tgt-vhdl/vhdl_syntax.hh | 30 ++++++++++- 2 files changed, 140 insertions(+), 1 deletion(-) diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index 60bd1a412..363a04736 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -255,6 +255,17 @@ void stmt_container::move_stmts_from(stmt_container *other) other->stmts_.clear(); } +void stmt_container::find_vars(vhdl_var_set_t& read, + vhdl_var_set_t& write) +{ + // Iterate over each sub-statement and find all its + // read/written variables + + for (stmt_list_t::const_iterator it = stmts_.begin(); + it != stmts_.end(); ++it) + (*it)->find_vars(read, write); +} + void stmt_container::emit(std::ostream &of, int level, bool newline) const { emit_children(of, stmts_, level, "", newline); @@ -347,6 +358,13 @@ vhdl_wait_stmt::~vhdl_wait_stmt() } +void vhdl_wait_stmt::find_vars(vhdl_var_set_t& read, + vhdl_var_set_t& write) +{ + if (expr_) + expr_->find_vars(read); +} + void vhdl_wait_stmt::emit(std::ostream &of, int level) const { of << "wait"; @@ -497,6 +515,13 @@ vhdl_expr_list::~vhdl_expr_list() } +void vhdl_expr_list::find_vars(vhdl_var_set_t& read) +{ + for (list::const_iterator it = exprs_.begin(); + it != exprs_.end(); ++it) + (*it)->find_vars(read); +} + void vhdl_expr_list::emit(std::ostream &of, int level) const { of << "("; @@ -520,6 +545,12 @@ void vhdl_pcall_stmt::emit(std::ostream &of, int level) const of << ";"; } +void vhdl_pcall_stmt::find_vars(vhdl_var_set_t& read, + vhdl_var_set_t& write) +{ + exprs_.find_vars(read); +} + vhdl_var_ref::~vhdl_var_ref() { @@ -546,6 +577,11 @@ void vhdl_var_ref::set_slice(vhdl_expr *s, int w) } } +void vhdl_var_ref::find_vars(vhdl_var_set_t& read) +{ + read.insert(this); +} + void vhdl_var_ref::emit(std::ostream &of, int level) const { of << name_; @@ -575,6 +611,11 @@ void vhdl_null_stmt::emit(std::ostream &of, int level) const emit_comment(of, level, true); } +void vhdl_fcall::find_vars(vhdl_var_set_t& read) +{ + exprs_.find_vars(read); +} + void vhdl_fcall::emit(std::ostream &of, int level) const { of << name_; @@ -586,6 +627,13 @@ vhdl_abstract_assign_stmt::~vhdl_abstract_assign_stmt() } +void vhdl_abstract_assign_stmt::find_vars(vhdl_var_set_t& read, + vhdl_var_set_t& write) +{ + write.insert(lhs_); + rhs_->find_vars(read); +} + void vhdl_nbassign_stmt::emit(std::ostream &of, int level) const { lhs_->emit(of, level); @@ -767,6 +815,21 @@ void vhdl_if_stmt::emit(std::ostream &of, int level) const of << "end if;"; } +void vhdl_if_stmt::find_vars(vhdl_var_set_t& read, + vhdl_var_set_t& write) +{ + test_->find_vars(read); + + then_part_.find_vars(read, write); + else_part_.find_vars(read, write); + + for (list::const_iterator it = elsif_parts_.begin(); + it != elsif_parts_.end(); ++it) { + (*it).test->find_vars(read); + (*it).container->find_vars(read, write); + } +} + int vhdl_expr::paren_levels(0); void vhdl_expr::open_parens(std::ostream& of) @@ -788,6 +851,11 @@ vhdl_unaryop_expr::~vhdl_unaryop_expr() } +void vhdl_unaryop_expr::find_vars(vhdl_var_set_t& read) +{ + operand_->find_vars(read); +} + void vhdl_unaryop_expr::emit(std::ostream &of, int level) const { open_parens(of); @@ -823,6 +891,13 @@ void vhdl_binop_expr::add_expr(vhdl_expr *e) operands_.push_back(e); } +void vhdl_binop_expr::find_vars(vhdl_var_set_t& read) +{ + for (list::const_iterator it = operands_.begin(); + it != operands_.end(); ++it) + (*it)->find_vars(read); +} + void vhdl_binop_expr::emit(std::ostream &of, int level) const { open_parens(of); @@ -896,6 +971,18 @@ vhdl_case_stmt::~vhdl_case_stmt() } +void vhdl_case_stmt::find_vars(vhdl_var_set_t& read, + vhdl_var_set_t& write) +{ + test_->find_vars(read); + + for (case_branch_list_t::const_iterator it = branches_.begin(); + it != branches_.end(); ++it) { + (*it)->when_->find_vars(read); + (*it)->stmts_.find_vars(read, write); + } +} + void vhdl_case_stmt::emit(std::ostream &of, int level) const { of << "case "; @@ -921,6 +1008,14 @@ vhdl_while_stmt::~vhdl_while_stmt() } +void vhdl_while_stmt::find_vars(vhdl_var_set_t& read, + vhdl_var_set_t& write) +{ + test_->find_vars(read); + + vhdl_loop_stmt::find_vars(read, write); +} + void vhdl_while_stmt::emit(std::ostream &of, int level) const { of << "while "; @@ -929,6 +1024,12 @@ void vhdl_while_stmt::emit(std::ostream &of, int level) const vhdl_loop_stmt::emit(of, level); } +void vhdl_loop_stmt::find_vars(vhdl_var_set_t& read, + vhdl_var_set_t& write) +{ + stmts_.find_vars(read, write); +} + void vhdl_loop_stmt::emit(std::ostream &of, int level) const { of << "loop"; @@ -941,6 +1042,16 @@ vhdl_for_stmt::~vhdl_for_stmt() } + +void vhdl_for_stmt::find_vars(vhdl_var_set_t& read, + vhdl_var_set_t& write) +{ + from_->find_vars(read); + to_->find_vars(write); + + vhdl_loop_stmt::find_vars(read, write); +} + void vhdl_for_stmt::emit(std::ostream &of, int level) const { of << "for " << lname_ << " in "; diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 8603e7090..ea7b7de3f 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -22,6 +22,7 @@ #define INC_VHDL_SYNTAX_HH #include +#include #include #include "vhdl_element.hh" #include "vhdl_type.hh" @@ -31,6 +32,9 @@ using namespace std; class vhdl_scope; class vhdl_entity; class vhdl_arch; +class vhdl_var_ref; + +typedef set vhdl_var_set_t; class vhdl_expr : public vhdl_element { public: @@ -48,6 +52,7 @@ public: virtual vhdl_expr *to_std_logic(); virtual vhdl_expr *to_std_ulogic(); virtual vhdl_expr *to_vector(vhdl_type_name_t name, int w); + virtual void find_vars(vhdl_var_set_t& read) const {} protected: static void open_parens(ostream& of); @@ -73,13 +78,13 @@ public: const std::string &get_name() const { return name_; } void set_name(const std::string &name) { name_ = name; } void set_slice(vhdl_expr *s, int w=0); + void find_vars(vhdl_var_set_t& read); private: std::string name_; vhdl_expr *slice_; unsigned slice_width_; }; - enum vhdl_binop_t { VHDL_BINOP_AND = 0, VHDL_BINOP_OR, @@ -121,6 +126,7 @@ public: void add_expr(vhdl_expr *e); void emit(std::ostream &of, int level) const; + void find_vars(vhdl_var_set_t& read); private: std::list operands_; vhdl_binop_t op_; @@ -140,6 +146,7 @@ public: ~vhdl_unaryop_expr(); void emit(std::ostream &of, int level) const; + void find_vars(vhdl_var_set_t& read); private: vhdl_unaryop_t op_; vhdl_expr *operand_; @@ -252,6 +259,7 @@ public: void emit(std::ostream &of, int level) const; bool empty() const { return exprs_.empty(); } void add_expr(vhdl_expr *e); + void find_vars(vhdl_var_set_t& read); private: std::list exprs_; }; @@ -268,6 +276,7 @@ public: void add_expr(vhdl_expr *e) { exprs_.add_expr(e); } void emit(std::ostream &of, int level) const; + void find_vars(vhdl_var_set_t& read); private: std::string name_; vhdl_expr_list exprs_; @@ -338,6 +347,12 @@ private: class vhdl_seq_stmt : public vhdl_element { public: virtual ~vhdl_seq_stmt() {} + + // Find all the variables that are read or written in the + // expressions within this statement + // This is used to clean up the VHDL output + virtual void find_vars(vhdl_var_set_t& read, + vhdl_var_set_t& write) = 0; }; @@ -353,6 +368,7 @@ public: void move_stmts_from(stmt_container *other); void emit(std::ostream &of, int level, bool newline=true) const; bool empty() const { return stmts_.empty(); } + void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write); typedef std::list stmt_list_t; stmt_list_t &get_stmts() { return stmts_; } @@ -371,6 +387,7 @@ public: virtual ~vhdl_abstract_assign_stmt(); void set_after(vhdl_expr *after) { after_ = after; } + void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write); protected: vhdl_var_ref *lhs_; vhdl_expr *rhs_, *after_; @@ -421,6 +438,7 @@ public: void emit(std::ostream &of, int level) const; void add_sensitivity(const std::string &s) { sensitivity_.push_back(s); } vhdl_wait_type_t get_type() const { return type_; } + void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write); private: vhdl_wait_type_t type_; vhdl_expr *expr_; @@ -431,6 +449,7 @@ private: class vhdl_null_stmt : public vhdl_seq_stmt { public: void emit(std::ostream &of, int level) const; + void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write) {} }; @@ -440,6 +459,7 @@ public: : reason_(reason) {} void emit(std::ostream &of, int level) const; + void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write) {} private: std::string reason_; }; @@ -454,6 +474,7 @@ public: stmt_container *get_else_container() { return &else_part_; } stmt_container *add_elsif(vhdl_expr *test); void emit(std::ostream &of, int level) const; + void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write); private: struct elsif { vhdl_expr *test; @@ -471,6 +492,7 @@ private: * expression part and a statement container. */ class vhdl_case_branch : public vhdl_element { + friend class vhdl_case_stmt; public: vhdl_case_branch(vhdl_expr *when) : when_(when) {} ~vhdl_case_branch(); @@ -491,6 +513,7 @@ public: void add_branch(vhdl_case_branch *b) { branches_.push_back(b); } void emit(std::ostream &of, int level) const; + void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write); private: vhdl_expr *test_; case_branch_list_t branches_; @@ -503,6 +526,8 @@ public: stmt_container *get_container() { return &stmts_; } void emit(std::ostream &of, int level) const; + virtual void find_vars(vhdl_var_set_t& read, + vhdl_var_set_t& write); private: stmt_container stmts_; }; @@ -514,6 +539,7 @@ public: ~vhdl_while_stmt(); void emit(std::ostream &of, int level) const; + void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write); private: vhdl_expr *test_; }; @@ -526,6 +552,7 @@ public: ~vhdl_for_stmt(); void emit(std::ostream &of, int level) const; + void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write); private: const char *lname_; vhdl_expr *from_, *to_; @@ -542,6 +569,7 @@ public: void emit(std::ostream &of, int level) const; void add_expr(vhdl_expr *e) { exprs_.add_expr(e); } + void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write); private: std::string name_; vhdl_expr_list exprs_;