Skip to content

Commit 4cc9e6a

Browse files
committed
Optimize _remove_double_inverts
1 parent c68d016 commit 4cc9e6a

1 file changed

Lines changed: 17 additions & 19 deletions

File tree

pyrtl/passes.py

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def optimize(update_working_block=True, block=None, skip_sanity_check=False):
6161
def _remove_double_inverts(block, skip_sanity_check=False):
6262
""" Removes all double invert nets from the block. """
6363

64-
# checks if the wirevector is used at a LogicNet other than used_at_net
64+
# checks if the wirevector is used at a LogicNet other than used_at_nets
6565
def is_wirevector_used_elsewhere(wire, used_at_nets):
6666
for net in block.logic:
6767
if net not in used_at_nets:
@@ -73,24 +73,22 @@ def is_wirevector_used_elsewhere(wire, used_at_nets):
7373
new_logic = set()
7474
net_exclude_set = set() # removed nets
7575
wire_removal_set = set()
76-
for net1 in block.logic:
77-
for net2 in block.logic:
78-
# Conditions need to be satisfied for the nets to be removed:
79-
# 1. Both nets should be invert nets
80-
# 2. Nets should not be in net_exclude_set (nets that are already removed)
81-
# 3. The destination of net1 should be the argument of net2
82-
# (so we know the nets are connected)
83-
# 4. The destination of net1 should not be used elsewhere
84-
# (because we can't remove a wire that is used in another net)
85-
if net1.op == '~' and net2.op == '~' \
86-
and net1 not in net_exclude_set and net2 not in net_exclude_set \
87-
and net1.dests[0].name == net2.args[0].name \
88-
and not is_wirevector_used_elsewhere(net1.dests[0], (net1, net2)):
89-
new_logic.add(LogicNet('w', None, args=net1.args, dests=net2.dests))
90-
net_exclude_set.add(net1)
91-
net_exclude_set.add(net2)
92-
wire_removal_set.add(net1.dests[0])
93-
break
76+
# Dictionary, key is the destination wire of the invert net, value is the invert net
77+
invert_destination_wires = {}
78+
for net in block.logic:
79+
if net.op == "~":
80+
invert_destination_wires[net.dests[0].name] = net
81+
for net in invert_destination_wires.values():
82+
# If the argument of the net is in invert_destination_wires, then it is a double invert
83+
# If the net is in net_exclude_set, then it was already removed, so we do not process it
84+
if net.args[0].name in invert_destination_wires and net not in net_exclude_set:
85+
previous_net = invert_destination_wires[net.args[0].name]
86+
if not is_wirevector_used_elsewhere(net.args[0], (net, previous_net)) \
87+
and previous_net not in net_exclude_set:
88+
new_logic.add(LogicNet('w', None, args=previous_net.args, dests=net.dests))
89+
wire_removal_set.add(net.args[0])
90+
net_exclude_set.add(net)
91+
net_exclude_set.add(previous_net)
9492

9593
for net in block.logic:
9694
if net not in net_exclude_set:

0 commit comments

Comments
 (0)