[pypy-svn] r37479 - in pypy/dist/pypy: config translator/backendopt translator/c/src translator/c/test
pedronis at codespeak.net
pedronis at codespeak.net
Sun Jan 28 18:07:02 CET 2007
Author: pedronis
Date: Sun Jan 28 18:06:57 2007
New Revision: 37479
Modified:
pypy/dist/pypy/config/translationoption.py
pypy/dist/pypy/translator/backendopt/all.py
pypy/dist/pypy/translator/c/src/instrument.h
pypy/dist/pypy/translator/c/test/test_standalone.py
Log:
let use all inlining strategies together with options for threshold and weight heuristic for all of them.
fix a bug with instrumentation counters where there were 0 of them in the produced executable, this would create
a -1 big file :(
Modified: pypy/dist/pypy/config/translationoption.py
==============================================================================
--- pypy/dist/pypy/config/translationoption.py (original)
+++ pypy/dist/pypy/config/translationoption.py Sun Jan 28 18:06:57 2007
@@ -6,6 +6,9 @@
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
+
translation_optiondescription = OptionDescription(
"translation", "Translation Options", [
BoolOption("stackless", "compile stackless features in",
@@ -90,6 +93,14 @@
default=None, cmdline="--fork-before"),
OptionDescription("backendopt", "Backend Optimization Options", [
+ # control inlining
+ FloatOption("inline_threshold", "Threshold when to inline functions",
+ default=DEFL_INLINE_THRESHOLD, cmdline="--inline-threshold"),
+ StrOption("inline_heuristic", "Dotted name of an heuristic function "
+ "for inlining",
+ default="pypy.translator.backendopt.inline.inlining_heuristic",
+ cmdline="--inline-heuristic"),
+
BoolOption("print_statistics", "Print statistics while optimizing",
default=False),
BoolOption("merge_if_blocks", "Merge if ... elif chains",
@@ -103,17 +114,40 @@
BoolOption("heap2stack", "Escape analysis and stack allocation",
default=False,
requires=[("translation.stackless", False)]),
- BoolOption("clever_malloc_removal",
- "Remove mallocs in a clever way", default=False),
- BoolOption("remove_asserts",
- "Kill 'raise AssertionError', which lets the C "
- "optimizer remove the asserts", default=False),
- FloatOption("inline_threshold", "Threshold when to inline functions",
- default=DEFL_INLINE_THRESHOLD, cmdline="--inline-threshold"),
+ # control profile based inlining
StrOption("profile_based_inline",
"Use call count profiling to drive inlining"
", specify arguments",
default=None, cmdline="--prof-based-inline"),
+ FloatOption("profile_based_inline_threshold",
+ "Threshold when to inline functions "
+ "for profile based inlining",
+ default=DEFL_PROF_BASED_INLINE_THRESHOLD,
+ cmdline="--prof-based-inline-threshold"),
+ StrOption("profile_based_inline_heuristic",
+ "Dotted name of an heuristic function "
+ "for profile based inlining",
+ default="pypy.translator.backendopt.inline.inlining_heuristic",
+ cmdline="--prof-based-inline-heuristic"),
+ # control clever malloc removal
+ BoolOption("clever_malloc_removal",
+ "Drives inlining to remove mallocs in a clever way",
+ default=False,
+ cmdline="--clever-malloc-removal"),
+ FloatOption("clever_malloc_removal_threshold",
+ "Threshold when to inline functions in "
+ "clever malloc removal",
+ default=DEFL_CLEVER_MALLOC_REMOVAL_INLINE_THRESHOLD,
+ cmdline="--clever-malloc-removal-threshold"),
+ StrOption("clever_malloc_removal_heuristic",
+ "Dotted name of an heuristic function "
+ "for inlining in clever malloc removal",
+ default="pypy.translator.backendopt.inline.inlining_heuristic",
+ cmdline="--clever-malloc-removal-heuristic"),
+
+ BoolOption("remove_asserts",
+ "Kill 'raise AssertionError', which lets the C "
+ "optimizer remove the asserts", default=False),
]),
OptionDescription("cli", "GenCLI options", [
Modified: pypy/dist/pypy/translator/backendopt/all.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/all.py (original)
+++ pypy/dist/pypy/translator/backendopt/all.py Sun Jan 28 18:06:57 2007
@@ -15,6 +15,22 @@
INLINE_THRESHOLD_FOR_TEST = 33
+def get_function(dottedname):
+ parts = dottedname.split('.')
+ module = '.'.join(parts[:-1])
+ name = parts[-1]
+ try:
+ mod = __import__(module, {}, {}, ['__doc__'])
+ except ImportError, e:
+ raise Exception, "Import error loading %s: %s" % (dottedname, e)
+
+ try:
+ func = getattr(mod, name)
+ except AttributeError:
+ raise Exception, "Function %s not found in module" % dottedname
+
+ return func
+
def backend_optimizations(translator, graphs=None, secondary=False, **kwds):
# sensible keywords are
# raisingop2direct_call, inline_threshold, mallocs
@@ -48,35 +64,44 @@
print "after no-op removal:"
print_statistics(translator.graphs[0], translator)
- if not config.clever_malloc_removal:
- if config.profile_based_inline and not secondary:
- inline_malloc_removal_phase(config, translator, graphs,
- config.inline_threshold*.5) # xxx tune!
- inline.instrument_inline_candidates(graphs, config.inline_threshold)
- counters = translator.driver_instrument_result(
- config.profile_based_inline)
- n = len(counters)
- def call_count_pred(label):
- if label >= n:
- return False
- return counters[label] > 250 # xxx tune!
- else:
- call_count_pred = None
+ if config.inline_threshold != 0:
+ heuristic = get_function(config.inline_heuristic)
inline_malloc_removal_phase(config, translator, graphs,
config.inline_threshold,
- call_count_pred=call_count_pred)
- else:
- count = mallocprediction.preparation(translator, graphs, 15)
- count += mallocprediction.clever_inlining_and_malloc_removal(
- translator, graphs, 33)
+ inline_heuristic=heuristic)
+
+ if config.clever_malloc_removal:
+ threshold = config.clever_malloc_removal_threshold
+ heuristic = get_function(config.clever_malloc_removal_heuristic)
+ log.inlineandremove("phase with threshold factor: %s" % threshold)
+ log.inlineandremove("heuristic: %s.%s" % (heuristic.__module__,
+ heuristic.__name__))
+ count = mallocprediction.clever_inlining_and_malloc_removal(
+ translator, graphs,
+ threshold = threshold,
+ heuristic=heuristic)
log.inlineandremove("removed %d simple mallocs in total" % count)
+ constfold(config, graphs)
if config.print_statistics:
print "after clever inlining and malloc removal"
- print_statistics(translator.graphs[0], translator)
+ print_statistics(translator.graphs[0], translator)
- if config.constfold:
- for graph in graphs:
- constant_fold_graph(graph)
+
+ if config.profile_based_inline and not secondary:
+ threshold = config.profile_based_inline_threshold
+ heuristic = get_function(config.profile_based_inline_heuristic)
+ inline.instrument_inline_candidates(graphs, threshold)
+ counters = translator.driver_instrument_result(
+ config.profile_based_inline)
+ n = len(counters)
+ def call_count_pred(label):
+ if label >= n:
+ return False
+ return counters[label] > 250 # xxx introduce an option for this
+ inline_malloc_removal_phase(config, translator, graphs,
+ threshold,
+ inline_heuristic=heuristic,
+ call_count_pred=call_count_pred)
if config.remove_asserts:
remove_asserts(translator, graphs)
@@ -96,15 +121,24 @@
for graph in graphs:
checkgraph(graph)
+def constfold(config, graphs):
+ if config.constfold:
+ for graph in graphs:
+ constant_fold_graph(graph)
+
def inline_malloc_removal_phase(config, translator, graphs, inline_threshold,
+ inline_heuristic,
call_count_pred=None):
type_system = translator.rtyper.type_system.name
log.inlining("phase with threshold factor: %s" % inline_threshold)
+ log.inlining("heuristic: %s.%s" % (inline_heuristic.__module__,
+ inline_heuristic.__name__))
# inline functions in each other
if inline_threshold:
inline.auto_inline_graphs(translator, graphs, inline_threshold,
+ heuristic=inline_heuristic,
call_count_pred=call_count_pred)
if config.print_statistics:
@@ -119,7 +153,5 @@
print "after malloc removal:"
print_statistics(translator.graphs[0], translator)
- if config.constfold:
- for graph in graphs:
- constant_fold_graph(graph)
+ constfold(config, graphs)
Modified: pypy/dist/pypy/translator/c/src/instrument.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/instrument.h (original)
+++ pypy/dist/pypy/translator/c/src/instrument.h Sun Jan 28 18:06:57 2007
@@ -16,7 +16,7 @@
typedef unsigned long instrument_count_t;
-instrument_count_t *_instrument_counters;
+instrument_count_t *_instrument_counters = NULL;
void instrument_setup() {
char *fname = getenv("_INSTRUMENT_COUNTERS");
@@ -25,15 +25,17 @@
void *buf;
size_t sz = sizeof(instrument_count_t)*INSTRUMENT_NCOUNTER;
fd = open(fname, O_CREAT|O_TRUNC|O_RDWR, 0744);
- lseek(fd, sz-1, SEEK_SET);
- write(fd, "", 1);
- buf = mmap(NULL, sz, PROT_WRITE|PROT_READ, MAP_SHARED,
- fd, 0);
- if (buf == MAP_FAILED) {
- fprintf(stderr, "mapping instrument counters file failed\n");
- abort();
+ if (sz > 0) {
+ lseek(fd, sz-1, SEEK_SET);
+ write(fd, "", 1);
+ buf = mmap(NULL, sz, PROT_WRITE|PROT_READ, MAP_SHARED,
+ fd, 0);
+ if (buf == MAP_FAILED) {
+ fprintf(stderr, "mapping instrument counters file failed\n");
+ abort();
+ }
+ _instrument_counters = (instrument_count_t *)buf;
}
- _instrument_counters = (instrument_count_t *)buf;
}
}
Modified: pypy/dist/pypy/translator/c/test/test_standalone.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_standalone.py (original)
+++ pypy/dist/pypy/translator/c/test/test_standalone.py Sun Jan 28 18:06:57 2007
@@ -2,6 +2,7 @@
import sys, os
from pypy.translator.translator import TranslationContext
+from pypy.translator.backendopt import all
from pypy.translator.c.genc import CStandaloneBuilder
from pypy.annotation.listdef import s_list_of_strings
from pypy.tool.udir import udir
@@ -103,7 +104,16 @@
return 0
from pypy.translator.interactive import Translation
t = Translation(entry_point, backend='c', standalone=True)
- t.backendopt(profile_based_inline="500")
+ # no counters
+ t.backendopt(inline_threshold=100, profile_based_inline="500")
+ exe = t.compile()
+ out = py.process.cmdexec("%s 500" % exe)
+ assert int(out) == 500*501/2
+
+ t = Translation(entry_point, backend='c', standalone=True)
+ # counters
+ t.backendopt(inline_threshold=all.INLINE_THRESHOLD_FOR_TEST*0.5,
+ profile_based_inline="500")
exe = t.compile()
out = py.process.cmdexec("%s 500" % exe)
assert int(out) == 500*501/2
More information about the Pypy-commit
mailing list