[pypy-svn] r56919 - in pypy/branch/opt-option/pypy: config config/test translator translator/goal

arigo at codespeak.net arigo at codespeak.net
Sat Aug 2 14:03:15 CEST 2008


Author: arigo
Date: Sat Aug  2 14:03:13 2008
New Revision: 56919

Modified:
   pypy/branch/opt-option/pypy/config/config.py
   pypy/branch/opt-option/pypy/config/pypyoption.py
   pypy/branch/opt-option/pypy/config/test/test_config.py
   pypy/branch/opt-option/pypy/config/test/test_pypyoption.py
   pypy/branch/opt-option/pypy/config/translationoption.py
   pypy/branch/opt-option/pypy/translator/driver.py
   pypy/branch/opt-option/pypy/translator/goal/translate.py
Log:
In-progress: implemented the '--opt' option.


Modified: pypy/branch/opt-option/pypy/config/config.py
==============================================================================
--- pypy/branch/opt-option/pypy/config/config.py	(original)
+++ pypy/branch/opt-option/pypy/config/config.py	Sat Aug  2 14:03:13 2008
@@ -13,6 +13,9 @@
 class ConfigError(Exception):
     pass
 
+class ConflictConfigError(ConfigError):
+    pass
+
 class Config(object):
     _cfgimpl_frozen = False
     
@@ -99,11 +102,23 @@
         if oldvalue != value and oldowner not in ("default", "suggested"):
             if who in ("default", "suggested"):
                 return
-            raise ConfigError('cannot override value to %s for option %s' %
-                                (value, name))
+            raise ConflictConfigError('cannot override value to %s for '
+                                      'option %s' % (value, name))
         child.setoption(self, value, who)
         self._cfgimpl_value_owners[name] = who
 
+    def suggest(self, **kwargs):
+        for name, value in kwargs.items():
+            self.suggestoption(name, value)
+
+    def suggestoption(self, name, value):
+        try:
+            self.setoption(name, value, "suggested")
+        except ConflictConfigError:
+            # setting didn't work, but that is fine, since it is
+            # suggested only
+            pass
+
     def set(self, **kwargs):
         all_paths = [p.split(".") for p in self.getpaths()]
         for key, value in kwargs.iteritems():
@@ -248,12 +263,7 @@
         for path, reqvalue in self._suggests.get(value, []):
             toplevel = config._cfgimpl_get_toplevel()
             homeconfig, name = toplevel._cfgimpl_get_home_by_path(path)
-            try:
-                homeconfig.setoption(name, reqvalue, "suggested")
-            except ConfigError:
-                # setting didn't work, but that is fine, since it is
-                # suggested only
-                pass
+            homeconfig.suggestoption(name, reqvalue)
         super(ChoiceOption, self).setoption(config, value, who)
 
     def validate(self, value):
@@ -298,12 +308,7 @@
             for path, reqvalue in self._suggests:
                 toplevel = config._cfgimpl_get_toplevel()
                 homeconfig, name = toplevel._cfgimpl_get_home_by_path(path)
-                try:
-                    homeconfig.setoption(name, reqvalue, "suggested")
-                except ConfigError:
-                    # setting didn't work, but that is fine, since it is
-                    # suggested
-                    pass
+                homeconfig.suggestoption(name, reqvalue)
 
         super(BoolOption, self).setoption(config, value, who)
 

Modified: pypy/branch/opt-option/pypy/config/pypyoption.py
==============================================================================
--- pypy/branch/opt-option/pypy/config/pypyoption.py	(original)
+++ pypy/branch/opt-option/pypy/config/pypyoption.py	Sat Aug  2 14:03:13 2008
@@ -3,7 +3,7 @@
 import sys
 from pypy.config.config import OptionDescription, BoolOption, IntOption, ArbitraryOption
 from pypy.config.config import ChoiceOption, StrOption, to_optparse, Config
-from pypy.config.config import ConfigError
+from pypy.config.config import ConflictConfigError
 
 modulepath = py.magic.autopath().dirpath().dirpath().join("module")
 all_modules = [p.basename for p in modulepath.listdir()
@@ -65,7 +65,8 @@
                     "The module %r is disabled\n" % (modname,) +
                     "because importing %s raised %s\n" % (name, errcls) +
                     str(e))
-                raise ConfigError("--withmod-%s: %s" % (modname, errcls))
+                raise ConflictConfigError("--withmod-%s: %s" % (modname,
+                                                                errcls))
         return validator
     else:
         return None
