diff -r 4d699bf00be0 Lib/test/libregrtest/cmdline.py --- a/Lib/test/libregrtest/cmdline.py Fri Oct 02 15:09:51 2015 -0400 +++ b/Lib/test/libregrtest/cmdline.py Fri Oct 02 14:59:06 2015 -0700 @@ -234,6 +234,8 @@ group.add_argument('-F', '--forever', action='store_true', help='run the specified tests in a loop, until an ' 'error happens') + group.add_argument('-P', '--pgo', dest='pgo', action='store_true', + help='enable Profile Guided Optimization training') parser.add_argument('args', nargs=argparse.REMAINDER, help=argparse.SUPPRESS) @@ -277,7 +279,7 @@ findleaks=False, use_resources=None, trace=False, coverdir='coverage', runleaks=False, huntrleaks=False, verbose2=False, print_slow=False, random_seed=None, use_mp=None, verbose3=False, forever=False, - header=False, failfast=False, match_tests=None) + header=False, failfast=False, match_tests=None, pgo=False) for k, v in kwargs.items(): if not hasattr(ns, k): raise TypeError('%r is an invalid keyword argument ' @@ -297,6 +299,8 @@ parser.error("-l and -j don't go together!") if ns.failfast and not (ns.verbose or ns.verbose3): parser.error("-G/--failfast needs either -v or -W") + if ns.pgo and (ns.verbose or ns.verbose2 or ns.verbose3): + parser.error("--pgo/-v don't go together!") if ns.quiet: ns.verbose = 0 diff -r 4d699bf00be0 Lib/test/libregrtest/main.py --- a/Lib/test/libregrtest/main.py Fri Oct 02 15:09:51 2015 -0400 +++ b/Lib/test/libregrtest/main.py Fri Oct 02 14:59:06 2015 -0700 @@ -102,7 +102,10 @@ def display_progress(self, test_index, test): if self.ns.quiet: return - fmt = "[{1:{0}}{2}/{3}] {4}" if self.bad else "[{1:{0}}{2}] {4}" + if self.bad and not self.ns.pgo: + fmt = "[{1:{0}}{2}/{3}] {4}" + else: + fmt = "[{1:{0}}{2}] {4}" print(fmt.format(self.test_count_width, test_index, self.test_count, len(self.bad), test), flush=True) @@ -166,12 +169,12 @@ # For a partial run, we do not need to clutter the output. if (self.ns.verbose or self.ns.header - or not (self.ns.quiet or self.ns.single + or not (self.ns.pgo or self.ns.quiet or self.ns.single or self.tests or self.ns.args)): # Print basic platform information print("==", platform.python_implementation(), *sys.version.split()) print("== ", platform.platform(aliased=True), - "%s-endian" % sys.byteorder) + "%s-endian" % sys.byteorder) print("== ", "hash algorithm:", sys.hash_info.algorithm, "64bit" if sys.maxsize > 2**32 else "32bit") print("== ", os.getcwd()) @@ -242,6 +245,11 @@ print(count(len(omitted), "test"), "omitted:") printlist(omitted) + # If running the test suite for PGO then no one cares about + # results. + if self.ns.pgo: + return + if self.good and not self.ns.quiet: if (not self.bad and not self.skipped diff -r 4d699bf00be0 Lib/test/libregrtest/runtest.py --- a/Lib/test/libregrtest/runtest.py Fri Oct 02 15:09:51 2015 -0400 +++ b/Lib/test/libregrtest/runtest.py Fri Oct 02 14:59:06 2015 -0700 @@ -65,6 +65,7 @@ timeout -- dump the traceback and exit if a test takes more than timeout seconds failfast, match_tests -- See regrtest command-line flags for these. + pgo -- if true, suppress any info irrelevant to a generating a PGO build Returns the tuple result, test_time, where result is one of the constants: INTERRUPTED KeyboardInterrupt when run under -j @@ -82,6 +83,7 @@ failfast = ns.failfast match_tests = ns.match_tests timeout = ns.timeout + pgo = ns.pgo use_timeout = (timeout is not None) if use_timeout: @@ -110,7 +112,7 @@ sys.stdout = stream sys.stderr = stream result = runtest_inner(test, verbose, quiet, huntrleaks, - display_failure=False) + display_failure=False, pgo=pgo) if result[0] == FAILED: output = stream.getvalue() orig_stderr.write(output) @@ -121,7 +123,7 @@ else: support.verbose = verbose # Tell tests to be moderately quiet result = runtest_inner(test, verbose, quiet, huntrleaks, - display_failure=not verbose) + display_failure=not verbose, pgo=pgo) return result finally: if use_timeout: @@ -131,7 +133,7 @@ def runtest_inner(test, verbose, quiet, - huntrleaks=False, display_failure=True): + huntrleaks=False, display_failure=True, *, pgo=False): support.unload(test) test_time = 0.0 @@ -142,7 +144,7 @@ else: # Always import it from the test package abstest = 'test.' + test - with saved_test_environment(test, verbose, quiet) as environment: + with saved_test_environment(test, verbose, quiet, pgo=pgo) as environment: start_time = time.time() the_module = importlib.import_module(abstest) # If the test has a test_main, that will run the appropriate @@ -162,24 +164,28 @@ refleak = dash_R(the_module, test, test_runner, huntrleaks) test_time = time.time() - start_time except support.ResourceDenied as msg: - if not quiet: + if not quiet and not pgo: print(test, "skipped --", msg, flush=True) return RESOURCE_DENIED, test_time except unittest.SkipTest as msg: - if not quiet: + if not quiet and not pgo: print(test, "skipped --", msg, flush=True) return SKIPPED, test_time except KeyboardInterrupt: raise except support.TestFailed as msg: - if display_failure: - print("test", test, "failed --", msg, file=sys.stderr, flush=True) - else: - print("test", test, "failed", file=sys.stderr, flush=True) + if not pgo: + if display_failure: + print("test", test, "failed --", msg, file=sys.stderr, + flush=True) + else: + print("test", test, "failed", file=sys.stderr, flush=True) return FAILED, test_time except: msg = traceback.format_exc() - print("test", test, "crashed --", msg, file=sys.stderr, flush=True) + if not pgo: + print("test", test, "crashed --", msg, file=sys.stderr, + flush=True) return FAILED, test_time else: if refleak: diff -r 4d699bf00be0 Lib/test/libregrtest/runtest_mp.py --- a/Lib/test/libregrtest/runtest_mp.py Fri Oct 02 15:09:51 2015 -0400 +++ b/Lib/test/libregrtest/runtest_mp.py Fri Oct 02 14:59:06 2015 -0700 @@ -42,6 +42,8 @@ '-X', 'faulthandler', '-m', 'test.regrtest', '--slaveargs', slaveargs] + if ns.pgo: + cmd += ['--pgo'] # Running the child from the same working directory as regrtest's original # invocation ensures that TEMPDIR for the child is the same when @@ -175,7 +177,7 @@ item = output.get(timeout=timeout) except queue.Empty: running = get_running(workers) - if running: + if running and not regrtest.ns.pgo: print('running: %s' % ', '.join(running)) continue @@ -189,17 +191,18 @@ text = test ok, test_time = result if (ok not in (CHILD_ERROR, INTERRUPTED) - and test_time >= PROGRESS_MIN_TIME): + and test_time >= PROGRESS_MIN_TIME + and not regrtest.ns.pgo): text += ' (%.0f sec)' % test_time running = get_running(workers) - if running: + if running and not regrtest.ns.pgo: text += ' -- running: %s' % ', '.join(running) regrtest.display_progress(test_index, text) # Copy stdout and stderr from the child process if stdout: print(stdout, flush=True) - if stderr: + if stderr and not regrtest.ns.pgo: print(stderr, file=sys.stderr, flush=True) if result[0] == INTERRUPTED: diff -r 4d699bf00be0 Lib/test/libregrtest/save_env.py --- a/Lib/test/libregrtest/save_env.py Fri Oct 02 15:09:51 2015 -0400 +++ b/Lib/test/libregrtest/save_env.py Fri Oct 02 14:59:06 2015 -0700 @@ -41,10 +41,11 @@ changed = False - def __init__(self, testname, verbose=0, quiet=False): + def __init__(self, testname, verbose=0, quiet=False, *, pgo=False): self.testname = testname self.verbose = verbose self.quiet = quiet + self.pgo = pgo # To add things to save and restore, add a name XXX to the resources list # and add corresponding get_XXX/restore_XXX functions. get_XXX should @@ -273,7 +274,7 @@ if current != original: self.changed = True restore(original) - if not self.quiet: + if not self.quiet and not self.pgo: print("Warning -- {} was modified by {}".format( name, self.testname), file=sys.stderr) diff -r 4d699bf00be0 Makefile.pre.in --- a/Makefile.pre.in Fri Oct 02 15:09:51 2015 -0400 +++ b/Makefile.pre.in Fri Oct 02 14:59:06 2015 -0700 @@ -231,7 +231,7 @@ TCLTK_LIBS= @TCLTK_LIBS@ # The task to run while instrument when building the profile-opt target -PROFILE_TASK=-m test.regrtest >/dev/null 2>&1 +PROFILE_TASK=-m test.regrtest --pgo # report files for gcov / lcov coverage report COVERAGE_INFO= $(abs_builddir)/coverage.info @@ -493,7 +493,7 @@ $(MAKE) profile-removal $(MAKE) build_all_generate_profile $(MAKE) profile-removal - @echo "Running code to generate profile data (this can take a while):" + @echo "Running code to generate profile data (errors do not affect results; this process can take a while):" $(MAKE) run_profile_task $(MAKE) build_all_merge_profile @echo "Rebuilding with profile guided optimizations:"