From: Jacob Lifshay Date: Mon, 5 Oct 2020 22:21:33 +0000 (-0700) Subject: `deepcopy` from cache instead of recreating parsers for `GardenSnakeCompiler` X-Git-Tag: 24jan2021_ls180~227 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=34ec75959ba7ff187045b17468d803b795d77dd8;p=soc.git `deepcopy` from cache instead of recreating parsers for `GardenSnakeCompiler` changes `make develop` time from about 1m30s to 1m09s for me --- diff --git a/src/soc/decoder/power_decoder.py b/src/soc/decoder/power_decoder.py index 36b57b07..028de9b3 100644 --- a/src/soc/decoder/power_decoder.py +++ b/src/soc/decoder/power_decoder.py @@ -451,7 +451,7 @@ class TopPowerDecoder(PowerDecoder): setattr(self, fname, sig) # create signals for all field forms - self.form_names = forms = self.fields.instrs.keys() + forms = self.form_names self.sigforms = {} for form in forms: fields = self.fields.instrs[form] @@ -468,6 +468,10 @@ class TopPowerDecoder(PowerDecoder): self.tree_analyse() + @property + def form_names(self): + return self.fields.instrs.keys() + def elaborate(self, platform): m = PowerDecoder.elaborate(self, platform) comb = m.d.comb diff --git a/src/soc/decoder/power_fields.py b/src/soc/decoder/power_fields.py index 02c2dc70..58df625b 100644 --- a/src/soc/decoder/power_fields.py +++ b/src/soc/decoder/power_fields.py @@ -118,9 +118,13 @@ class DecodeFields: name_on_wiki = "fields.text" self.fname = find_wiki_file(name_on_wiki) + @property + def form_names(self): + return self.instrs.keys() + def create_specs(self): self.forms, self.instrs = self.decode_fields() - self.form_names = forms = self.instrs.keys() + forms = self.form_names #print ("specs", self.forms, forms) for form in forms: fields = self.instrs[form] diff --git a/src/soc/decoder/power_fieldsn.py b/src/soc/decoder/power_fieldsn.py index eefe929e..852dd15b 100644 --- a/src/soc/decoder/power_fieldsn.py +++ b/src/soc/decoder/power_fieldsn.py @@ -2,6 +2,7 @@ from collections import OrderedDict from soc.decoder.power_fields import DecodeFields, BitRange from nmigen import Module, Elaboratable, Signal, Cat from nmigen.cli import rtlil +from copy import deepcopy class SignalBitRange(BitRange): @@ -9,6 +10,15 @@ class SignalBitRange(BitRange): BitRange.__init__(self) self.signal = signal + def __deepcopy__(self, memo): + signal = deepcopy(self.signal, memo) + retval = SignalBitRange(signal=signal) + for k, v in self.items(): + k = deepcopy(k, memo) + v = deepcopy(v, memo) + retval[k] = v + return retval + def _rev(self, k): width = self.signal.width return width-1-k diff --git a/src/soc/decoder/pseudo/parser.py b/src/soc/decoder/pseudo/parser.py index 178caa9c..1466f87c 100644 --- a/src/soc/decoder/pseudo/parser.py +++ b/src/soc/decoder/pseudo/parser.py @@ -11,6 +11,7 @@ from pprint import pprint from ply import lex, yacc import astor +from copy import deepcopy from soc.decoder.power_decoder import create_pdecode from soc.decoder.pseudo.lexer import IndentLexer @@ -865,10 +866,24 @@ class GardenSnakeParser(PowerParser): #from compiler import misc, syntax, pycodegen +_CACHED_PARSERS = {} +_CACHE_PARSERS = True + + class GardenSnakeCompiler(object): def __init__(self, debug=False, form=None, incl_carry=False): - self.parser = GardenSnakeParser(debug=debug, form=form, - incl_carry=incl_carry) + if _CACHE_PARSERS: + try: + parser = _CACHED_PARSERS[debug, form, incl_carry] + except KeyError: + parser = GardenSnakeParser(debug=debug, form=form, + incl_carry=incl_carry) + _CACHED_PARSERS[debug, form, incl_carry] = parser + + self.parser = deepcopy(parser) + else: + self.parser = GardenSnakeParser(debug=debug, form=form, + incl_carry=incl_carry) def compile(self, code, mode="exec", filename=""): tree = self.parser.parse(code)