Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/42589 )

Change subject: scons,python: Always generate default create() methods.
......................................................................

scons,python: Always generate default create() methods.

We were originally generating default create() methods along side the
pybind definitions, but unfortunately those are only included when
python support is included. Since the SimObject Param structs are
unconditionally provided even if the thing calling their create()
methods is not, we need to also unconditionally provide the default
create() definitions. We do that by putting them in their own new .cc
files.

Change-Id: I29d1573d578794b3fe7ec2bc16ef5c8c58e56d0e
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/42589
Maintainer: Gabe Black <gabe.bl...@gmail.com>
Tested-by: kokoro <noreply+kok...@google.com>
Reviewed-by: Jason Lowe-Power <power...@gmail.com>
Reviewed-by: Earl Ou <shunhsin...@google.com>
---
M src/SConscript
M src/python/m5/SimObject.py
2 files changed, 94 insertions(+), 76 deletions(-)

Approvals:
  Jason Lowe-Power: Looks good to me, approved
  Earl Ou: Looks good to me, approved
  Gabe Black: Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/SConscript b/src/SConscript
index 5fe0ab2..31fce0c 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -917,7 +917,7 @@
 # Create all of the SimObject param headers and enum headers
 #

-def createSimObjectParamStruct(target, source, env):
+def createSimObjectParamDecl(target, source, env):
     assert len(target) == 1 and len(source) == 1

     name = source[0].get_text_contents()
@@ -927,6 +927,16 @@
     obj.cxx_param_decl(code)
     code.write(target[0].abspath)

+def createSimObjectParamDef(target, source, env):
+    assert len(target) == 1 and len(source) == 1
+
+    name = source[0].get_text_contents()
+    obj = sim_objects[name]
+
+    code = code_formatter()
+    obj.cxx_param_def(code)
+    code.write(target[0].abspath)
+
 def createSimObjectCxxConfig(is_header):
     def body(target, source, env):
         assert len(target) == 1 and len(source) == 1
@@ -987,9 +997,16 @@
     hh_file = File('params/%s.hh' % name)
     params_hh_files.append(hh_file)
     env.Command(hh_file, Value(name),
- MakeAction(createSimObjectParamStruct, Transform("SO PARAM"))) + MakeAction(createSimObjectParamDecl, Transform("SOPARMHH")))
     env.Depends(hh_file, depends + extra_deps)

+    if not getattr(simobj, 'abstract', False) and hasattr(simobj, 'type'):
+        cc_file = File('params/%s.cc' % name)
+        env.Command(cc_file, Value(name),
+ MakeAction(createSimObjectParamDef, Transform("SOPARMCC")))
+        env.Depends(cc_file, depends + extra_deps)
+        Source(cc_file)
+
 # C++ parameter description files
 if GetOption('with_cxx_config'):
     for name,simobj in sorted(sim_objects.items()):
diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py
index e604a20..bdce718 100644
--- a/src/python/m5/SimObject.py
+++ b/src/python/m5/SimObject.py
@@ -368,7 +368,7 @@

     if not is_header:
         code('{')
-        if hasattr(simobj, 'abstract') and simobj.abstract:
+        if getattr(simobj, 'abstract', False):
             code('    return NULL;')
         else:
             code('    return this->create();')
@@ -700,6 +700,80 @@
     def pybind_predecls(cls, code):
         code('#include "${{cls.cxx_header}}"')

+    def cxx_param_def(cls, code):
+        code('''
+#include <type_traits>
+
+#include "base/compiler.hh"
+
+#include "${{cls.cxx_header}}"
+#include "params/${cls}.hh"
+
+''')
+        code()
+        code('namespace')
+        code('{')
+        code()
+ # If we can't define a default create() method for this params struct
+        # because the SimObject doesn't have the right constructor, use
+ # template magic to make it so we're actually defining a create method
+        # for this class instead.
+        code('class Dummy${cls}ParamsClass')
+        code('{')
+        code('  public:')
+        code('    ${{cls.cxx_class}} *create() const;')
+        code('};')
+        code()
+        code('template <class CxxClass, class Enable=void>')
+        code('class Dummy${cls}Shunt;')
+        code()
+        # This version directs to the real Params struct and the default
+        # behavior of create if there's an appropriate constructor.
+        code('template <class CxxClass>')
+        code('class Dummy${cls}Shunt<CxxClass, std::enable_if_t<')
+        code('    std::is_constructible<CxxClass,')
+        code('        const ${cls}Params &>::value>>')
+        code('{')
+        code('  public:')
+        code('    using Params = ${cls}Params;')
+        code('    static ${{cls.cxx_class}} *')
+        code('    create(const Params &p)')
+        code('    {')
+        code('        return new CxxClass(p);')
+        code('    }')
+        code('};')
+        code()
+        # This version diverts to the DummyParamsClass and a dummy
+        # implementation of create if the appropriate constructor does not
+        # exist.
+        code('template <class CxxClass>')
+        code('class Dummy${cls}Shunt<CxxClass, std::enable_if_t<')
+        code('    !std::is_constructible<CxxClass,')
+        code('        const ${cls}Params &>::value>>')
+        code('{')
+        code('  public:')
+        code('    using Params = Dummy${cls}ParamsClass;')
+        code('    static ${{cls.cxx_class}} *')
+        code('    create(const Params &p)')
+        code('    {')
+        code('        return nullptr;')
+        code('    }')
+        code('};')
+        code()
+        code('} // anonymous namespace')
+        code()
+        # An implementation of either the real Params struct's create
+        # method, or the Dummy one. Either an implementation is
+        # mandantory since this was shunted off to the dummy class, or
+        # one is optional which will override this weak version.
+        code('M5_VAR_USED ${{cls.cxx_class}} *')
+ code('Dummy${cls}Shunt<${{cls.cxx_class}}>::Params::create() const')
+        code('{')
+        code('    return Dummy${cls}Shunt<${{cls.cxx_class}}>::')
+        code('        create(*this);')
+        code('}')
+
+
     def pybind_decl(cls, code):
         py_class_name = cls.pybind_class

