Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC

Commits:

6 changed files:

Changes:

  • libraries/base/tests/all.T
    ... ... @@ -243,7 +243,7 @@ test('T8684', expect_broken(8684), compile_and_run, [''])
    243 243
     test('hWaitForInput-accurate-stdin', [js_broken(22349), expect_broken_for(16535, threaded_ways), req_process], compile_and_run, [''])
    
    244 244
     test('T9826',normal, compile_and_run,[''])
    
    245 245
     test('T9848',
    
    246
    -        [ collect_stats('bytes allocated')
    
    246
    +        [ collect_stats('bytes allocated', 2)
    
    247 247
             , only_ways(['normal'])
    
    248 248
             , js_broken(22261)
    
    249 249
             ],
    

  • testsuite/driver/README.md
    ... ... @@ -35,11 +35,13 @@ differences, and things such as that are not necessary to be considered by the
    35 35
     test writer anymore. This is due to the fact that the test comparison relies
    
    36 36
     entirely on locally collected metrics on the testing machine.
    
    37 37
     
    
    38
    -As such, it is perfectly sufficient to write `collect_stats('all',20)` in the
    
    39
    -".T" files to measure the 3 potential stats that can be collected for that test
    
    40
    -and automatically test them for regressions, failing if there is more than a 20%
    
    41
    -change in any direction. In fact, even that is not necessary as
    
    42
    -`collect_stats()` defaults to 'all', and 20% deviation allowed.
    
    38
    +A test states which metric to measure and how much deviation to allow, e.g.
    
    39
    +`collect_stats('bytes allocated', 2)` in the ".T" files. Such a test fails if
    
    40
    +the metric changes by more than 2% in either direction. To gate several metrics,
    
    41
    +use one `collect_stats` call per metric, so that each gets a tolerance matched
    
    42
    +to its noise profile: allocations are nearly deterministic and support tight
    
    43
    +windows, while the residency metrics need considerably slacker ones (see
    
    44
    +Note [Measuring residency] in testlib.py).
    
    43 45
     
    
    44 46
     The function `collect_compiler_stats()` is completely equivalent in every way to
    
    45 47
     `collect_stats` except that it measures the performance of the compiler itself
    

  • testsuite/driver/testlib.py
    ... ... @@ -24,7 +24,7 @@ import subprocess
    24 24
     from testglobals import config, ghc_env, default_testopts, brokens, t, \
    
    25 25
                             TestRun, TestResult, TestOptions, PerfMetric
    
    26 26
     from testutil import strip_quotes, lndir, link_or_copy_file, passed, \
    
    27
    -                     failBecause, testing_metrics, residency_testing_metrics, \
    
    27
    +                     failBecause, residency_testing_metrics, \
    
    28 28
                          stable_perf_counters, \
    
    29 29
                          PassFail, badResult, str_warn, str_removeprefix
    
    30 30
     from term_color import Color, colored_if
    
    ... ... @@ -816,28 +816,20 @@ def _collect_generic_stat(name : TestName, opts, metric_infos):
    816 816
     
    
    817 817
     # -----
    
    818 818
     
    
    819
    -# Defaults to "test everything, and only break on extreme cases"
    
    820
    -#
    
    821
    -# The inputs to this function are slightly interesting:
    
    822
    -# metric can be either:
    
    823
    -#     - 'all', in which case all 3 possible metrics are collected and compared.
    
    824
    -#     - The specific metric one wants to use in the test.
    
    825
    -#     - A set of the metrics one wants to use in the test.
    
    826
    -#
    
    827
    -# Deviation defaults to 20% because the goal is correctness over performance.
    
    828
    -# The testsuite should avoid breaking when there is not an actual error.
    
    829
    -# Instead, the testsuite should notify of regressions in a non-breaking manner.
    
    819
    +# metric is either a single metric name or a set of metric names. Use one
    
    820
    +# call per metric so each gets a tolerance matched to its noise profile.
    
    821
    +# See Note [Measuring residency] for the residency metrics.
    
    830 822
     #
    
    831 823
     # collect_compiler_stats is used when the metrics collected are about the compiler.
    
    832 824
     # collect_stats is used in the majority case when the metrics to be collected
    
    833 825
     # are about the performance of the runtime code generated by the compiler.
    
    834
    -def collect_compiler_stats(metric='all',deviation=20):
    
    826
    +def collect_compiler_stats(metric, deviation):
    
    835 827
         def f(name, opts, m=metric, d=deviation):
    
    836 828
             no_lint(name, opts)
    
    837 829
             return _collect_stats(name, opts, m, d, None, True)
    
    838 830
         return f
    
    839 831
     
    
    840
    -def collect_stats(metric='all', deviation=20, static_stats_file=None):
    
    832
    +def collect_stats(metric, deviation, static_stats_file=None):
    
    841 833
         return lambda name, opts, m=metric, d=deviation, s=static_stats_file: _collect_stats(name, opts, m, d, s)
    
    842 834
     
    
    843 835
     def statsFile(comp_test: bool, name: str) -> str:
    
    ... ... @@ -864,12 +856,9 @@ def _collect_stats(name: TestName, opts, metrics, deviation: Optional[int],
    864 856
             # This is a bit weird, though.
    
    865 857
             return
    
    866 858
     
    
    867
    -    # Normalize metrics to a list of strings.
    
    859
    +    # Normalize metrics to a set of strings.
    
    868 860
         if isinstance(metrics, str):
    
    869
    -        if metrics == 'all':
    
    870
    -            metrics = testing_metrics()
    
    871
    -        else:
    
    872
    -            metrics = { metrics }
    
    861
    +        metrics = { metrics }
    
    873 862
     
    
    874 863
         opts.is_stats_test = True
    
    875 864
         if is_compiler_stats_test:
    

  • testsuite/tests/perf/compiler/all.T
    ... ... @@ -638,13 +638,15 @@ test ('T15164',
    638 638
           ],
    
    639 639
           compile,
    
    640 640
           ['-v0 -O'])
    
    641
    +# T15630/T15630a guard against exponential simplifier blowup when inlining
    
    642
    +# join points (#15630).
    
    641 643
     test('T15630',
    
    642
    -      [collect_compiler_stats()
    
    644
    +      [collect_compiler_stats('bytes allocated', 2)
    
    643 645
           ],
    
    644 646
           compile,
    
    645 647
           ['-O2'])
    
    646 648
     test('T15630a',
    
    647
    -      [collect_compiler_stats()
    
    649
    +      [collect_compiler_stats('bytes allocated', 2)
    
    648 650
           ],
    
    649 651
           compile,
    
    650 652
           ['-O2'])
    
    ... ... @@ -768,12 +770,17 @@ test ('T9198',
    768 770
           compile,
    
    769 771
           [''])
    
    770 772
     
    
    773
    +# Guards against quadratic demand-analysis cost on wide recursive data
    
    774
    +# types, which manifested as a compile-time memory blowup (#11545).
    
    771 775
     test('T11545',
    
    772
    -     [ collect_compiler_stats('all', 15) ],
    
    776
    +     [ collect_compiler_stats('bytes allocated', 2)
    
    777
    +     , collect_compiler_residency(15) ],
    
    773 778
          compile, ['-O'])
    
    774 779
     
    
    780
    +# Guards against the compile-time memory blowup of #15304
    
    775 781
     test('T15304',
    
    776
    -     [ collect_compiler_stats('all', 10) ],
    
    782
    +     [ collect_compiler_stats('bytes allocated', 2)
    
    783
    +     , collect_compiler_residency(10) ],
    
    777 784
          compile, ['-O'])
    
    778 785
     test ('T20049',
    
    779 786
           [ collect_compiler_stats('bytes allocated',2) ],
    
    ... ... @@ -795,8 +802,10 @@ test('T16875', # Testing one hole-fit with a lot in scope for #16875
    795 802
          collect_compiler_runtime(4),
    
    796 803
          compile, ['-fdefer-type-errors -fno-max-valid-hole-fits -package ghc'])
    
    797 804
     
    
    805
    +# Guards against renamer/typechecker allocation regressions on very large
    
    806
    +# generated modules (#20261, a Happy-generated parser).
    
    798 807
     test ('T20261',
    
    799
    -      [collect_compiler_stats('all')],
    
    808
    +      [collect_compiler_stats('bytes allocated', 2)],
    
    800 809
           compile,
    
    801 810
           [''])
    
    802 811
     
    
    ... ... @@ -805,8 +814,7 @@ test ('T20261',
    805 814
     # does not sensibly handle one test acting as both
    
    806 815
     # a compile-time and a run-time performance test
    
    807 816
     test('T21839c',
    
    808
    -    [   collect_compiler_stats('all', 10),
    
    809
    -        collect_compiler_runtime(1),
    
    817
    +    [   collect_compiler_runtime(1),
    
    810 818
             only_ways(['normal'])],
    
    811 819
         compile,
    
    812 820
         ['-O'])
    
    ... ... @@ -872,8 +880,10 @@ test('interpreter_steplocal',
    872 880
          ghci_script,
    
    873 881
          ['interpreter_steplocal.script'])
    
    874 882
     
    
    883
    +# Guards against the compile-time memory blowup of #26425
    
    875 884
     test ('T26425',
    
    876
    -      [ collect_compiler_stats('all',20) ],
    
    885
    +      [ collect_compiler_stats('bytes allocated', 2)
    
    886
    +      , collect_compiler_residency(20) ],
    
    877 887
           compile,
    
    878 888
           ['-O'])
    
    879 889
     
    

  • testsuite/tests/perf/compiler/large-project/all.T
    ... ... @@ -7,7 +7,7 @@ def large_project_makedepend(num):
    7 7
         return test(
    
    8 8
             f'large-project-makedepend-{num}',
    
    9 9
             [
    
    10
    -            collect_compiler_stats('bytes allocated'),
    
    10
    +            collect_compiler_stats('bytes allocated', 10),
    
    11 11
                 pre_cmd(f'./large-project.sh {num}'),
    
    12 12
                 extra_files(['large-project.sh']),
    
    13 13
                 ignore_stderr,
    

  • testsuite/tests/perf/space_leaks/all.T
    1 1
     setTestOpts(js_skip)
    
    2 2
     
    
    3 3
     test('space_leak_001',
    
    4
    -     # This could potentially be replaced with
    
    5
    -     # collect_stats('all',5) to test all 3 with
    
    6
    -     # 5% possible deviation.
    
    7 4
          [ collect_stats('bytes allocated',5),
    
    8 5
           collect_runtime_residency(15),
    
    9 6
           omit_ways(['profasm','profthreaded','threaded1','threaded2',