1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
#!/usr/bin/env python3
import argparse
import os
import subprocess
import sys
import textwrap
# Append the src dir
sys.path.append(os.path.join(os.path.dirname(
os.path.dirname(os.path.abspath(__file__))), 'src'))
import passes # noqa (E402 module level import not at top of file)
# TODO: This should not be hard coded.
PIPELINES = ["PreSpecialize", "HighLevel", "EarlyLoopOpt",
"MidLevelOpt", "Lower", "LowLevel", "LateLoopOpt"]
PASSES = [p.name for p in passes.PASSES]
DEFAULT_PRESENTS = \
"--preset=buildbot_incremental_extra_swift_args,tools=RA,stdlib=RD"
def run_build_script_with_data_file(build_script, data_file, verbose=False):
build_script_args = [
build_script,
DEFAULT_PRESENTS,
r'extra_swift_args=^Swift$;-Xfrontend\;' +
r'-external-pass-pipeline-filename\;-Xfrontend\;%s' % data_file]
sys.stdout.write("Running build script with: %s..." %
' '.join(build_script_args))
sys.stdout.flush()
if not verbose:
p = subprocess.Popen(
build_script_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output = p.stdout.readlines()
status = p.wait()
if status == 0:
sys.stdout.write(" Success!\n")
else:
sys.stdout.write(" Failure:\n")
sys.stdout.write(output)
sys.stdout.flush()
else:
p = subprocess.Popen(build_script_args)
status = p.wait()
if status == 0:
sys.stdout.write(" Success!\n")
else:
sys.stdout.write(" Failure:\n")
def build_disable_slice_pipelines(**kwargs):
pipeline_range = range(len(PIPELINES))
def get_pipeline_args(script, iter):
result = [script]
for j in iter:
result.extend(['--disable-passpipeline', PIPELINES[j]])
return result
for i in pipeline_range:
pipeline_args = get_pipeline_args(
kwargs['pipeline_script'], pipeline_range[:i + 1])
data_file = os.path.join(
kwargs['output_dir'],
"pipeline-slice-%.2d-disabled-pipeline.json" % i)
with open(data_file, 'w') as f:
f.write(subprocess.check_output(pipeline_args))
run_build_script_with_data_file(
kwargs['build_script'], data_file, verbose=kwargs['verbose'])
def build_disable_individual_pass(**kwargs):
pass_name = kwargs['pass_name']
data_file = os.path.join(
kwargs['output_dir'], "%s-disabled-pass.json" % pass_name)
with open(data_file, 'w') as f:
f.write(subprocess.check_output(
[kwargs['pipeline_script'], '--disable-pass', pass_name]))
run_build_script_with_data_file(
kwargs['build_script'], data_file, verbose=kwargs['verbose'])
def build_disable_individual_passes(**kwargs):
for p in PASSES:
d = dict(kwargs)
d['pass_name'] = p
build_disable_individual_pass(**d)
def add_default_parser_args(p):
p.add_argument('pipeline_script', help=textwrap.dedent("""
The path to normal_pipeline.py. In the future could be generalized to take
other files.
"""))
p.add_argument('build_script', help=textwrap.dedent("""
The path to build-script.
"""))
p.add_argument('output_dir', help=textwrap.dedent("""
The output directory to use.
"""))
p.add_argument('-v', action='store_true', dest='verbose',
help=textwrap.dedent("""
Emit verbose output from build-script.
"""))
def main():
parser = argparse.ArgumentParser(
description="Run build-script with various passes disabled")
subparsers = parser.add_subparsers(help="The specific action to perform")
slice_pipeline_parser = subparsers.add_parser(
'disable_slice_pipelines',
description=textwrap.dedent("""
Go through all predefined pass pipelines and run build_script with only
specific slices enabled. Currently what this means is that we perform
the normal pipeline order, stopping after N pipelines have run.
"""))
slice_pipeline_parser.set_defaults(func=build_disable_slice_pipelines)
add_default_parser_args(slice_pipeline_parser)
disable_individual_passes_parser = subparsers.add_parser(
'disable_individual_passes',
description=textwrap.dedent("""
Loop over all predefines passes and run build_script once for each pass
with that pass disabled.
"""))
disable_individual_passes_parser.set_defaults(
func=build_disable_individual_passes)
add_default_parser_args(disable_individual_passes_parser)
disable_individual_pass_parser = subparsers.add_parser(
'disable_individual_pass',
description=textwrap.dedent("""
Run build-script disabling only the specified passes.
"""))
disable_individual_pass_parser.add_argument(
'pass_name',
help="The pass to disable",
choices=PASSES,
type=str)
disable_individual_pass_parser.set_defaults(
func=build_disable_individual_pass)
add_default_parser_args(disable_individual_pass_parser)
args = parser.parse_args()
args.func(**vars(args))
if __name__ == "__main__":
main()
|