@@ -713,9 +787,6 @@
         code('''#include "pybind11/pybind11.h"
 #include "pybind11/stl.h"

-#include <type_traits>
-
-#include "base/compiler.hh"
 #include "params/$cls.hh"
 #include "python/pybind11/core.hh"
 #include "sim/init.hh"
@@ -797,76 +868,6 @@
         code()
code('static EmbeddedPyBind embed_obj("${0}", module_init, "${1}");',
              cls, cls._base.type if cls._base else "")
-        if not hasattr(cls, 'abstract') or not cls.abstract:
-            if 'type' in cls.__dict__:
-                code()
- # This namespace can't *actually* be anonymous, or the compiler
-                # gets upset about having a weak symbol init.
-                code('namespace anonymous_params')
-                code('{')
-                code()
- # If we can't define a default create() method for this params
-                # struct because the SimObject doesn't have the right
- # constructor, use template magic to make it so we're actually
-                # defining a create method for this class instead.
-                code('class Dummy${cls}ParamsClass')
-                code('{')
-                code('  public:')
-                code('    ${{cls.cxx_class}} *create() const;')
-                code('};')
-                code()
-                code('template <class CxxClass, class Enable=void>')
-                code('class DummyShunt;')
-                code()
-                # This version directs to the real Params struct and the
-                # default behavior of create if there's an appropriate
-                # constructor.
-                code('template <class CxxClass>')
-                code('class DummyShunt<CxxClass, std::enable_if_t<')
-                code('    std::is_constructible<CxxClass,')
-                code('        const ${cls}Params &>::value>>')
-                code('{')
-                code('  public:')
-                code('    using Params = ${cls}Params;')
-                code('    static ${{cls.cxx_class}} *')
-                code('    create(const Params &p)')
-                code('    {')
-                code('        return new CxxClass(p);')
-                code('    }')
-                code('};')
-                code()
-                # This version diverts to the DummyParamsClass and a dummy
- # implementation of create if the appropriate constructor does
-                # not exist.
-                code('template <class CxxClass>')
-                code('class DummyShunt<CxxClass, std::enable_if_t<')
-                code('    !std::is_constructible<CxxClass,')
-                code('        const ${cls}Params &>::value>>')
-                code('{')
-                code('  public:')
-                code('    using Params = Dummy${cls}ParamsClass;')
-                code('    static ${{cls.cxx_class}} *')
-                code('    create(const Params &p)')
-                code('    {')
-                code('        return nullptr;')
-                code('    }')
-                code('};')
-                code()
-                code('} // namespace anonymous_params')
-                code()
-                code('using namespace anonymous_params;')
-                code()
-                # A weak implementation of either the real Params struct's
-                # create method, or the Dummy one if we don't want to have
-                # any default implementation. Either an implementation is
- # mandantory since this was shunted off to the dummy class, or
-                # one is optional which will override this weak version.
-                code('M5_WEAK ${{cls.cxx_class}} *')
- code('DummyShunt<${{cls.cxx_class}}>::Params::create() const')
-                code('{')
-                code('    return DummyShunt<${{cls.cxx_class}}>::')
-                code('        create(*this);')
-                code('}')

     _warned_about_nested_templates = False


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

Gerrit-Project: public/gem5
Gerrit-Branch: release-staging-v21-0
Gerrit-Change-Id: I29d1573d578794b3fe7ec2bc16ef5c8c58e56d0e
Gerrit-Change-Number: 42589
Gerrit-PatchSet: 3
Gerrit-Owner: Gabe Black <gabe.bl...@gmail.com>
Gerrit-Reviewer: Andreas Sandberg <andreas.sandb...@arm.com>
Gerrit-Reviewer: Bobby R. Bruce <bbr...@ucdavis.edu>
Gerrit-Reviewer: Earl Ou <shunhsin...@google.com>
Gerrit-Reviewer: Gabe Black <gabe.bl...@gmail.com>
Gerrit-Reviewer: Jason Lowe-Power <ja...@lowepower.com>
Gerrit-Reviewer: Jason Lowe-Power <power...@gmail.com>
Gerrit-Reviewer: kokoro <noreply+kok...@google.com>
Gerrit-MessageType: merged
_______________________________________________
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