blob: 0ed8a163a5415d57075db1d538968a9da727917b [file] [log] [blame]
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ===--- bench_code_size -------------------------------------------------===//
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See https://swift.org/LICENSE.txt for license information
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
#
# ===---------------------------------------------------------------------===//
#
# Reports code size differences of two benchmark build directories
#
# ===---------------------------------------------------------------------===//
from __future__ import print_function
import argparse
import glob
import os
import subprocess
import sys
def main():
argparser = argparse.ArgumentParser()
argparser.add_argument(
'-O', action='append_const', const='O', dest='opt_levels',
help='report code size of -O benchmarks')
argparser.add_argument(
'-Osize', action='append_const', const='Osize', dest='opt_levels',
help='report code size of -Osize benchmarks')
argparser.add_argument(
'-Onone', action='append_const', const='Onone', dest='opt_levels',
help='report code size of -Onone benchmarks')
argparser.add_argument(
'-swiftlibs', action='append_const', const='swiftlibs',
dest='opt_levels',
help='report code size of swift dylibs')
argparser.add_argument(
'oldbuilddir', nargs=1, type=str,
help='old benchmark build directory')
argparser.add_argument(
'newbuilddir', nargs=1, type=str,
help='new benchmark build directory')
argparser.add_argument(
'-platform', type=str,
help='The benchmark build platform', default='macosx')
args = argparser.parse_args()
for opt_level in args.opt_levels or ['O', 'Osize', 'Onone']:
report_code_size(opt_level, args.oldbuilddir[0], args.newbuilddir[0],
args.platform)
return 0
def report_code_size(opt_level, old_dir, new_dir, platform):
def log_filename(bench_dir):
return os.path.join(bench_dir, 'result_' + opt_level + '_size')
old_logf = open(log_filename(old_dir), 'w')
new_logf = open(log_filename(new_dir), 'w')
if opt_level == 'swiftlibs':
files = glob.glob(os.path.join(old_dir, 'lib', 'swift', platform,
'*.dylib'))
else:
files = glob.glob(os.path.join(old_dir,
opt_level + '-*' + platform + '*',
'*.o'))
idx = 1
for oldfile in files:
newfile = oldfile.replace(old_dir, new_dir, 1)
if os.path.isfile(newfile):
oldsize = get_codesize(oldfile)
newsize = get_codesize(newfile)
bname = os.path.basename(oldfile)
def write_line(value, logf):
v = ',' + str(value)
logf.write(str(idx) + ',' + bname + ',1' + (v * 3) +
',0' + v + '\n')
write_line(oldsize, old_logf)
write_line(newsize, new_logf)
idx += 1
old_logf.close()
new_logf.close()
print('Logfiles written to ' + log_filename(old_dir) + ' and ' +
log_filename(new_dir))
def get_codesize(filename):
output = subprocess.check_output(['size', filename]).splitlines()
header_line = output[0]
data_line = output[1]
if header_line.find('__TEXT') != 0:
sys.exit('unexpected output from size command:\n' + output)
return int(data_line.split('\t')[0])
if __name__ == '__main__':
sys.exit(main())