mem-ruby: Use shared and per-protocol SLICC files
This changes extends SLICC to understand two different kinds of slicc files: files that are protocol-specific and files that are shared or included between different protocols. Each declaration in SLICC can now be shared or not. If it is shared, then we can take a different action in the code generation (e.g., wrap in a namespace). *Developer facing change* Removes the RubySlicc_interfaces.slicc file from the SLICC includes of every protocol. Changes required: If you have a custom protocol, you will need to remove the line `include "RubySlicc_interfaces.slicc" from your .slicc file. Change-Id: Ia6c2dafe2b8fe86749a13d17daa885bddd166855 Signed-off-by: Jason Lowe-Power <jason@lowepower.com>
This commit is contained in:
committed by
Bobby R. Bruce
parent
c0f67f7388
commit
1b84fbbeae
@@ -7,6 +7,15 @@
|
||||
* It returns if the stride does not match, as opposed to issuing prefetching using the new stride --- the previous, incorrect behavior.
|
||||
* Returns if the new stride is 0, indicating multiple reads from the same cache line.
|
||||
|
||||
### Multiple Ruby Protocols in a Single Build
|
||||
|
||||
There are many developer facing / API changes to enable Ruby multiple protocols in a single build.
|
||||
The most notable changes are:
|
||||
|
||||
* Removes the RubySlicc_interfaces.slicc file from the SLICC includes of
|
||||
every protocol.
|
||||
* Changes required: If you have a custom protocol, you will need to remove the line `include "RubySlicc_interfaces.slicc"` from your .slicc file.
|
||||
|
||||
* The [behavior of the statistics `simInsts` and `simOps` has been changed](https://github.com/gem5/gem5/pull/1615).
|
||||
* They now reset to zero when m5.stats.reset() is called.
|
||||
* Previously, they incorrectly did not reset and would increase monotonically throughout the simulation.
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
protocol "MSI";
|
||||
include "RubySlicc_interfaces.slicc";
|
||||
include "MSI-msg.sm";
|
||||
include "MSI-cache.sm";
|
||||
include "MSI-dir.sm";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
protocol "GPU_VIPER";
|
||||
include "RubySlicc_interfaces.slicc";
|
||||
include "MOESI_AMD_Base-msg.sm";
|
||||
include "MOESI_AMD_Base-dir.sm";
|
||||
include "MOESI_AMD_Base-dma.sm";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
protocol "Garnet_standalone";
|
||||
include "RubySlicc_interfaces.slicc";
|
||||
include "Garnet_standalone-msg.sm";
|
||||
include "Garnet_standalone-cache.sm";
|
||||
include "Garnet_standalone-dir.sm";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
protocol "MESI_Three_Level";
|
||||
include "RubySlicc_interfaces.slicc";
|
||||
include "MESI_Two_Level-msg.sm";
|
||||
include "MESI_Three_Level-msg.sm";
|
||||
include "MESI_Three_Level-L0cache.sm";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
protocol "MESI_Three_Level_HTM";
|
||||
include "RubySlicc_interfaces.slicc";
|
||||
include "MESI_Two_Level-msg.sm";
|
||||
include "MESI_Three_Level-msg.sm";
|
||||
include "MESI_Three_Level_HTM-L0cache.sm";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
protocol "MESI_Two_Level";
|
||||
include "RubySlicc_interfaces.slicc";
|
||||
include "MESI_Two_Level-msg.sm";
|
||||
include "MESI_Two_Level-L1cache.sm";
|
||||
include "MESI_Two_Level-L2cache.sm";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
protocol "MI_example";
|
||||
include "RubySlicc_interfaces.slicc";
|
||||
include "MI_example-msg.sm";
|
||||
include "MI_example-cache.sm";
|
||||
include "MI_example-dir.sm";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
protocol "MOESI_AMD_Base";
|
||||
include "RubySlicc_interfaces.slicc";
|
||||
include "MOESI_AMD_Base-msg.sm";
|
||||
include "MOESI_AMD_Base-CorePair.sm";
|
||||
include "MOESI_AMD_Base-L3cache.sm";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
protocol "MOESI_CMP_directory";
|
||||
include "RubySlicc_interfaces.slicc";
|
||||
include "MOESI_CMP_directory-msg.sm";
|
||||
include "MOESI_CMP_directory-L1cache.sm";
|
||||
include "MOESI_CMP_directory-L2cache.sm";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
protocol "MOESI_CMP_token";
|
||||
include "RubySlicc_interfaces.slicc";
|
||||
include "MOESI_CMP_token-msg.sm";
|
||||
include "MOESI_CMP_token-L1cache.sm";
|
||||
include "MOESI_CMP_token-L2cache.sm";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
protocol "MOESI_hammer";
|
||||
include "RubySlicc_interfaces.slicc";
|
||||
include "MOESI_hammer-msg.sm";
|
||||
include "MOESI_hammer-cache.sm";
|
||||
include "MOESI_hammer-dir.sm";
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// All of the sm files that are shared between all protocols
|
||||
|
||||
include "RubySlicc_Exports.sm";
|
||||
include "RubySlicc_Types.sm";
|
||||
include "RubySlicc_Util.sm";
|
||||
|
||||
@@ -66,7 +66,12 @@ def slicc_emitter(target, source, env):
|
||||
assert len(source) == 1
|
||||
filepath = source[0].srcnode().abspath
|
||||
|
||||
slicc = SLICC(filepath, protocol_base.abspath, verbose=False)
|
||||
slicc = SLICC(
|
||||
filepath,
|
||||
[os.path.join(protocol_base.abspath, 'RubySlicc_interfaces.slicc')],
|
||||
protocol_base.abspath,
|
||||
verbose=False
|
||||
)
|
||||
slicc.process()
|
||||
slicc.writeCodeFiles(output_dir.abspath, slicc_includes)
|
||||
if env['CONF']['SLICC_HTML']:
|
||||
@@ -78,8 +83,12 @@ def slicc_emitter(target, source, env):
|
||||
def slicc_action(target, source, env):
|
||||
assert len(source) == 1
|
||||
filepath = source[0].srcnode().abspath
|
||||
|
||||
slicc = SLICC(filepath, protocol_base.abspath, verbose=True)
|
||||
slicc = SLICC(
|
||||
filepath,
|
||||
[os.path.join(protocol_base.abspath, 'RubySlicc_interfaces.slicc')],
|
||||
protocol_base.abspath,
|
||||
verbose=True
|
||||
)
|
||||
slicc.process()
|
||||
slicc.writeCodeFiles(output_dir.abspath, slicc_includes)
|
||||
if env['CONF']['SLICC_HTML']:
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
protocol "CHI";
|
||||
|
||||
include "RubySlicc_interfaces.slicc";
|
||||
include "CHI-msg.sm";
|
||||
include "CHI-cache.sm";
|
||||
include "CHI-mem.sm";
|
||||
|
||||
@@ -31,6 +31,12 @@ from slicc.ast.AST import AST
|
||||
class DeclAST(AST):
|
||||
def __init__(self, slicc, pairs=None):
|
||||
super().__init__(slicc, pairs)
|
||||
# If true, then this declaration is shared between protocols
|
||||
self.shared = False
|
||||
|
||||
def setShared(self, shared: bool):
|
||||
"""Used to mark this declaration as shared between protocols"""
|
||||
self.shared = shared
|
||||
|
||||
def files(self, parent=None):
|
||||
return set()
|
||||
|
||||
@@ -49,3 +49,12 @@ class DeclListAST(AST):
|
||||
for decl in self.decls:
|
||||
decl.findMachines()
|
||||
decl.generate()
|
||||
|
||||
def setShared(self):
|
||||
"""Mark all types in this DeclList as shared"""
|
||||
for decl in self.decls:
|
||||
decl.setShared(True)
|
||||
|
||||
def __iadd__(self, other):
|
||||
self.decls += other.decls
|
||||
return self
|
||||
|
||||
@@ -58,7 +58,12 @@ class EnumDeclAST(DeclAST):
|
||||
|
||||
# Make the new type
|
||||
t = Type(
|
||||
self.symtab, ident, self.location, self.pairs, self.state_machine
|
||||
self.symtab,
|
||||
ident,
|
||||
self.location,
|
||||
self.pairs,
|
||||
self.shared,
|
||||
self.state_machine,
|
||||
)
|
||||
self.symtab.newSymbol(t)
|
||||
|
||||
|
||||
@@ -57,7 +57,12 @@ class StateDeclAST(DeclAST):
|
||||
|
||||
# Make the new type
|
||||
t = Type(
|
||||
self.symtab, ident, self.location, self.pairs, self.state_machine
|
||||
self.symtab,
|
||||
ident,
|
||||
self.location,
|
||||
self.pairs,
|
||||
self.shared,
|
||||
self.state_machine,
|
||||
)
|
||||
self.symtab.newSymbol(t)
|
||||
|
||||
|
||||
@@ -55,7 +55,12 @@ class TypeDeclAST(DeclAST):
|
||||
|
||||
# Make the new type
|
||||
new_type = Type(
|
||||
self.symtab, ident, self.location, self.pairs, self.state_machine
|
||||
self.symtab,
|
||||
ident,
|
||||
self.location,
|
||||
self.pairs,
|
||||
self.shared,
|
||||
self.state_machine,
|
||||
)
|
||||
|
||||
if machine:
|
||||
|
||||
@@ -94,15 +94,11 @@ def main(args=None):
|
||||
parser.add_option("-q", "--quiet", help="don't print messages")
|
||||
opts, files = parser.parse_args(args=args)
|
||||
|
||||
if len(files) != 1:
|
||||
parser.print_help()
|
||||
sys.exit(2)
|
||||
|
||||
slicc_file = files[0]
|
||||
if not slicc_file.endswith(".slicc"):
|
||||
print("Must specify a .slicc file with a list of state machine files")
|
||||
parser.print_help()
|
||||
sys.exit(2)
|
||||
for slicc_file in files:
|
||||
if not slicc_file.endswith(".slicc"):
|
||||
print("Must specify a .slicc file")
|
||||
parser.print_help()
|
||||
sys.exit(2)
|
||||
|
||||
output = nprint if opts.quiet else eprint
|
||||
|
||||
@@ -112,27 +108,31 @@ def main(args=None):
|
||||
protocol_base = os.path.join(
|
||||
os.path.dirname(__file__), "..", "ruby", "protocol"
|
||||
)
|
||||
slicc = SLICC(
|
||||
slicc_file,
|
||||
protocol_base,
|
||||
verbose=True,
|
||||
debug=opts.debug,
|
||||
traceback=opts.tb,
|
||||
)
|
||||
|
||||
if opts.print_files:
|
||||
for i in sorted(slicc.files()):
|
||||
print(f" {i}")
|
||||
else:
|
||||
output("Processing AST...")
|
||||
slicc.process()
|
||||
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,
|
||||
verbose=True,
|
||||
debug=opts.debug,
|
||||
traceback=opts.tb,
|
||||
)
|
||||
|
||||
if opts.html_path:
|
||||
output("Writing HTML files...")
|
||||
slicc.writeHTMLFiles(opts.html_path)
|
||||
if opts.print_files:
|
||||
for i in sorted(slicc.files()):
|
||||
print(f" {i}")
|
||||
else:
|
||||
output("Processing AST...")
|
||||
slicc.process()
|
||||
|
||||
output("Writing C++ files...")
|
||||
slicc.writeCodeFiles(opts.code_path, [])
|
||||
if opts.html_path:
|
||||
output("Writing HTML files...")
|
||||
slicc.writeHTMLFiles(opts.html_path)
|
||||
|
||||
output("Writing C++ files...")
|
||||
slicc.writeCodeFiles(opts.code_path, [])
|
||||
|
||||
output("SLICC is Done.")
|
||||
|
||||
|
||||
@@ -54,16 +54,36 @@ from slicc.symbols import SymbolTable
|
||||
|
||||
class SLICC(Grammar):
|
||||
def __init__(
|
||||
self, filename, base_dir, verbose=False, traceback=False, **kwargs
|
||||
self,
|
||||
protocol,
|
||||
includes,
|
||||
base_dir,
|
||||
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
|
||||
"""
|
||||
self.protocol = None
|
||||
self.traceback = traceback
|
||||
self.verbose = verbose
|
||||
self.symtab = SymbolTable(self)
|
||||
self.base_dir = base_dir
|
||||
|
||||
if not includes:
|
||||
# raise error
|
||||
pass
|
||||
|
||||
try:
|
||||
self.decl_list = self.parse_file(filename, **kwargs)
|
||||
self.decl_list = self.parse_file(includes[0], **kwargs)
|
||||
for include in includes[1:]:
|
||||
self.decl_list += self.parse_file(include, **kwargs)
|
||||
# set all of the types parsed so far as shared
|
||||
self.decl_list.setShared()
|
||||
|
||||
self.decl_list += self.parse_file(protocol, **kwargs)
|
||||
except ParseError as e:
|
||||
if not self.traceback:
|
||||
sys.exit(str(e))
|
||||
|
||||
@@ -55,7 +55,7 @@ class SymbolTable:
|
||||
pairs["primitive"] = "yes"
|
||||
pairs["external"] = "yes"
|
||||
location = Location("init", 0, no_warning=not slicc.verbose)
|
||||
void = Type(self, "void", location, pairs)
|
||||
void = Type(self, "void", location, pairs, shared=False)
|
||||
self.newSymbol(void)
|
||||
|
||||
def __repr__(self):
|
||||
|
||||
@@ -63,10 +63,13 @@ class Enumeration(PairContainer):
|
||||
|
||||
|
||||
class Type(Symbol):
|
||||
def __init__(self, table, ident, location, pairs, machine=None):
|
||||
def __init__(
|
||||
self, table, ident, location, pairs, shared=False, machine=None
|
||||
):
|
||||
super().__init__(table, ident, location, pairs)
|
||||
self.c_ident = ident
|
||||
self.abstract_ident = ""
|
||||
self.shared = shared
|
||||
if machine:
|
||||
if self.isExternal or self.isPrimitive:
|
||||
if "external_name" in self:
|
||||
|
||||
Reference in New Issue
Block a user