Commit 38367391 authored by Ian Lynagh's avatar Ian Lynagh
Browse files

Add support for compiler -t stats

parent d5999e77
......@@ -178,10 +178,11 @@ class TestOptions:
# which -t numeric fields do we want to look at, and what bounds must
# they fall within?
# Elements of this list should be things like
# Elements of these lists should be things like
# ('bytes allocated',
# 9300000000,
# 9400000000)
self.compiler_stats_num_fields = []
self.stats_num_fields = []
# should we run this test alone, i.e. not run it in parallel with
......
......@@ -222,6 +222,12 @@ def stats_num_field( field, min, max ):
def _stats_num_field( opts, f, x, y ):
opts.stats_num_fields = opts.stats_num_fields + [(f, x, y)]
def compiler_stats_num_field( field, min, max ):
return lambda opts, f=field, x=min, y=max: _compiler_stats_num_field(opts, f, x, y);
def _compiler_stats_num_field( opts, f, x, y ):
opts.compiler_stats_num_fields = opts.compiler_stats_num_fields + [(f, x, y)]
# -----
def skip_if_no_ghci(opts):
......@@ -255,7 +261,7 @@ def if_os( os, f ):
return normal
def if_wordsize( ws, f ):
if config.wordsize == ws:
if config.wordsize == str(ws):
return f
else:
return normal
......@@ -628,12 +634,8 @@ def do_compile( name, way, should_fail, top_mod, extra_hc_opts ):
pretest_cleanup(name)
result = simple_build( name, way, extra_hc_opts, should_fail, top_mod, 0 )
if should_fail:
if result == 0:
return 'fail'
else:
if result != 0:
return 'fail'
if result == 'fail':
return result
# the actual stderr should always match the expected, regardless
# of whether we expected the compilation to fail or not (successful
......@@ -667,9 +669,8 @@ def compile_and_run__( name, way, extra_hc_opts, top_mod ):
return extcore_run( name, way, extra_hc_opts, 0, top_mod )
else: # compiled...
result = simple_build( name, way, extra_hc_opts, 0, top_mod, 1 )
if result != 0:
return 'fail'
if result == 'fail':
return result
cmd = './' + name;
if getTestOpts().cmd_prefix != '':
......@@ -684,10 +685,40 @@ def compile_and_run( name, way, extra_hc_opts ):
def multimod_compile_and_run( name, way, top_mod, extra_hc_opts ):
return compile_and_run__( name, way, extra_hc_opts, top_mod)
# -----------------------------------------------------------------------------
# Check -t stats info
def checkStats(stats_file, num_fields):
if num_fields != []:
num_field_fail = False
f = open(in_testdir(stats_file))
contents = f.read()
f.close()
for (field, min, max) in num_fields:
m = re.search('\("' + field + '", "([0-9]+)"\)', contents)
if m == None:
print 'Failed to find field: ', field
return 'fail'
val = int(m.group(1))
if val < min:
print field, val, 'is less than minimum allowed', min
print 'If this is because you have improved GHC, please'
print 'update the test so that GHC doesn\'t regress again'
num_field_fail = True
if val > max:
print field, val, 'is more than maximum allowed', max
num_field_fail = True
if num_field_fail:
return 'fail'
# -----------------------------------------------------------------------------
# Build a single-module program
def simple_build( name, way, extra_hc_opts, should_fail, top_mod, link ):
opts = getTestOpts()
errname = add_suffix(name, 'comp.stderr')
rm_no_fail( errname )
rm_no_fail( name )
......@@ -702,11 +733,14 @@ def simple_build( name, way, extra_hc_opts, should_fail, top_mod, link ):
to_do = '--make -o ' + name
elif link:
to_do = '-o ' + name
elif getTestOpts().compile_to_hc:
elif opts.compile_to_hc:
to_do = '-C'
else:
to_do = '-c' # just compile
stats_file = name + '.comp.stats'
if opts.compiler_stats_num_fields != []:
extra_hc_opts += ' +RTS -t' + stats_file + ' --machine-readable -RTS'
cmd = 'cd ' + testdir + " && '" \
+ config.compiler + "' " \
......@@ -714,7 +748,7 @@ def simple_build( name, way, extra_hc_opts, should_fail, top_mod, link ):
+ to_do + ' ' + srcname + ' ' \
+ join(config.way_flags[way],' ') + ' ' \
+ extra_hc_opts + ' ' \
+ getTestOpts().extra_hc_opts + ' ' \
+ opts.extra_hc_opts + ' ' \
+ '>' + errname + ' 2>&1'
result = runCmd(cmd)
......@@ -726,7 +760,19 @@ def simple_build( name, way, extra_hc_opts, should_fail, top_mod, link ):
# ToDo: if the sub-shell was killed by ^C, then exit
return result
num_field_fail = checkStats(stats_file, opts.compiler_stats_num_fields)
if num_field_fail:
return 'fail'
if should_fail:
if result == 0:
return 'fail'
else:
if result != 0:
return 'fail'
return 'pass'
# -----------------------------------------------------------------------------
# Run a program and check its output
......@@ -759,8 +805,8 @@ def simple_run( name, way, prog, args ):
my_rts_flags = rts_flags(way)
stats_file = name + '.stats'
if opts.stats_num_fields != []:
stats_file = name + '.stats'
args += ' +RTS -t' + stats_file + ' --machine-readable -RTS'
if opts.no_stdin:
......@@ -801,30 +847,10 @@ def simple_run( name, way, prog, args ):
if check_prof and not check_prof_ok(name):
return 'fail'
if opts.stats_num_fields != []:
num_field_fail = False
f = open(in_testdir(stats_file))
contents = f.read()
f.close()
for (field, min, max) in opts.stats_num_fields:
m = re.search('\("' + field + '", "([0-9]+)"\)', contents)
if m == None:
print 'Failed to find field: ', field
return 'fail'
val = int(m.group(1))
if val < min:
print field, val, 'is less than minimum allowed', min
print 'If this is because you have improved GHC, please'
print 'update the test so that GHC doesn\'t regress again'
num_field_fail = True
if val > max:
print field, val, 'is more than maximum allowed', max
num_field_fail = True
num_field_fail = checkStats(stats_file, opts.stats_num_fields)
if num_field_fail:
return 'fail'
if num_field_fail:
return 'fail'
return 'pass'
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment