File: pipelines_build_script.py

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (153 lines) | stat: -rwxr-xr-x 5,218 bytes parent folder | download
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()