@@ -285,7 +286,7 @@
                    "special case the 'list[integer]' expressions",
                    default=False),
         BoolOption("builtinshortcut",
-                   "a shortcut for operations between built-in types XXX BROKEN",
+                   "a shortcut for operations between built-in types",
                    default=False),
         BoolOption("getattributeshortcut",
                    "track types that override __getattribute__",
@@ -295,45 +296,7 @@
                    "a instrumentation option: before exit, print the types seen by "
                    "certain simpler bytecodes",
                    default=False),
-
-        BoolOption("allopts",
-                   "enable all thought-to-be-working optimizations",
-                   default=False,
-                   suggests=[("objspace.opcodes.CALL_LIKELY_BUILTIN", True),
-                             ("objspace.opcodes.CALL_METHOD", True),
-                             ("translation.withsmallfuncsets", 5),
-                             ("translation.profopt",
-                              "-c 'from richards import main;main(); from test import pystone; pystone.main()'"),
-                             ("objspace.std.withmultidict", True),
-#                             ("objspace.std.withstrjoin", True),
-                             ("objspace.std.withshadowtracking", True),
-#                             ("objspace.std.withstrslice", True),
-#                             ("objspace.std.withsmallint", True),
-                             ("objspace.std.withrangelist", True),
-                             ("objspace.std.withmethodcache", True),
-#                             ("objspace.std.withfastslice", True),
-                             ("objspace.std.withprebuiltchar", True),
-                             ("objspace.std.builtinshortcut", True),
-                             ("objspace.std.optimized_list_getitem", True),
-                             ("objspace.std.getattributeshortcut", True),
-                             ("translation.list_comprehension_operations",True),
-                             ("translation.backendopt.remove_asserts",True),
-                             ],
-                   cmdline="--allopts --faassen", negation=False),
-
-##         BoolOption("llvmallopts",
-##                    "enable all optimizations, and use llvm compiled via C",
-##                    default=False,
-##                    requires=[("objspace.std.allopts", True),
-##                              ("translation.llvm_via_c", True),
-##                              ("translation.backend", "llvm")],
-##                    cmdline="--llvm-faassen", negation=False),
      ]),
-    #BoolOption("lowmem", "Try to use less memory during translation",
-    #           default=False, cmdline="--lowmem",
-    #           requires=[("objspace.geninterp", False)]),
-
-
 ])
 
 def get_pypy_config(overrides=None, translating=False):
@@ -342,6 +305,46 @@
             pypy_optiondescription, overrides=overrides,
             translating=translating)
 
+def set_pypy_opt_level(config, level):
+    """Apply PyPy-specific optimization suggestions on the 'config'.
+    The optimizations depend on the selected level and possibly on the backend.
+    """
+    # warning: during some tests, the type_system and the backend may be
+    # unspecified and we get None.  It shouldn't occur in translate.py though.
+    type_system = config.translation.type_system
+    backend = config.translation.backend
+
+    # all the good optimizations for PyPy should be listed here
+    if level in ['2', '3']:
+        config.objspace.opcodes.suggest(CALL_LIKELY_BUILTIN=True)
+        config.objspace.opcodes.suggest(CALL_METHOD=True)
+        config.objspace.std.suggest(withmultidict=True)
+        config.objspace.std.suggest(withshadowtracking=True)
+        config.objspace.std.suggest(withrangelist=True)
+        config.objspace.std.suggest(withmethodcache=True)
+        config.objspace.std.suggest(withprebuiltchar=True)
+        config.objspace.std.suggest(builtinshortcut=True)
+        config.objspace.std.suggest(optimized_list_getitem=True)
+        config.objspace.std.suggest(getattributeshortcut=True)
+
+    # extra costly optimizations only go in level 3
+    if level == '3':
+        config.translation.suggest(profopt=
+            "-c 'from richards import main;main(); "
+                "from test import pystone; pystone.main()'")
+
+    # memory-saving optimizations
+    if level == 'mem':
+        config.objspace.std.suggest(withsmallint=True)
+        config.objspace.std.suggest(withrangelist=True)
+        config.objspace.std.suggest(withprebuiltchar=True)
+        config.objspace.std.suggest(withsharingdict=True)
+
+    # completely disable geninterp in a level 0 translation
+    if level == '0':
+        config.objspace.suggest(geninterp=False)
+
+
 if __name__ == '__main__':
     config = get_pypy_config()
     print config.getpaths()

