Gabe Black has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/49451 )
Change subject: python,util: Pull CXX config generation code out of
SimObject.
......................................................................
python,util: Pull CXX config generation code out of SimObject.
Change-Id: I94d6f5b172ab71ee8bedea854e1db9711748f313
---
M src/python/m5/SimObject.py
M util/bld/cxx_config_cc.py
M util/bld/cxx_config_hh.py
M util/bld/cxx_config_init_cc.py
4 files changed, 310 insertions(+), 293 deletions(-)
diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py
index 239e4c8..2037dcd 100644
--- a/src/python/m5/SimObject.py
+++ b/src/python/m5/SimObject.py
@@ -116,281 +116,6 @@
isinstance(value, (FunctionType, MethodType, ModuleType,
classmethod, type))
-def createCxxConfigDirectoryEntryFile(code, name, simobj, is_header):
- entry_class = 'CxxConfigDirectoryEntry_%s' % name
- param_class = '%sCxxConfigParams' % name
-
- code('#include "params/%s.hh"' % name)
-
- if not is_header:
- for param in simobj._params.values():
- if isSimObjectClass(param.ptype):
- code('#include "%s"' %
param.ptype._value_dict['cxx_header'])
- code('#include "params/%s.hh"' % param.ptype.__name__)
- else:
- param.ptype.cxx_ini_predecls(code)
-
- if is_header:
- member_prefix = ''
- end_of_decl = ';'
- code('#include "sim/cxx_config.hh"')
- code()
- code('namespace gem5')
- code('{')
- code()
- code('class ${param_class} : public CxxConfigParams,'
- ' public ${name}Params')
- code('{')
- code(' private:')
- code.indent()
- code('class DirectoryEntry : public CxxConfigDirectoryEntry')
- code('{')
- code(' public:')
- code.indent()
- code('DirectoryEntry();');
- code()
- code('CxxConfigParams *makeParamsObject() const')
- code('{ return new ${param_class}; }')
- code.dedent()
- code('};')
- code()
- code.dedent()
- code(' public:')
- code.indent()
- else:
- member_prefix = '%s::' % param_class
- end_of_decl = ''
- code('#include "%s"' % simobj._value_dict['cxx_header'])
- code('#include "base/str.hh"')
- code('#include "cxx_config/${name}.hh"')
-
- code('namespace gem5')
- code('{')
- code()
- code('${member_prefix}DirectoryEntry::DirectoryEntry()');
- code('{')
-
- def cxx_bool(b):
- return 'true' if b else 'false'
-
- code.indent()
- for param in simobj._params.values():
- is_vector = isinstance(param, m5.params.VectorParamDesc)
- is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)
-
- code('parameters["%s"] = new ParamDesc("%s", %s, %s);' %
- (param.name, param.name, cxx_bool(is_vector),
- cxx_bool(is_simobj)));
-
- for port in simobj._ports.values():
- is_vector = isinstance(port, m5.params.VectorPort)
- is_requestor = port.role == 'GEM5 REQUESTOR'
-
- code('ports["%s"] = new PortDesc("%s", %s, %s);' %
- (port.name, port.name, cxx_bool(is_vector),
- cxx_bool(is_requestor)))
-
- code.dedent()
- code('}')
- code()
-
- code('bool ${member_prefix}setSimObject(const std::string &name,')
- code(' SimObject *simObject)${end_of_decl}')
-
- if not is_header:
- code('{')
- code.indent()
- code('bool ret = true;')
- code()
- code('if (false) {')
- for param in simobj._params.values():
- is_vector = isinstance(param, m5.params.VectorParamDesc)
- is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)
-
- if is_simobj and not is_vector:
- code('} else if (name == "${{param.name}}") {')
- code.indent()
- code('this->${{param.name}} = '
- 'dynamic_cast<${{param.ptype.cxx_type}}>(simObject);')
- code('if (simObject && !this->${{param.name}})')
- code(' ret = false;')
- code.dedent()
- code('} else {')
- code(' ret = false;')
- code('}')
- code()
- code('return ret;')
- code.dedent()
- code('}')
-
- code()
- code('bool ${member_prefix}setSimObjectVector('
- 'const std::string &name,')
- code(' const std::vector<SimObject *> &simObjects)${end_of_decl}')
-
- if not is_header:
- code('{')
- code.indent()
- code('bool ret = true;')
- code()
- code('if (false) {')
- for param in simobj._params.values():
- is_vector = isinstance(param, m5.params.VectorParamDesc)
- is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)
-
- if is_simobj and is_vector:
- code('} else if (name == "${{param.name}}") {')
- code.indent()
- code('this->${{param.name}}.clear();')
- code('for (auto i = simObjects.begin(); '
- 'ret && i != simObjects.end(); i ++)')
- code('{')
- code.indent()
- code('${{param.ptype.cxx_type}} object = '
- 'dynamic_cast<${{param.ptype.cxx_type}}>(*i);')
- code('if (*i && !object)')
- code(' ret = false;')
- code('else')
- code(' this->${{param.name}}.push_back(object);')
- code.dedent()
- code('}')
- code.dedent()
- code('} else {')
- code(' ret = false;')
- code('}')
- code()
- code('return ret;')
- code.dedent()
- code('}')
-
- code()
- code('void ${member_prefix}setName(const std::string &name_)'
- '${end_of_decl}')
-
- if not is_header:
- code('{')
- code.indent()
- code('this->name = name_;')
- code.dedent()
- code('}')
-
- if is_header:
- code('const std::string &${member_prefix}getName()')
- code('{ return this->name; }')
-
- code()
- code('bool ${member_prefix}setParam(const std::string &name,')
- code(' const std::string &value, const Flags flags)${end_of_decl}')
-
- if not is_header:
- code('{')
- code.indent()
- code('bool ret = true;')
- code()
- code('if (false) {')
- for param in simobj._params.values():
- is_vector = isinstance(param, m5.params.VectorParamDesc)
- is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)
-
- if not is_simobj and not is_vector:
- code('} else if (name == "${{param.name}}") {')
- code.indent()
- param.ptype.cxx_ini_parse(code,
- 'value', 'this->%s' % param.name, 'ret =')
- code.dedent()
- code('} else {')
- code(' ret = false;')
- code('}')
- code()
- code('return ret;')
- code.dedent()
- code('}')
-
- code()
- code('bool ${member_prefix}setParamVector('
- 'const std::string &name,')
- code(' const std::vector<std::string> &values,')
- code(' const Flags flags)${end_of_decl}')
-
- if not is_header:
- code('{')
- code.indent()
- code('bool ret = true;')
- code()
- code('if (false) {')
- for param in simobj._params.values():
- is_vector = isinstance(param, m5.params.VectorParamDesc)
- is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)
-
- if not is_simobj and is_vector:
- code('} else if (name == "${{param.name}}") {')
- code.indent()
- code('${{param.name}}.clear();')
- code('for (auto i = values.begin(); '
- 'ret && i != values.end(); i ++)')
- code('{')
- code.indent()
- code('${{param.ptype.cxx_type}} elem;')
- param.ptype.cxx_ini_parse(code,
- '*i', 'elem', 'ret =')
- code('if (ret)')
- code(' this->${{param.name}}.push_back(elem);')
- code.dedent()
- code('}')
- code.dedent()
- code('} else {')
- code(' ret = false;')
- code('}')
- code()
- code('return ret;')
- code.dedent()
- code('}')
-
- code()
- code('bool ${member_prefix}setPortConnectionCount('
- 'const std::string &name,')
- code(' unsigned int count)${end_of_decl}')
-
- if not is_header:
- code('{')
- code.indent()
- code('bool ret = true;')
- code()
- code('if (false)')
- code(' ;')
- for port in simobj._ports.values():
- code('else if (name == "${{port.name}}")')
- code(' this->port_${{port.name}}_connection_count = count;')
- code('else')
- code(' ret = false;')
- code()
- code('return ret;')
- code.dedent()
- code('}')
-
- code()
- code('SimObject *${member_prefix}simObjectCreate()${end_of_decl}')
-
- if not is_header:
- code('{')
- if hasattr(simobj, 'abstract') and simobj.abstract:
- code(' return NULL;')
- else:
- code(' return this->create();')
- code('}')
-
- if is_header:
- code()
- code('static CxxConfigDirectoryEntry'
- ' *${member_prefix}makeDirectoryEntry()')
- code('{ return new DirectoryEntry; }')
-
- if is_header:
- code.dedent()
- code('};')
-
- code('} // namespace gem5')
-
# The metaclass for SimObject. This class controls how new classes
# that derive from SimObject are instantiated, and provides inherited
# class behavior (just like a class controls how instances of that
@@ -707,12 +432,6 @@
def pybind_predecls(cls, code):
code('#include "${{cls.cxx_header}}"')
- # Generate the C++ declaration/definition files for this SimObject's
- # param struct to allow C++ initialisation
- def cxx_config_param_file(cls, code, is_header):
- createCxxConfigDirectoryEntryFile(code, cls.__name__, cls,
is_header)
- return code
-
# This *temporary* definition is required to support calls from the
# SimObject class definition to the MetaSimObject methods (in
# particular _set_param, which gets called for parameters with default
diff --git a/util/bld/cxx_config_cc.py b/util/bld/cxx_config_cc.py
index fcb9314..13be3f6 100644
--- a/util/bld/cxx_config_cc.py
+++ b/util/bld/cxx_config_cc.py
@@ -44,6 +44,242 @@
module = importlib.import_module(modpath)
sim_object = getattr(module, sim_object_name)
+from m5.params import isSimObjectClass
+import m5.params
+
code = code_formatter()
-sim_object.cxx_config_param_file(code, False)
+
+entry_class = 'CxxConfigDirectoryEntry_%s' % sim_object_name
+param_class = '%sCxxConfigParams' % sim_object_name
+
+def cxx_bool(b):
+ return 'true' if b else 'false'
+
+code('#include "params/%s.hh"' % sim_object_name)
+
+for param in sim_object._params.values():
+ if isSimObjectClass(param.ptype):
+ code('#include "%s"' % param.ptype._value_dict['cxx_header'])
+ code('#include "params/%s.hh"' % param.ptype.__name__)
+ else:
+ param.ptype.cxx_ini_predecls(code)
+
+code('''#include "${{sim_object._value_dict['cxx_header']}}"
+#include "base/str.hh"
+#include "cxx_config/${sim_object_name}.hh"
+
+namespace gem5
+{
+
+${param_class}::DirectoryEntry::DirectoryEntry()
+{
+''')
+code.indent()
+for param in sim_object._params.values():
+ is_vector = isinstance(param, m5.params.VectorParamDesc)
+ is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)
+
+ code('parameters["%s"] = new ParamDesc("%s", %s, %s);' %
+ (param.name, param.name, cxx_bool(is_vector),
+ cxx_bool(is_simobj)));
+
+for port in sim_object._ports.values():
+ is_vector = isinstance(port, m5.params.VectorPort)
+ is_requestor = port.role == 'GEM5 REQUESTOR'
+
+ code('ports["%s"] = new PortDesc("%s", %s, %s);' %
+ (port.name, port.name, cxx_bool(is_vector),
+ cxx_bool(is_requestor)))
+
+code.dedent()
+
+code('''}
+
+bool
+${param_class}::setSimObject(const std::string &name, SimObject *simObject)
+{
+ bool ret = true;
+ if (false) {
+''')
+
+code.indent()
+for param in sim_object._params.values():
+ is_vector = isinstance(param, m5.params.VectorParamDesc)
+ is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)
+
+ if is_simobj and not is_vector:
+ code('} else if (name == "${{param.name}}") {')
+ code.indent()
+ code('this->${{param.name}} = '
+ 'dynamic_cast<${{param.ptype.cxx_type}}>(simObject);')
+ code('if (simObject && !this->${{param.name}})')
+ code(' ret = false;')
+ code.dedent()
+code.dedent()
+
+code('''
+ } else {
+ ret = false;
+ }
+
+ return ret;
+}
+
+bool
+${param_class}::setSimObjectVector(const std::string &name,
+ const std::vector<SimObject *> &simObjects)
+{
+ bool ret = true;
+
+ if (false) {
+''')
+
+code.indent()
+for param in sim_object._params.values():
+ is_vector = isinstance(param, m5.params.VectorParamDesc)
+ is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)
+
+ if is_simobj and is_vector:
+ code('} else if (name == "${{param.name}}") {')
+ code.indent()
+ code('this->${{param.name}}.clear();')
+ code('for (auto i = simObjects.begin(); '
+ 'ret && i != simObjects.end(); i ++)')
+ code('{')
+ code.indent()
+ code('${{param.ptype.cxx_type}} object = '
+ 'dynamic_cast<${{param.ptype.cxx_type}}>(*i);')
+ code('if (*i && !object)')
+ code(' ret = false;')
+ code('else')
+ code(' this->${{param.name}}.push_back(object);')
+ code.dedent()
+ code('}')
+ code.dedent()
+code.dedent()
+
+code('''
+ } else {
+ ret = false;
+ }
+
+ return ret;
+}
+
+void
+${param_class}::setName(const std::string &name_)
+{
+ this->name = name_;
+}
+
+bool
+${param_class}::setParam(const std::string &name,
+ const std::string &value, const Flags flags)
+{
+ bool ret = true;
+
+ if (false) {
+''')
+
+code.indent()
+for param in sim_object._params.values():
+ is_vector = isinstance(param, m5.params.VectorParamDesc)
+ is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)
+
+ if not is_simobj and not is_vector:
+ code('} else if (name == "${{param.name}}") {')
+ code.indent()
+ param.ptype.cxx_ini_parse(code,
+ 'value', 'this->%s' % param.name, 'ret =')
+ code.dedent()
+code.dedent()
+
+code('''
+ } else {
+ ret = false;
+ }
+
+ return ret;
+}
+
+bool
+${param_class}::setParamVector(const std::string &name,
+ const std::vector<std::string> &values, const Flags flags)
+{
+ bool ret = true;
+
+ if (false) {
+''')
+
+code.indent()
+for param in sim_object._params.values():
+ is_vector = isinstance(param, m5.params.VectorParamDesc)
+ is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)
+
+ if not is_simobj and is_vector:
+ code('} else if (name == "${{param.name}}") {')
+ code.indent()
+ code('${{param.name}}.clear();')
+ code('for (auto i = values.begin(); '
+ 'ret && i != values.end(); i ++)')
+ code('{')
+ code.indent()
+ code('${{param.ptype.cxx_type}} elem;')
+ param.ptype.cxx_ini_parse(code,
+ '*i', 'elem', 'ret =')
+ code('if (ret)')
+ code(' this->${{param.name}}.push_back(elem);')
+ code.dedent()
+ code('}')
+ code.dedent()
+code.dedent()
+
+code('''
+ } else {
+ ret = false;
+ }
+
+ return ret;
+}
+
+bool
+${param_class}::setPortConnectionCount(const std::string &name,
+ unsigned int count)
+{
+ bool ret = true;
+
+ if (false) {
+''')
+
+code.indent()
+for port in sim_object._ports.values():
+ code('} else if (name == "${{port.name}}") {')
+ code(' this->port_${{port.name}}_connection_count = count;')
+code.dedent()
+
+code('''
+ } else {
+ ret = false;
+ }
+
+ return ret;
+}
+
+SimObject *
+${param_class}::simObjectCreate()
+{
+''')
+
+code.indent()
+if hasattr(sim_object, 'abstract') and sim_object.abstract:
+ code('return nullptr;')
+else:
+ code('return this->create();')
+code.dedent()
+
+code('''}
+
+} // namespace gem5
+''')
+
code.write(cc)
diff --git a/util/bld/cxx_config_hh.py b/util/bld/cxx_config_hh.py
index 6e6e260..b559cc6 100644
--- a/util/bld/cxx_config_hh.py
+++ b/util/bld/cxx_config_hh.py
@@ -45,5 +45,61 @@
sim_object = getattr(module, sim_object_name)
code = code_formatter()
-sim_object.cxx_config_param_file(code, True)
+
+entry_class = 'CxxConfigDirectoryEntry_%s' % sim_object_name
+param_class = '%sCxxConfigParams' % sim_object_name
+
+code('''#include "params/${sim_object_name}.hh"
+
+#include "sim/cxx_config.hh"
+
+namespace gem5
+{
+
+class ${param_class} : public CxxConfigParams, public
${sim_object_name}Params
+{
+ private:
+ class DirectoryEntry : public CxxConfigDirectoryEntry
+ {
+ public:
+ DirectoryEntry();
+
+ CxxConfigParams *
+ makeParamsObject() const
+ {
+ return new ${param_class};
+ }
+ };
+
+ public:
+ bool setSimObject(const std::string &name, SimObject *simObject);
+
+ bool setSimObjectVector(const std::string &name,
+ const std::vector<SimObject *> &simObjects);
+
+ void setName(const std::string &name_);
+
+ const std::string &getName() { return this->name; }
+
+ bool setParam(const std::string &name, const std::string &value,
+ const Flags flags);
+
+ bool setParamVector(const std::string &name,
+ const std::vector<std::string> &values, const Flags flags);
+
+ bool setPortConnectionCount(const std::string &name, unsigned int
count);
+
+ SimObject *simObjectCreate();
+
+ static CxxConfigDirectoryEntry *
+ makeDirectoryEntry()
+ {
+ return new DirectoryEntry;
+ }
+
+};
+
+} // namespace gem5
+''')
+
code.write(hh)
diff --git a/util/bld/cxx_config_init_cc.py b/util/bld/cxx_config_init_cc.py
index 392052b..f26c0e4 100644
--- a/util/bld/cxx_config_init_cc.py
+++ b/util/bld/cxx_config_init_cc.py
@@ -39,20 +39,26 @@
for sim_object in sim_objects:
code('#include "cxx_config/${sim_object}.hh"')
-code('')
-code('namespace gem5')
-code('{')
-code('')
-code('void')
-code('cxxConfigInit()')
-code('{')
+
+code('''
+namespace gem5
+{
+
+void
+cxxConfigInit()
+{
+''')
+
code.indent()
for sim_object in sim_objects:
code('cxx_config_directory["${sim_object}"] = '
'${sim_object}CxxConfigParams::makeDirectoryEntry();')
code.dedent()
-code('}')
-code('')
-code('} // namespace gem5')
+
+code('''
+}
+
+} // namespace gem5
+''')
code.write(cc)
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/49451
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: I94d6f5b172ab71ee8bedea854e1db9711748f313
Gerrit-Change-Number: 49451
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s