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

Reply via email to