From e815d37c2545086be0a64159f0e543d43ad5b916 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 22 Mar 2022 08:59:02 +0100 Subject: [PATCH 1/4] pform_make_var_init(): Remove unnecessary signal look-up by name `pform_make_var_init()` calls `pform_get_wire_in_scope()` but never uses the result other than checking that the signal exists. But we already know that the signal exists since we only call `pform_make_var_init()` for a freshly created signal. Remove the unnecessary signal look-up by name. Signed-off-by: Lars-Peter Clausen --- pform.cc | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pform.cc b/pform.cc index 3b2b0a1f1..a1136ab4f 100644 --- a/pform.cc +++ b/pform.cc @@ -2536,13 +2536,6 @@ void pform_make_var_init(const struct vlltype&li, return; } - PWire*cur = pform_get_wire_in_scope(name); - if (cur == 0) { - VLerror(li, "internal error: var_init to non-register?"); - delete expr; - return; - } - PEIdent*lval = new PEIdent(name); FILE_NAME(lval, li); PAssign*ass = new PAssign(lval, expr, !gn_system_verilog()); From 135c664adf51edaa7d40c3e6df0ea2e8cfeb3374 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 18 Apr 2022 11:01:54 +0200 Subject: [PATCH 2/4] pform_set_net_range(): Avoid signal look-up by name The `pform_set_net_range()` function currently looks up a signal by name. But in all places where it is called the reference to the signal is already available. Refactor the code to pass the signal itself, rather than the signal name, to `pform_set_net_range()`. This allows to skip the look-up by name. Signed-off-by: Lars-Peter Clausen --- pform.cc | 51 +++++++++++++++++---------------------------------- 1 file changed, 17 insertions(+), 34 deletions(-) diff --git a/pform.cc b/pform.cc index a1136ab4f..b1af4d61b 100644 --- a/pform.cc +++ b/pform.cc @@ -2151,42 +2151,22 @@ void pform_make_udp(const struct vlltype&loc, perm_string name, * only called by the parser within the scope of the net declaration, * and the name that I receive only has the tail component. */ -static void pform_set_net_range(perm_string name, +static void pform_set_net_range(PWire *wire, const list*range, bool signed_flag, - PWSRType rt, - std::list*attr) + PWSRType rt = SR_NET, + std::list*attr = 0) { - PWire*cur = pform_get_wire_in_scope(name); - if (cur == 0) { - VLerror("error: name is not a valid net."); - return; - } - if (range == 0) { /* This is the special case that we really mean a scalar. Set a fake range. */ - cur->set_range_scalar(rt); - + wire->set_range_scalar(rt); } else { - cur->set_range(*range, rt); - } - cur->set_signed(signed_flag); - - pform_bind_attributes(cur->attributes, attr, true); -} - -static void pform_set_net_range(list*names, - list*range, - bool signed_flag, - std::list*attr) -{ - for (list::iterator cur = names->begin() - ; cur != names->end() ; ++ cur ) { - perm_string txt = *cur; - pform_set_net_range(txt, range, signed_flag, SR_NET, attr); + wire->set_range(*range, rt); } + wire->set_signed(signed_flag); + pform_bind_attributes(wire->attributes, attr, true); } /* @@ -3288,8 +3268,8 @@ extern void pform_module_specify_path(PSpecPath*obj) } -static void pform_set_port_type(const struct vlltype&li, - perm_string name, NetNet::PortType pt) +static PWire *pform_set_port_type(const struct vlltype&li, + perm_string name, NetNet::PortType pt) { PWire*cur = pform_get_wire_in_scope(name); if (cur == 0) { @@ -3313,6 +3293,7 @@ static void pform_set_port_type(const struct vlltype&li, break; } + return cur; } void pform_set_port_type(const struct vlltype&li, @@ -3337,8 +3318,8 @@ void pform_set_port_type(const struct vlltype&li, for (list::iterator cur = ports->begin() ; cur != ports->end() ; ++ cur ) { - pform_set_port_type(li, cur->name, pt); - pform_set_net_range(cur->name, range, signed_flag, SR_PORT, attr); + PWire *wire = pform_set_port_type(li, cur->name, pt); + pform_set_net_range(wire, range, signed_flag, SR_PORT, attr); if (cur->udims) { cerr << li << ": warning: " << "Array dimensions in incomplete port declarations " @@ -3381,9 +3362,8 @@ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, listbase_type; - if (vector_type_t*vec_type = dynamic_cast (data_type)) { - pform_set_net_range(names, vec_type->pdims.get(), - vec_type->signed_flag, 0); + vector_type_t*vec_type = dynamic_cast (data_type); + if (vec_type) { vt = vec_type->base_type; } @@ -3404,6 +3384,9 @@ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, listend() ; ++ cur ) { PWire*wire = pform_get_wire_in_scope(*cur); + if (vec_type) + pform_set_net_range(wire, vec_type->pdims.get(), vec_type->signed_flag); + // If these fail there is a bug somewhere else. pform_set_data_type() // is only ever called on a fresh wire that already exists. ivl_assert(li, wire); From 254e9dc094ccb2788122f8fef77b26b4e2d97a48 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 17 Apr 2022 20:57:03 +0200 Subject: [PATCH 3/4] pform_set_data_type(): Avoid signal look-up by name The `pform_set_data_type()` function is used to set the data type as well as attributes on a list of signals. Currently the signals are passed as a list of signal names and then the function looks up the actual signals from the names. Refactor the code to directly pass a list of signals. This will allow to skip the look-up by name. Signed-off-by: Lars-Peter Clausen --- parse.y | 22 +++++++++++----------- pform.cc | 28 ++++++++++++++++------------ pform.h | 14 +++++++++----- 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/parse.y b/parse.y index 0bc3c11c6..9ce602dd8 100644 --- a/parse.y +++ b/parse.y @@ -603,9 +603,12 @@ static void current_function_set_statement(const YYLTYPE&loc, std::vector udp_initial udp_init_opt %type udp_initial_expr_opt -%type net_variable event_variable label_opt class_declaration_endlabel_opt +%type net_variable +%type net_variable_list + +%type event_variable label_opt class_declaration_endlabel_opt %type block_identifier_opt -%type net_variable_list event_variable_list +%type event_variable_list %type list_of_identifiers loop_variables %type list_of_port_identifiers list_of_variable_port_identifiers @@ -5833,23 +5836,20 @@ dimensions net_variable : IDENTIFIER dimensions_opt { perm_string name = lex_strings.make($1); - pform_makewire(@1, name, NetNet::IMPLICIT, IVL_VT_NO_TYPE, $2); - $$ = $1; + $$ = pform_makewire(@1, name, NetNet::IMPLICIT, IVL_VT_NO_TYPE, $2); + delete [] $1; } ; net_variable_list : net_variable - { std::list*tmp = new std::list; - tmp->push_back(lex_strings.make($1)); + { std::vector *tmp = new std::vector; + tmp->push_back($1); $$ = tmp; - delete[]$1; } | net_variable_list ',' net_variable - { std::list*tmp = $1; - tmp->push_back(lex_strings.make($3)); - $$ = tmp; - delete[]$3; + { $1->push_back($3); + $$ = $1; } ; diff --git a/pform.cc b/pform.cc index b1af4d61b..5259b0ac8 100644 --- a/pform.cc +++ b/pform.cc @@ -2714,8 +2714,8 @@ static PWire* pform_get_or_make_wire(const vlltype&li, perm_string name, * the variable/net. Other forms of pform_makewire ultimately call * this one to create the wire and stash it. */ -void pform_makewire(const vlltype&li, perm_string name, NetNet::Type type, - ivl_variable_type_t dt, std::list *indices) +PWire *pform_makewire(const vlltype&li, perm_string name, NetNet::Type type, + ivl_variable_type_t dt, std::list *indices) { PWire*cur = pform_get_or_make_wire(li, name, type, NetNet::NOT_A_PORT, dt); @@ -2741,6 +2741,8 @@ void pform_makewire(const vlltype&li, perm_string name, NetNet::Type type, if (indices && !indices->empty()) cur->set_unpacked_idx(*indices); + + return cur; } void pform_makewire(const struct vlltype&li, @@ -2756,16 +2758,17 @@ void pform_makewire(const struct vlltype&li, return; } - list*names = new list; + std::vector *wires = new std::vector; for (list::iterator cur = assign_list->begin() ; cur != assign_list->end() ; ++ cur) { decl_assignment_t* curp = *cur; - pform_makewire(li, curp->name, type, IVL_VT_NO_TYPE, &curp->index); - names->push_back(curp->name); + PWire *wire = pform_makewire(li, curp->name, type, IVL_VT_NO_TYPE, + &curp->index); + wires->push_back(wire); } - pform_set_data_type(li, data_type, names, type, attr); + pform_set_data_type(li, data_type, wires, type, attr); while (! assign_list->empty()) { decl_assignment_t*first = assign_list->front(); @@ -3350,7 +3353,9 @@ void pform_set_port_type(const struct vlltype&li, * This function detects the derived class for the given type and * dispatches the type to the proper subtype function. */ -void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list*names, NetNet::Type net_type, list*attr) +void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, + std::vector *wires, NetNet::Type net_type, + list*attr) { ivl_variable_type_t vt; if (data_type == 0) { @@ -3380,16 +3385,15 @@ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, listfigure_packed_base_type(); } - for (list::iterator cur = names->begin() - ; cur != names->end() ; ++ cur ) { - PWire*wire = pform_get_wire_in_scope(*cur); + for (std::vector::iterator it= wires->begin(); + it != wires->end() ; ++it) { + PWire *wire = *it; if (vec_type) pform_set_net_range(wire, vec_type->pdims.get(), vec_type->signed_flag); // If these fail there is a bug somewhere else. pform_set_data_type() // is only ever called on a fresh wire that already exists. - ivl_assert(li, wire); bool rc = wire->set_wire_type(net_type); ivl_assert(li, rc); rc = wire->set_data_type(vt); @@ -3404,7 +3408,7 @@ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, listattributes, attr, true); } - delete names; + delete wires; } vector* pform_make_udp_input_ports(list*names) diff --git a/pform.h b/pform.h index dbdf189f0..d2901ef4f 100644 --- a/pform.h +++ b/pform.h @@ -347,10 +347,10 @@ extern PForeach* pform_make_foreach(const struct vlltype&loc, * The makewire functions announce to the pform code new wires. These * go into a module that is currently opened. */ -extern void pform_makewire(const struct vlltype&li, perm_string name, - NetNet::Type type, - ivl_variable_type_t dt, - std::list *indices); +extern PWire *pform_makewire(const struct vlltype&li, perm_string name, + NetNet::Type type, + ivl_variable_type_t dt, + std::list *indices); /* This form handles assignment declarations. */ @@ -380,7 +380,11 @@ extern void pform_set_port_type(const struct vlltype&li, data_type_t*dt, std::list*attr); -extern void pform_set_data_type(const struct vlltype&li, data_type_t*, std::list*names, NetNet::Type net_type, std::list*attr); +extern void pform_set_data_type(const struct vlltype&li, + data_type_t *data_type, + std::vector *wires, + NetNet::Type net_type, + std::list*attr); extern void pform_set_string_type(const struct vlltype&li, const string_type_t*string_type, std::list*names, NetNet::Type net_type, std::list*attr); From d4e862dc4e728fffa88fe68270293b2b971ff359 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 18 Apr 2022 03:47:58 +0200 Subject: [PATCH 4/4] pform_attach_discipline(): Avoid signal look-up by name The `pform_attach_discipline()` function creates a signal using `pform_makewire()` and then looks it up by name. `pform_makewire()` now returns the signal, so use that directly and skip the look-up by name. Signed-off-by: Lars-Peter Clausen --- pform_disciplines.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pform_disciplines.cc b/pform_disciplines.cc index c0fd6d074..3e83233ce 100644 --- a/pform_disciplines.cc +++ b/pform_disciplines.cc @@ -195,8 +195,7 @@ void pform_attach_discipline(const struct vlltype&loc, PWire* cur_net = pform_get_wire_in_scope(*cur); if (cur_net == 0) { /* Not declared yet, declare it now. */ - pform_makewire(loc, *cur, NetNet::WIRE, IVL_VT_REAL, 0); - cur_net = pform_get_wire_in_scope(*cur); + cur_net = pform_makewire(loc, *cur, NetNet::WIRE, IVL_VT_REAL, 0); assert(cur_net); }