Jason Lowe-Power has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/58436 )

Change subject: mem-ruby,scons: Split SLICC generic and specific
......................................................................

mem-ruby,scons: Split SLICC generic and specific

Update the SLICC generation to be able to generate the shared files and
protocol-specific files separately.

Update the SLICC SConscript to make a separate call to SLICC for the
shared files and the protocol-specific files.

Note: The Scons changes are a bit hacky. Improvements are welcome.

Change-Id: I516a1bbe7f82e57dc4145064170f10b31683b6cd
Signed-off-by: Jason Lowe-Power <ja...@lowepower.com>
---
M src/mem/ruby/protocol/SConscript
M src/mem/slicc/ast/DeclListAST.py
M src/mem/slicc/main.py
M src/mem/slicc/parser.py
M src/mem/slicc/symbols/SymbolTable.py
5 files changed, 117 insertions(+), 34 deletions(-)



diff --git a/src/mem/ruby/protocol/SConscript b/src/mem/ruby/protocol/SConscript
index 162c0db..550dd73 100644
--- a/src/mem/ruby/protocol/SConscript
+++ b/src/mem/ruby/protocol/SConscript
@@ -66,15 +66,23 @@
     assert len(source) == 1
     filepath = source[0].srcnode().abspath

+    if filepath.endswith('RubySlicc_interfaces.slicc'):
+        # We're working on the shared files
+        filepath = None
+        shared_only = True
+    else:
+        shared_only = False
+
     slicc = SLICC(
         filepath,
[os.path.join(protocol_base.abspath, 'RubySlicc_interfaces.slicc')],
         protocol_base.abspath,
+        shared_only=shared_only,
         verbose=False
     )
     slicc.process()
     slicc.writeCodeFiles(output_dir.abspath, slicc_includes)
-    if env['CONF']['SLICC_HTML']:
+    if env['CONF']['SLICC_HTML'] and not shared_only:
         slicc.writeHTMLFiles(html_dir.abspath)

     target.extend([output_dir.File(f) for f in sorted(slicc.files())])
@@ -83,35 +91,63 @@
 def slicc_action(target, source, env):
     assert len(source) == 1
     filepath = source[0].srcnode().abspath
+
+    if filepath.endswith('RubySlicc_interfaces.slicc'):
+        # We're working on the shared files
+        filepath = None
+        shared_only = True
+    else:
+        shared_only = False
+
     slicc = SLICC(
         filepath,
[os.path.join(protocol_base.abspath, 'RubySlicc_interfaces.slicc')],
         protocol_base.abspath,
+        shared_only=shared_only,
         verbose=True
     )
     slicc.process()
     slicc.writeCodeFiles(output_dir.abspath, slicc_includes)
-    if env['CONF']['SLICC_HTML']:
+    if env['CONF']['SLICC_HTML'] and not shared_only:
         slicc.writeHTMLFiles(html_dir.abspath)

slicc_builder = Builder(action=MakeAction(slicc_action, Transform("SLICC")),
                         emitter=slicc_emitter)

-protocol = env['CONF']['PROTOCOL']
-protocol_dir = None
-for path in env['PROTOCOL_DIRS']:
-    if os.path.exists(path.File("%s.slicc" % protocol).abspath):
-        protocol_dir = Dir(path)
-        break
-
-if not protocol_dir:
-    raise ValueError("Could not find {}.slicc in PROTOCOL_DIRS".format(
-        protocol))
-
-sources = [ protocol_dir.File("%s.slicc" % protocol) ]
-
 env.Append(BUILDERS={'SLICC' : slicc_builder})
-nodes = env.SLICC([], sources)
+
+for protocol in [env['CONF']['PROTOCOL']]:
+    if protocol == "None":
+        continue
+    protocol_dir = None
+    for path in env['PROTOCOL_DIRS']:
+        if os.path.exists(path.File("%s.slicc" % protocol).abspath):
+            protocol_dir = Dir(path)
+            break
+
+    if not protocol_dir:
+        raise ValueError("Could not find {}.slicc in PROTOCOL_DIRS".format(
+            protocol))
+
+    nodes = env.SLICC([], [protocol_dir.File("%s.slicc" % protocol)])
+    env.Depends(nodes, slicc_depends)
+
+    append = {}
+    if env['CLANG']:
+        append['CCFLAGS'] = '-Wno-parentheses'
+    for f in nodes:
+        s = str(f)
+        if s.endswith('.cc'):
+            Source(f, append=append)
+        elif s.endswith('.py'):
+            filename = os.path.basename(s)
+ # We currently only expect ${ident}_Controller.py to be generated,
+            # and for it to contain a single SimObject with the same name +
+            # protocol.
+            assert(filename.endswith('_Controller.py'))
+            SimObject(f, sim_objects=[os.path.splitext(filename)[0]])
+
+nodes = env.SLICC([], [protocol_base.File('RubySlicc_interfaces.slicc')])
 env.Depends(nodes, slicc_depends)

 append = {}
@@ -121,10 +157,3 @@
     s = str(f)
     if s.endswith('.cc'):
         Source(f, append=append)
-    elif s.endswith('.py'):
-        filename = os.path.basename(s)
- # We currently only expect ${ident}_Controller.py to be generated, and - # for it to contain a single SimObject with the same name + protocol.
-        assert(filename.endswith('_Controller.py'))
- SimObject(f, sim_objects=[protocol+'_'+os.path.splitext(filename)[0]])
-
diff --git a/src/mem/slicc/ast/DeclListAST.py b/src/mem/slicc/ast/DeclListAST.py
index e25cd50..ee65579 100644
--- a/src/mem/slicc/ast/DeclListAST.py
+++ b/src/mem/slicc/ast/DeclListAST.py
@@ -38,9 +38,10 @@
     def __repr__(self):
