Skip to content

Commit cc0e136

Browse files
committed
[utils] update_llc_test_checks --downstream-target-handler-path option
This patch adds a new option to update_llce_test_checks that points to a downstream python module implementing handler functions for a downstream compiler.
1 parent df28c81 commit cc0e136

File tree

5 files changed

+115
-3
lines changed

5 files changed

+115
-3
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
; RUN: llc < %s -mtriple=i686-- | FileCheck %s
2+
define void @foo() {
3+
ret void
4+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
; RUN: llc < %s -mtriple=i686-- | FileCheck %s
2+
define void @foo() {
3+
; CHECK-LABEL: foo:
4+
; CHECK: Test
5+
; CHECK-NEXT: Downstream
6+
; CHECK-NEXT: Target
7+
ret void
8+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# This is an example of a downstream module, which in this case is for i686.
2+
# The goal is to test the updater's downstream-target-module-path option.
3+
#
4+
# This target module implements a simple scrubber that returns a fixed string,
5+
# a regex that matches the fixed strings generated by the scrubber.
6+
#
7+
# This module needs to define:
8+
# 2. The `downstream_scrub(asm, arg)` scrubber function
9+
# 3. The `downstream_asm_fn_re` regex for matching func, body, etc.
10+
11+
import re
12+
import sys
13+
import os
14+
from pathlib import Path
15+
16+
common_dir = Path(__file__).parent / "../../../../../utils/"
17+
sys.path.append(common_dir)
18+
from UpdateTestChecks import common
19+
20+
21+
# The asm scrubber returns the scrubbed asm.
22+
# In this test we return a fixed string.
23+
def scrub(asm, args):
24+
return "Test\n" "Downstream\n" "Target\n"
25+
26+
27+
# The regular expression for matching func, body, etc.
28+
regex = re.compile(
29+
r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*(@"?(?P=func)"?| -- Begin function (?P=func))\n(?:\s*\.?Lfunc_begin[^:\n]*:\n)?'
30+
r"(?:\.L(?P=func)\$local:\n)?" # drop .L<func>$local:
31+
r"(?:\s*\.type\s+\.L(?P=func)\$local,@function\n)?" # drop .type .L<func>$local
32+
r"(?:[ \t]*(?:\.cfi_startproc|\.cfi_personality|\.cfi_lsda|\.seh_proc|\.seh_handler)\b[^\n]*\n)*" # drop optional cfi
33+
r"(?P<body>^##?[ \t]+[^:]+:.*?)\s*"
34+
r"^\s*(?:[^:\n]+?:\s*\n\s*\.size|\.cfi_endproc|\.globl|\.comm|\.(?:sub)?section|#+ -- End function)",
35+
flags=(re.M | re.S),
36+
)
37+
38+
39+
def get_run_handler(triple):
40+
return (scrub, regex)
41+
42+
43+
def add_checks(
44+
output_lines,
45+
comment_marker,
46+
prefix_list,
47+
func_dict,
48+
func_name,
49+
ginfo: common.GeneralizerInfo,
50+
global_vars_seen_dict,
51+
is_filtered,
52+
):
53+
# Label format is based on ASM string.
54+
check_label_format = "{} %s-LABEL: %s%s%s%s".format(comment_marker)
55+
return common.add_checks(
56+
output_lines,
57+
comment_marker,
58+
prefix_list,
59+
func_dict,
60+
func_name,
61+
check_label_format,
62+
ginfo,
63+
global_vars_seen_dict,
64+
is_filtered=is_filtered,
65+
)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# REQUIRES: x86-registered-target
2+
## Tests that the downstream module support works
3+
4+
# RUN: cp -f %S/Inputs/downstream_target.ll %t.ll && %update_llc_test_checks %t.ll --downstream-target-handler-path=%S/Inputs/downstream_target.py
5+
# RUN: grep -v '^; NOTE:' %t.ll > %t.ll.expected
6+
# RUN: diff -b -u %S/Inputs/downstream_target.ll.expected %t.ll.expected
7+

llvm/utils/update_llc_test_checks.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
import argparse
1313
import os # Used to advertise this file's name ("autogenerated_note").
14+
import sys
15+
import importlib.util
1416

1517
from UpdateTestChecks import common
1618

@@ -21,6 +23,19 @@
2123
]
2224

2325

26+
# Helper that imports module from `module_path` and returns it.
27+
def import_module(module_path):
28+
if not os.path.exists(module_path):
29+
common.error("Path does not exist", module_path)
30+
sys.exit(1)
31+
module_name_with_ext = os.path.basename(module_path)
32+
module_name = os.path.splitext(module_name_with_ext)[0]
33+
spec = importlib.util.spec_from_file_location(module_name, module_path)
34+
module = importlib.util.module_from_spec(spec)
35+
sys.modules[module_name] = module
36+
spec.loader.exec_module(module)
37+
return module
38+
2439
def main():
2540
parser = argparse.ArgumentParser(description=__doc__)
2641
parser.add_argument(
@@ -67,6 +82,12 @@ def main():
6782
help="Set a default -march for when neither triple nor arch are found in a RUN line",
6883
)
6984
parser.add_argument("tests", nargs="+")
85+
parser.add_argument(
86+
"--downstream-target-handler-path",
87+
default=None,
88+
dest="downstream_target_handler_path",
89+
help="The path of a python module that implements the scrubber and the regex generator and adds it to the targets handlers map for a downstream target",
90+
)
7091
initial_args = common.parse_commandline_args(parser)
7192

7293
script_name = os.path.basename(__file__)
@@ -107,10 +128,17 @@ def main():
107128
march_in_cmd = m.groups()[0]
108129

109130
m = common.DEBUG_ONLY_ARG_RE.search(llc_cmd)
110-
if m and m.groups()[0] == "isel":
111-
from UpdateTestChecks import isel as output_type
131+
if initial_args.downstream_target_handler_path:
132+
common.warn(
133+
"Downstream handlers provided by '%s'"
134+
% initial_args.downstream_target_handler_path
135+
)
136+
output_type = import_module(initial_args.downstream_target_handler_path)
112137
else:
113-
from UpdateTestChecks import asm as output_type
138+
if m and m.groups()[0] == "isel":
139+
from UpdateTestChecks import isel as output_type
140+
else:
141+
from UpdateTestChecks import asm as output_type
114142

115143
common.verify_filecheck_prefixes(filecheck_cmd)
116144

0 commit comments

Comments
 (0)