Modified: pypy/branch/opt-option/pypy/config/test/test_config.py
==============================================================================
--- pypy/branch/opt-option/pypy/config/test/test_config.py	(original)
+++ pypy/branch/opt-option/pypy/config/test/test_config.py	Sat Aug  2 14:03:13 2008
@@ -530,6 +530,15 @@
     assert not c.toplevel
 
 
+def test_bogus_suggests():
+    descr = OptionDescription("test", '', [
+        BoolOption("toplevel", "", suggests=[("opt", "bogusvalue")]),
+        ChoiceOption("opt", "", ["a", "b", "c"], "a"),
+    ])
+    c = Config(descr)
+    py.test.raises(ConfigError, "c.toplevel = True")
+
+
 def test_delattr():
     descr = OptionDescription("opt", "", [
     OptionDescription("s1", "", [
@@ -549,7 +558,7 @@
 
     def my_validator_2(config):
         assert config is c
-        raise ConfigError
+        raise ConflictConfigError
 
     descr = OptionDescription("opt", "", [
         BoolOption('booloption1', 'option test1', default=False,

Modified: pypy/branch/opt-option/pypy/config/test/test_pypyoption.py
==============================================================================
--- pypy/branch/opt-option/pypy/config/test/test_pypyoption.py	(original)
+++ pypy/branch/opt-option/pypy/config/test/test_pypyoption.py	Sat Aug  2 14:03:13 2008
@@ -1,6 +1,7 @@
 import py
-from pypy.config.pypyoption import get_pypy_config
+from pypy.config.pypyoption import get_pypy_config, set_pypy_opt_level
 from pypy.config.config import Config, ConfigError
+from pypy.config.translationoption import set_opt_level
 
 thisdir = py.magic.autopath().dirpath()
 
@@ -29,10 +30,32 @@
         conf.translation.gc = name
         assert conf.translation.gctransformer == "framework"
 
+def test_set_opt_level():
+    conf = get_pypy_config()
+    set_opt_level(conf, '0')
+    assert conf.translation.gc == 'boehm'
+    assert conf.translation.backendopt.none == True
+    conf = get_pypy_config()
+    set_opt_level(conf, '2')
+    assert conf.translation.gc != 'boehm'
+    assert not conf.translation.backendopt.none
+    conf = get_pypy_config()
+    set_opt_level(conf, 'mem')
+    assert conf.translation.gc == 'marksweep'
+    assert not conf.translation.backendopt.none
+
+def test_set_pypy_opt_level():
+    conf = get_pypy_config()
+    set_pypy_opt_level(conf, '2')
+    assert conf.objspace.std.withmultidict
+    conf = get_pypy_config()
+    set_pypy_opt_level(conf, '0')
+    assert not conf.objspace.std.withmultidict
+
 def test_rweakref_required():
     conf = get_pypy_config()
     conf.translation.rweakref = False
-    conf.objspace.std.allopts = True
+    set_pypy_opt_level(conf, '3')
 
     assert not conf.objspace.std.withtypeversion
     assert not conf.objspace.std.withmethodcache

Modified: pypy/branch/opt-option/pypy/config/translationoption.py
==============================================================================
--- pypy/branch/opt-option/pypy/config/translationoption.py	(original)
+++ pypy/branch/opt-option/pypy/config/translationoption.py	Sat Aug  2 14:03:13 2008
@@ -2,12 +2,14 @@
 import py, os
 from pypy.config.config import OptionDescription, BoolOption, IntOption, ArbitraryOption, FloatOption
 from pypy.config.config import ChoiceOption, StrOption, to_optparse, Config
+from pypy.config.config import ConfigError
 
 DEFL_INLINE_THRESHOLD = 32.4    # just enough to inline add__Int_Int()
 # and just small enough to prevend inlining of some rlist functions.
 
 DEFL_PROF_BASED_INLINE_THRESHOLD = 32.4
 DEFL_CLEVER_MALLOC_REMOVAL_INLINE_THRESHOLD = 32.4
+DEFL_LOW_INLINE_THRESHOLD = DEFL_INLINE_THRESHOLD / 2.0
 
 translation_optiondescription = OptionDescription(
         "translation", "Translation Options", [
@@ -39,6 +41,8 @@
     BoolOption("llvm_via_c", "compile llvm via C",
                default=False, cmdline="--llvm-via-c",
                requires=[("translation.backend", "llvm")]),
+
+    # gc
     ChoiceOption("gc", "Garbage Collection Strategy",
                  ["boehm", "ref", "marksweep", "semispace", "statistics",
                   "generation", "hybrid", "none"],
@@ -82,18 +86,10 @@
                      "llvmgc": [("translation.gc", "generation")],
                      "asmgcc": [("translation.gc", "generation")],
                  }),
+
+    # other noticeable options
     BoolOption("thread", "enable use of threading primitives",
                default=False, cmdline="--thread"),
-    BoolOption("verbose", "Print extra information", default=False),
-    BoolOption("debug", "Record extra annotation information",
-               cmdline="-d --debug", default=False),
-    BoolOption("insist", "Try hard to go on RTyping", default=False,
-               cmdline="--insist"),
-    IntOption("withsmallfuncsets",
-              "Represent groups of less funtions than this as indices into an array",
-               default=0),
-    BoolOption("countmallocs", "Count mallocs and frees", default=False,
-               cmdline=None),
     BoolOption("sandbox", "Produce a fully-sandboxed executable",
                default=False, cmdline="--sandbox",
                requires=[("translation.thread", False)]),
@@ -101,6 +97,11 @@
                default=True),
 
     # misc
+    BoolOption("verbose", "Print extra information", default=False),
+    BoolOption("debug", "Record extra annotation information",
+               cmdline="-d --debug", default=True),
+    BoolOption("insist", "Try hard to go on RTyping", default=False,
+               cmdline="--insist"),
     StrOption("cc", "Specify compiler to use for compiling generated C", cmdline="--cc"),
     StrOption("profopt", "Specify profile based optimization script",
               cmdline="--profopt"),
@@ -108,6 +109,13 @@
                default=False, cmdline="--no-profopt", negation=False),
     BoolOption("instrument", "internal: turn instrumentation on",
                default=False, cmdline=None),
+    BoolOption("countmallocs", "Count mallocs and frees", default=False,
+               cmdline=None),
+    ChoiceOption("fork_before",
+                 "(UNIX) Create restartable checkpoint before step",
+                 ["annotate", "rtype", "backendopt", "database", "source",
+                  "hintannotate", "timeshift"],
+                 default=None, cmdline="--fork-before"),
 
     ArbitraryOption("instrumentctl", "internal",
                default=None),
@@ -140,11 +148,9 @@
                "attempt to pre-allocate the list",
                default=False,
                cmdline='--listcompr'),
-    ChoiceOption("fork_before",
-                 "(UNIX) Create restartable checkpoint before step",
-                 ["annotate", "rtype", "backendopt", "database", "source",
-                  "hintannotate", "timeshift"],
-                 default=None, cmdline="--fork-before"),
+    IntOption("withsmallfuncsets",
+              "Represent groups of less funtions than this as indices into an array",
+               default=0),
 
     # options for ootype
     OptionDescription("ootype", "Object Oriented Typesystem options", [
@@ -273,3 +279,61 @@
             value = getattr(existing_config, child._name)
             config._cfgimpl_values[child._name] = value
     return config
+
+# ____________________________________________________________
+
+OPT_LEVELS = ['0', '1', 'size', 'mem', '2', '3']
+DEFAULT_OPT_LEVEL = '2'
+
+OPT_TABLE_DOC = {
+    '0':    'No optimization.  Uses the Boehm GC.',
+    '1':    'Enable a default set of optimizations.  Uses the Boehm GC.',
+    'size': 'Optimize for the size of the executable.  Uses the Boehm GC.',
+    'mem':  'Optimize for run-time memory usage and use a memory-saving GC.',
+    '2':    'Enable most optimizations and use a high-performance GC.',
+    '3':    'Enable all optimizations and use a high-performance GC.',
+    }
+
+OPT_TABLE = {
+    #level:  gc          backend optimizations...
+    '0':    'boehm       nobackendopt',
+    '1':    'boehm       lowinline',
+    'size': 'boehm       lowinline     remove_asserts',
+    'mem':  'marksweep   lowinline     remove_asserts',
+    '2':    'hybrid      extraopts',
+    '3':    'hybrid      extraopts     remove_asserts',
+    }
+
+def set_opt_level(config, level):
+    """Apply optimization suggestions on the 'config'.
+    The optimizations depend on the selected level and possibly on the backend.
+    """
+    # warning: during some tests, the type_system and the backend may be
+    # unspecified and we get None.  It shouldn't occur in translate.py though.
+    type_system = config.translation.type_system
+    backend = config.translation.backend
+
+    try:
+        opts = OPT_TABLE[level]
+    except KeyError:
+        raise ConfigError("no such optimization level: %r" % (level,))
+    words = opts.split()
+    gc = words.pop(0)
+
+    # set the GC (only meaningful with lltype)
+    config.translation.suggest(gc=gc)
+
+    # set the backendopts
+    for word in words:
+        if word == 'nobackendopt':
+            config.translation.backendopt.suggest(none=True)
+        elif word == 'lowinline':
+            config.translation.backendopt.suggest(inline_threshold=
+                                                DEFL_LOW_INLINE_THRESHOLD)
+        elif word == 'remove_asserts':
+            config.translation.backendopt.suggest(remove_asserts=True)
+        elif word == 'extraopts':
+            config.translation.suggest(withsmallfuncsets=5)
+            config.translation.suggest(list_comprehension_operations=True)
+        else:
+            raise ValueError(word)

Modified: pypy/branch/opt-option/pypy/translator/driver.py
==============================================================================
--- pypy/branch/opt-option/pypy/translator/driver.py	(original)
+++ pypy/branch/opt-option/pypy/translator/driver.py	Sat Aug  2 14:03:13 2008
@@ -15,22 +15,6 @@
 log = py.log.Producer("translation")
 py.log.setconsumer("translation", ansi_log)
 
-DEFAULTS = {
-  'translation.gc': 'ref',
-  'translation.cc': None,
-  'translation.profopt': None,
-
-  'translation.thread': False, # influences GC policy
-
-  'translation.stackless': False,
-  'translation.debug': True,
-  'translation.insist': False,
-  'translation.backend': 'c',
-  'translation.fork_before': None,
-  'translation.backendopt.raisingop2direct_call' : False,
-  'translation.backendopt.merge_if_blocks': True,
-}
-
 
 def taskdef(taskfunc, deps, title, new_state=None, expected_states=[],
             idemp=False, earlycheck=None):
@@ -93,7 +77,7 @@
 
         if config is None:
             from pypy.config.pypyoption import get_pypy_config
-            config = get_pypy_config(DEFAULTS, translating=True)
+            config = get_pypy_config(translating=True)
         self.config = config
         if overrides is not None:
             self.config.override(overrides)

Modified: pypy/branch/opt-option/pypy/translator/goal/translate.py
==============================================================================
--- pypy/branch/opt-option/pypy/translator/goal/translate.py	(original)
+++ pypy/branch/opt-option/pypy/translator/goal/translate.py	Sat Aug  2 14:03:13 2008
@@ -12,6 +12,8 @@
                                ArbitraryOption, StrOption, IntOption, Config, \
                                ChoiceOption, OptHelpFormatter
 from pypy.config.translationoption import get_combined_translation_config
+from pypy.config.translationoption import set_opt_level
+from pypy.config.translationoption import OPT_LEVELS, DEFAULT_OPT_LEVEL
 
 
 GOALS= [
@@ -46,6 +48,9 @@
 translate_optiondescr = OptionDescription("translate", "XXX", [
     StrOption("targetspec", "XXX", default='targetpypystandalone',
               cmdline=None),
+    ChoiceOption("opt",
+                 "optimization level", OPT_LEVELS, default=DEFAULT_OPT_LEVEL,
+                 cmdline="--opt"),
     BoolOption("profile",
                "cProfile (to debug the speed of the translation process)",
                default=False,
@@ -72,17 +77,7 @@
     
 OVERRIDES = {
     'translation.debug': False,
-    'translation.insist': False,
-
-    'translation.gc': 'boehm',
     'translation.backend': 'c',
-    'translation.stackless': False,
-    'translation.backendopt.raisingop2direct_call' : False,
-    'translation.backendopt.merge_if_blocks': True,
-
-    'translation.cc': None,
-    'translation.profopt': None,
-    'translation.output': None,
 }
 
 import py
@@ -162,6 +157,9 @@
                 existing_config=config,
                 translating=True)
 
+    # apply the optimization level settings
+    set_opt_level(config, translateconfig.opt)
+
     # let the target modify or prepare itself
     # based on the config
     if 'handle_config' in targetspec_dic:



More information about the Pypy-commit mailing list