Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / third-party / benchmark / tools / strip_asm.py
blob086255dc657781bfb8a66ad2ac4644a951143a70
1 #!/usr/bin/env python
3 """
4 strip_asm.py - Cleanup ASM output for the specified file
5 """
7 from argparse import ArgumentParser
8 import sys
9 import os
10 import re
13 def find_used_labels(asm):
14 found = set()
15 label_re = re.compile("\s*j[a-z]+\s+\.L([a-zA-Z0-9][a-zA-Z0-9_]*)")
16 for l in asm.splitlines():
17 m = label_re.match(l)
18 if m:
19 found.add(".L%s" % m.group(1))
20 return found
23 def normalize_labels(asm):
24 decls = set()
25 label_decl = re.compile("^[.]{0,1}L([a-zA-Z0-9][a-zA-Z0-9_]*)(?=:)")
26 for l in asm.splitlines():
27 m = label_decl.match(l)
28 if m:
29 decls.add(m.group(0))
30 if len(decls) == 0:
31 return asm
32 needs_dot = next(iter(decls))[0] != "."
33 if not needs_dot:
34 return asm
35 for ld in decls:
36 asm = re.sub("(^|\s+)" + ld + "(?=:|\s)", "\\1." + ld, asm)
37 return asm
40 def transform_labels(asm):
41 asm = normalize_labels(asm)
42 used_decls = find_used_labels(asm)
43 new_asm = ""
44 label_decl = re.compile("^\.L([a-zA-Z0-9][a-zA-Z0-9_]*)(?=:)")
45 for l in asm.splitlines():
46 m = label_decl.match(l)
47 if not m or m.group(0) in used_decls:
48 new_asm += l
49 new_asm += "\n"
50 return new_asm
53 def is_identifier(tk):
54 if len(tk) == 0:
55 return False
56 first = tk[0]
57 if not first.isalpha() and first != "_":
58 return False
59 for i in range(1, len(tk)):
60 c = tk[i]
61 if not c.isalnum() and c != "_":
62 return False
63 return True
66 def process_identifiers(l):
67 """
68 process_identifiers - process all identifiers and modify them to have
69 consistent names across all platforms; specifically across ELF and MachO.
70 For example, MachO inserts an additional understore at the beginning of
71 names. This function removes that.
72 """
73 parts = re.split(r"([a-zA-Z0-9_]+)", l)
74 new_line = ""
75 for tk in parts:
76 if is_identifier(tk):
77 if tk.startswith("__Z"):
78 tk = tk[1:]
79 elif (
80 tk.startswith("_") and len(tk) > 1 and tk[1].isalpha() and tk[1] != "Z"
82 tk = tk[1:]
83 new_line += tk
84 return new_line
87 def process_asm(asm):
88 """
89 Strip the ASM of unwanted directives and lines
90 """
91 new_contents = ""
92 asm = transform_labels(asm)
94 # TODO: Add more things we want to remove
95 discard_regexes = [
96 re.compile("\s+\..*$"), # directive
97 re.compile("\s*#(NO_APP|APP)$"), # inline ASM
98 re.compile("\s*#.*$"), # comment line
99 re.compile("\s*\.globa?l\s*([.a-zA-Z_][a-zA-Z0-9$_.]*)"), # global directive
100 re.compile(
101 "\s*\.(string|asciz|ascii|[1248]?byte|short|word|long|quad|value|zero)"
104 keep_regexes = []
105 fn_label_def = re.compile("^[a-zA-Z_][a-zA-Z0-9_.]*:")
106 for l in asm.splitlines():
107 # Remove Mach-O attribute
108 l = l.replace("@GOTPCREL", "")
109 add_line = True
110 for reg in discard_regexes:
111 if reg.match(l) is not None:
112 add_line = False
113 break
114 for reg in keep_regexes:
115 if reg.match(l) is not None:
116 add_line = True
117 break
118 if add_line:
119 if fn_label_def.match(l) and len(new_contents) != 0:
120 new_contents += "\n"
121 l = process_identifiers(l)
122 new_contents += l
123 new_contents += "\n"
124 return new_contents
127 def main():
128 parser = ArgumentParser(description="generate a stripped assembly file")
129 parser.add_argument(
130 "input", metavar="input", type=str, nargs=1, help="An input assembly file"
132 parser.add_argument(
133 "out", metavar="output", type=str, nargs=1, help="The output file"
135 args, unknown_args = parser.parse_known_args()
136 input = args.input[0]
137 output = args.out[0]
138 if not os.path.isfile(input):
139 print(("ERROR: input file '%s' does not exist") % input)
140 sys.exit(1)
141 contents = None
142 with open(input, "r") as f:
143 contents = f.read()
144 new_contents = process_asm(contents)
145 with open(output, "w") as f:
146 f.write(new_contents)
149 if __name__ == "__main__":
150 main()
152 # vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
153 # kate: tab-width: 4; replace-tabs on; indent-width 4; tab-indents: off;
154 # kate: indent-mode python; remove-trailing-spaces modified;