return "[DeclListAST: %s]" % (', '.join(repr(d) for d in self.decls))

-    def files(self, parent=None):
+    def files(self, parent=None, shared=True):
         s = set()
         for decl in self.decls:
+            if not shared and decl.shared: continue
             s |= decl.files(parent)
         return s

diff --git a/src/mem/slicc/main.py b/src/mem/slicc/main.py
index 0b82a98..24e0508 100644
--- a/src/mem/slicc/main.py
+++ b/src/mem/slicc/main.py
@@ -87,12 +87,31 @@
     protocol_base = os.path.join(os.path.dirname(__file__),
                                  '..', 'ruby', 'protocol')

+    output("Generating shared files")
+    slicc = SLICC(
+            None,
+            [os.path.join(protocol_base, 'RubySlicc_interfaces.slicc')],
+            protocol_base,
+            shared_only=True,
+            verbose=True, debug=opts.debug,
+            traceback=opts.tb
+        )
+    if opts.print_files:
+        for i in sorted(slicc.files()):
+            print('    %s' % i)
+    else:
+        output("Processing AST...")
+        slicc.process()
+        output("Writing C++ files...")
+        slicc.writeCodeFiles(opts.code_path, [])
+
     for slicc_file in files:
         output(f"Working on {slicc_file}")
         slicc = SLICC(
             slicc_file,
             [os.path.join(protocol_base, 'RubySlicc_interfaces.slicc')],
             protocol_base,
+            shared_only=False,
             verbose=True, debug=opts.debug,
             traceback=opts.tb
         )
diff --git a/src/mem/slicc/parser.py b/src/mem/slicc/parser.py
index 78a16bf..a749be0 100644
--- a/src/mem/slicc/parser.py
+++ b/src/mem/slicc/parser.py
@@ -49,8 +49,8 @@
 from slicc.symbols import SymbolTable

 class SLICC(Grammar):
-    def __init__(self, protocol, includes, base_dir, verbose=False,
-                 traceback=False, **kwargs):
+    def __init__(self, protocol, includes, base_dir, shared_only,
+                 verbose=False, traceback=False, **kwargs):
         """Entrypoint for SLICC parsing
         protocol: The protocol `.slicc` file to parse
includes: list of `.slicc` files that are shared between all protocols
@@ -60,6 +60,9 @@
         self.verbose = verbose
         self.symtab = SymbolTable(self)
         self.base_dir = base_dir
+        # If true, only emit the shared files. Otherwise, only emit the
+        # protocol-specific files
+        self.shared_only = shared_only

         if not includes:
             # raise error
@@ -72,7 +75,8 @@
             # set all of the types parsed so far as shared
             self.decl_list.setShared()

-            self.decl_list += self.parse_file(protocol, **kwargs)
+            if not shared_only:
+                self.decl_list += self.parse_file(protocol, **kwargs)
         except ParseError as e:
             if not self.traceback:
                 sys.exit(str(e))
@@ -91,15 +95,18 @@
         self.decl_list.generate()

     def writeCodeFiles(self, code_path, includes):
-        self.symtab.writeCodeFiles(code_path, includes)
+        self.symtab.writeCodeFiles(code_path, includes, self.shared_only)

     def writeHTMLFiles(self, html_path):
         self.symtab.writeHTMLFiles(html_path)

     def files(self):
-        f = set([os.path.join(self.protocol, 'Types.hh')])
+        if self.shared_only:
+            f = set()
+        else:
+            f = set([os.path.join(self.protocol, 'Types.hh')])

-        f |= self.decl_list.files()
+        f |= self.decl_list.files(shared=self.shared_only)

         return f

diff --git a/src/mem/slicc/symbols/SymbolTable.py b/src/mem/slicc/symbols/SymbolTable.py
index d51ba18..be3147b 100644
--- a/src/mem/slicc/symbols/SymbolTable.py
+++ b/src/mem/slicc/symbols/SymbolTable.py
@@ -131,9 +131,10 @@
             if isinstance(symbol, type):
                 yield symbol

-    def writeCodeFiles(self, path, includes):
+    def writeCodeFiles(self, path, includes, shared_only=False):
         makeDir(path)
-        makeDir(os.path.join(path, self.slicc.protocol))
+        if not shared_only:
+            makeDir(os.path.join(path, self.slicc.protocol))

         code = self.codeFormatter()

@@ -147,10 +148,18 @@
                     ident = f"{self.slicc.protocol}/{ident}"
                 code('#include "mem/ruby/protocol/${{ident}}.hh"')

-        code.write(path, f"{self.slicc.protocol}/Types.hh")
+        if not shared_only:
+            code.write(path, f"{self.slicc.protocol}/Types.hh")

         for symbol in self.sym_vec:
-            symbol.writeCodeFiles(path, includes)
+            if shared_only:
+                if hasattr(symbol, 'shared') and symbol.shared:
+                    symbol.writeCodeFiles(path, includes)
+                else:
+                    symbol.writeCodeFiles(path, includes)
+            else:
+                if not hasattr(symbol, 'shared') or not symbol.shared:
+                    symbol.writeCodeFiles(path, includes)

     def writeHTMLFiles(self, path):
         makeDir(path)

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58436
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I516a1bbe7f82e57dc4145064170f10b31683b6cd
Gerrit-Change-Number: 58436
Gerrit-PatchSet: 1
Gerrit-Owner: Jason Lowe-Power <power...@gmail.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to