Skip to content

Commit d9e9519

Browse files
committed
move MIR parsing code to the common
1 parent 5f596b6 commit d9e9519

File tree

3 files changed

+117
-119
lines changed

3 files changed

+117
-119
lines changed

llvm/utils/UpdateTestChecks/common.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2404,6 +2404,121 @@ def add_analyze_checks(
24042404
MIR_BASIC_BLOCK_RE = re.compile(r" *bb\.[0-9]+.*:$")
24052405
MIR_PREFIX_DATA_RE = re.compile(r"^ *(;|bb.[0-9].*: *$|[a-z]+:( |$)|$)")
24062406

2407+
# Patterns for MIR function parsing
2408+
VREG_RE = re.compile(r"(%[0-9]+)(?:\.[a-z0-9_]+)?(?::[a-z0-9_]+)?(?:\([<>a-z0-9 ]+\))?")
2409+
MI_FLAGS_STR = (
2410+
r"(frame-setup |frame-destroy |nnan |ninf |nsz |arcp |contract |afn "
2411+
r"|reassoc |nuw |nsw |exact |nofpexcept |nomerge |unpredictable "
2412+
r"|noconvergent |nneg |disjoint |nusw |samesign |inbounds )*"
2413+
)
2414+
VREG_DEF_FLAGS_STR = r"(?:dead |undef )*"
2415+
2416+
# Pattern to match the defined vregs and the opcode of an instruction that
2417+
# defines vregs. Opcodes starting with a lower-case 't' are allowed to match
2418+
# ARM's thumb instructions, like tADDi8 and t2ADDri.
2419+
VREG_DEF_RE = re.compile(
2420+
r"^ *(?P<vregs>{2}{0}(?:, {2}{0})*) = "
2421+
r"{1}(?P<opcode>[A-Zt][A-Za-z0-9_]+)".format(
2422+
VREG_RE.pattern, MI_FLAGS_STR, VREG_DEF_FLAGS_STR
2423+
)
2424+
)
2425+
2426+
MIR_FUNC_RE = re.compile(
2427+
r"^---$"
2428+
r"\n"
2429+
r"^ *name: *(?P<func>[A-Za-z0-9_.-]+)$"
2430+
r".*?"
2431+
r"(?:^ *fixedStack: *(\[\])? *\n"
2432+
r"(?P<fixedStack>.*?)\n?"
2433+
r"^ *stack:"
2434+
r".*?)?"
2435+
r"^ *body: *\|\n"
2436+
r"(?P<body>.*?)\n"
2437+
r"^\.\.\.$",
2438+
flags=(re.M | re.S),
2439+
)
2440+
2441+
2442+
def mangle_vreg(opcode, current_names):
2443+
base = opcode
2444+
# Simplify some common prefixes and suffixes
2445+
if opcode.startswith("G_"):
2446+
base = base[len("G_") :]
2447+
if opcode.endswith("_PSEUDO"):
2448+
base = base[: -len("_PSEUDO")]
2449+
# Shorten some common opcodes with long-ish names
2450+
base = dict(
2451+
IMPLICIT_DEF="DEF",
2452+
GLOBAL_VALUE="GV",
2453+
CONSTANT="C",
2454+
FCONSTANT="C",
2455+
MERGE_VALUES="MV",
2456+
UNMERGE_VALUES="UV",
2457+
INTRINSIC="INT",
2458+
INTRINSIC_W_SIDE_EFFECTS="INT",
2459+
INSERT_VECTOR_ELT="IVEC",
2460+
EXTRACT_VECTOR_ELT="EVEC",
2461+
SHUFFLE_VECTOR="SHUF",
2462+
).get(base, base)
2463+
# Avoid ambiguity when opcodes end in numbers
2464+
if len(base.rstrip("0123456789")) < len(base):
2465+
base += "_"
2466+
2467+
i = 0
2468+
for name in current_names:
2469+
if name.rstrip("0123456789") == base:
2470+
i += 1
2471+
if i:
2472+
return "{}{}".format(base, i)
2473+
return base
2474+
2475+
2476+
def build_function_info_dictionary(
2477+
test, raw_tool_output, triple, prefixes, func_dict, verbose
2478+
):
2479+
for m in MIR_FUNC_RE.finditer(raw_tool_output):
2480+
func = m.group("func")
2481+
fixedStack = m.group("fixedStack")
2482+
body = m.group("body")
2483+
if verbose:
2484+
debug("Processing function: {}".format(func))
2485+
for l in body.splitlines():
2486+
debug(" {}".format(l))
2487+
2488+
# Vreg mangling
2489+
mangled = []
2490+
vreg_map = {}
2491+
for func_line in body.splitlines(keepends=True):
2492+
m = VREG_DEF_RE.match(func_line)
2493+
if m:
2494+
for vreg in VREG_RE.finditer(m.group("vregs")):
2495+
if vreg.group(1) in vreg_map:
2496+
name = vreg_map[vreg.group(1)]
2497+
else:
2498+
name = mangle_vreg(m.group("opcode"), vreg_map.values())
2499+
vreg_map[vreg.group(1)] = name
2500+
func_line = func_line.replace(
2501+
vreg.group(1), "[[{}:%[0-9]+]]".format(name), 1
2502+
)
2503+
for number, name in vreg_map.items():
2504+
func_line = re.sub(
2505+
r"{}\b".format(number), "[[{}]]".format(name), func_line
2506+
)
2507+
mangled.append(func_line)
2508+
body = "".join(mangled)
2509+
2510+
for prefix in prefixes:
2511+
info = function_body(body, fixedStack, None, None, None, None, ginfo=None)
2512+
if func in func_dict[prefix]:
2513+
if (
2514+
not func_dict[prefix][func]
2515+
or func_dict[prefix][func].scrub != info.scrub
2516+
or func_dict[prefix][func].extrascrub != info.extrascrub
2517+
):
2518+
func_dict[prefix][func] = None
2519+
else:
2520+
func_dict[prefix][func] = info
2521+
24072522

24082523
def find_mir_functions_with_one_bb(lines, verbose=False):
24092524
result = []

llvm/utils/update_llc_test_checks.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import sys
1717

1818
from UpdateTestChecks import common
19-
import update_mir_test_checks # Reuse MIR parsing code.
2019

2120
# llc is the only llc-like in the LLVM tree but downstream forks can add
2221
# additional ones here if they have them.
@@ -156,7 +155,7 @@ def update_test(ti: common.TestInfo):
156155
if prefix not in mir_func_dict:
157156
mir_func_dict[prefix] = {}
158157

159-
update_mir_test_checks.build_function_info_dictionary(
158+
common.build_function_info_dictionary(
160159
ti.path,
161160
raw_tool_output,
162161
triple,

llvm/utils/update_mir_test_checks.py

Lines changed: 1 addition & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -32,39 +32,6 @@
3232

3333
from UpdateTestChecks import common
3434

35-
VREG_RE = re.compile(r"(%[0-9]+)(?:\.[a-z0-9_]+)?(?::[a-z0-9_]+)?(?:\([<>a-z0-9 ]+\))?")
36-
MI_FLAGS_STR = (
37-
r"(frame-setup |frame-destroy |nnan |ninf |nsz |arcp |contract |afn "
38-
r"|reassoc |nuw |nsw |exact |nofpexcept |nomerge |unpredictable "
39-
r"|noconvergent |nneg |disjoint |nusw |samesign |inbounds )*"
40-
)
41-
VREG_DEF_FLAGS_STR = r"(?:dead |undef )*"
42-
43-
# Pattern to match the defined vregs and the opcode of an instruction that
44-
# defines vregs. Opcodes starting with a lower-case 't' are allowed to match
45-
# ARM's thumb instructions, like tADDi8 and t2ADDri.
46-
VREG_DEF_RE = re.compile(
47-
r"^ *(?P<vregs>{2}{0}(?:, {2}{0})*) = "
48-
r"{1}(?P<opcode>[A-Zt][A-Za-z0-9_]+)".format(
49-
VREG_RE.pattern, MI_FLAGS_STR, VREG_DEF_FLAGS_STR
50-
)
51-
)
52-
53-
MIR_FUNC_RE = re.compile(
54-
r"^---$"
55-
r"\n"
56-
r"^ *name: *(?P<func>[A-Za-z0-9_.-]+)$"
57-
r".*?"
58-
r"(?:^ *fixedStack: *(\[\])? *\n"
59-
r"(?P<fixedStack>.*?)\n?"
60-
r"^ *stack:"
61-
r".*?)?"
62-
r"^ *body: *\|\n"
63-
r"(?P<body>.*?)\n"
64-
r"^\.\.\.$",
65-
flags=(re.M | re.S),
66-
)
67-
6835

6936
class LLC:
7037
def __init__(self, bin):
@@ -143,89 +110,6 @@ def build_run_list(test, run_lines, verbose=False):
143110
return run_list
144111

145112

146-
def build_function_info_dictionary(
147-
test, raw_tool_output, triple, prefixes, func_dict, verbose
148-
):
149-
for m in MIR_FUNC_RE.finditer(raw_tool_output):
150-
func = m.group("func")
151-
fixedStack = m.group("fixedStack")
152-
body = m.group("body")
153-
if verbose:
154-
log("Processing function: {}".format(func))
155-
for l in body.splitlines():
156-
log(" {}".format(l))
157-
158-
# Vreg mangling
159-
mangled = []
160-
vreg_map = {}
161-
for func_line in body.splitlines(keepends=True):
162-
m = VREG_DEF_RE.match(func_line)
163-
if m:
164-
for vreg in VREG_RE.finditer(m.group("vregs")):
165-
if vreg.group(1) in vreg_map:
166-
name = vreg_map[vreg.group(1)]
167-
else:
168-
name = mangle_vreg(m.group("opcode"), vreg_map.values())
169-
vreg_map[vreg.group(1)] = name
170-
func_line = func_line.replace(
171-
vreg.group(1), "[[{}:%[0-9]+]]".format(name), 1
172-
)
173-
for number, name in vreg_map.items():
174-
func_line = re.sub(
175-
r"{}\b".format(number), "[[{}]]".format(name), func_line
176-
)
177-
mangled.append(func_line)
178-
body = "".join(mangled)
179-
180-
for prefix in prefixes:
181-
info = common.function_body(
182-
body, fixedStack, None, None, None, None, ginfo=None
183-
)
184-
if func in func_dict[prefix]:
185-
if (
186-
not func_dict[prefix][func]
187-
or func_dict[prefix][func].scrub != info.scrub
188-
or func_dict[prefix][func].extrascrub != info.extrascrub
189-
):
190-
func_dict[prefix][func] = None
191-
else:
192-
func_dict[prefix][func] = info
193-
194-
195-
def mangle_vreg(opcode, current_names):
196-
base = opcode
197-
# Simplify some common prefixes and suffixes
198-
if opcode.startswith("G_"):
199-
base = base[len("G_") :]
200-
if opcode.endswith("_PSEUDO"):
201-
base = base[: len("_PSEUDO")]
202-
# Shorten some common opcodes with long-ish names
203-
base = dict(
204-
IMPLICIT_DEF="DEF",
205-
GLOBAL_VALUE="GV",
206-
CONSTANT="C",
207-
FCONSTANT="C",
208-
MERGE_VALUES="MV",
209-
UNMERGE_VALUES="UV",
210-
INTRINSIC="INT",
211-
INTRINSIC_W_SIDE_EFFECTS="INT",
212-
INSERT_VECTOR_ELT="IVEC",
213-
EXTRACT_VECTOR_ELT="EVEC",
214-
SHUFFLE_VECTOR="SHUF",
215-
).get(base, base)
216-
# Avoid ambiguity when opcodes end in numbers
217-
if len(base.rstrip("0123456789")) < len(base):
218-
base += "_"
219-
220-
i = 0
221-
for name in current_names:
222-
if name.rstrip("0123456789") == base:
223-
i += 1
224-
if i:
225-
return "{}{}".format(base, i)
226-
return base
227-
228-
229113
def update_test_file(args, test, autogenerated_note):
230114
with open(test) as fd:
231115
input_lines = [l.rstrip() for l in fd]
@@ -247,7 +131,7 @@ def update_test_file(args, test, autogenerated_note):
247131
common.warn("No triple found: skipping file", test_file=test)
248132
return
249133

250-
build_function_info_dictionary(
134+
common.build_function_info_dictionary(
251135
test,
252136
raw_tool_output,
253137
triple_in_cmd or triple_in_ir,

0 commit comments

Comments
 (0)