From b7957b00ae545f007560e4089c966ae106c523a4 Mon Sep 17 00:00:00 2001 From: whitequark Date: Thu, 8 Aug 2019 10:56:23 +0000 Subject: [PATCH] hdl.ast: hash-cons ValueKey. This speeds up elaboration by ~10%. --- nmigen/hdl/ast.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/nmigen/hdl/ast.py b/nmigen/hdl/ast.py index 397f738..749b8a2 100644 --- a/nmigen/hdl/ast.py +++ b/nmigen/hdl/ast.py @@ -1256,32 +1256,33 @@ class _MappedKeySet(MutableSet, _MappedKeyCollection): class ValueKey: def __init__(self, value): self.value = Value.wrap(value) - - def __hash__(self): if isinstance(self.value, Const): - return hash(self.value.value) + self._hash = hash(self.value.value) elif isinstance(self.value, (Signal, AnyValue)): - return hash(self.value.duid) + self._hash = hash(self.value.duid) elif isinstance(self.value, (ClockSignal, ResetSignal)): - return hash(self.value.domain) + self._hash = hash(self.value.domain) elif isinstance(self.value, Operator): - return hash((self.value.op, tuple(ValueKey(o) for o in self.value.operands))) + self._hash = hash((self.value.op, tuple(ValueKey(o) for o in self.value.operands))) elif isinstance(self.value, Slice): - return hash((ValueKey(self.value.value), self.value.start, self.value.end)) + self._hash = hash((ValueKey(self.value.value), self.value.start, self.value.end)) elif isinstance(self.value, Part): - return hash((ValueKey(self.value.value), ValueKey(self.value.offset), - self.value.width, self.value.stride)) + self._hash = hash((ValueKey(self.value.value), ValueKey(self.value.offset), + self.value.width, self.value.stride)) elif isinstance(self.value, Cat): - return hash(tuple(ValueKey(o) for o in self.value.parts)) + self._hash = hash(tuple(ValueKey(o) for o in self.value.parts)) elif isinstance(self.value, ArrayProxy): - return hash((ValueKey(self.value.index), - tuple(ValueKey(e) for e in self.value._iter_as_values()))) + self._hash = hash((ValueKey(self.value.index), + tuple(ValueKey(e) for e in self.value._iter_as_values()))) elif isinstance(self.value, Sample): - return hash((ValueKey(self.value.value), self.value.clocks, self.value.domain)) + self._hash = hash((ValueKey(self.value.value), self.value.clocks, self.value.domain)) else: # :nocov: raise TypeError("Object '{!r}' cannot be used as a key in value collections" .format(self.value)) + def __hash__(self): + return self._hash + def __eq__(self, other): if type(other) is not ValueKey: return False @@ -1358,6 +1359,7 @@ class ValueSet(_MappedKeySet): class SignalKey: def __init__(self, signal): + self.signal = signal if type(signal) is Signal: self._intern = (0, signal.duid) elif type(signal) is ClockSignal: @@ -1366,7 +1368,6 @@ class SignalKey: self._intern = (2, signal.domain) else: raise TypeError("Object '{!r}' is not an nMigen signal".format(signal)) - self.signal = signal def __hash__(self): return hash(self._intern) -- 2.30.2