[RISCV] Refactor predicates for rvv intrinsic patterns.
[llvm-project.git] / llvm / utils / llvm-original-di-preservation.py
blob5b53e6ad3d67f9f2bf48bf6e041541810f95f660
1 #!/usr/bin/env python
3 # Debugify summary for the original debug info testing.
6 from __future__ import print_function
7 import argparse
8 import os
9 import sys
10 from json import loads
11 from collections import defaultdict
12 from collections import OrderedDict
14 class DILocBug:
15 def __init__(self, action, bb_name, fn_name, instr):
16 self.action = action
17 self.bb_name = bb_name
18 self.fn_name = fn_name
19 self.instr = instr
20 def __str__(self):
21 return self.action + self.bb_name + self.fn_name + self.instr
23 class DISPBug:
24 def __init__(self, action, fn_name):
25 self.action = action
26 self.fn_name = fn_name
27 def __str__(self):
28 return self.action + self.fn_name
30 class DIVarBug:
31 def __init__(self, action, name, fn_name):
32 self.action = action
33 self.name = name
34 self.fn_name = fn_name
35 def __str__(self):
36 return self.action + self.name + self.fn_name
38 # Report the bugs in form of html.
39 def generate_html_report(di_location_bugs, di_subprogram_bugs, di_var_bugs, \
40 di_location_bugs_summary, di_sp_bugs_summary, \
41 di_var_bugs_summary, html_file):
42 fileout = open(html_file, "w")
44 html_header = """ <html>
45 <head>
46 <style>
47 table, th, td {
48 border: 1px solid black;
50 table.center {
51 margin-left: auto;
52 margin-right: auto;
54 </style>
55 </head>
56 <body>
57 """
59 # Create the table for Location bugs.
60 table_title_di_loc = "Location Bugs found by the Debugify"
62 table_di_loc = """<table>
63 <caption><b>{}</b></caption>
64 <tr>
65 """.format(table_title_di_loc)
67 header_di_loc = ["File", "LLVM Pass Name", "LLVM IR Instruction", \
68 "Function Name", "Basic Block Name", "Action"]
70 for column in header_di_loc:
71 table_di_loc += " <th>{0}</th>\n".format(column.strip())
72 table_di_loc += " </tr>\n"
74 at_least_one_bug_found = False
76 # Handle loction bugs.
77 for file, per_file_bugs in di_location_bugs.items():
78 for llvm_pass, per_pass_bugs in per_file_bugs.items():
79 # No location bugs for the pass.
80 if len(per_pass_bugs) == 0:
81 continue
82 at_least_one_bug_found = True
83 row = []
84 table_di_loc += " </tr>\n"
85 # Get the bugs info.
86 for x in per_pass_bugs:
87 row.append(" <tr>\n")
88 row.append(file)
89 row.append(llvm_pass)
90 row.append(x.instr)
91 row.append(x.fn_name)
92 row.append(x.bb_name)
93 row.append(x.action)
94 row.append(" </tr>\n")
95 # Dump the bugs info into the table.
96 for column in row:
97 # The same file-pass pair can have multiple bugs.
98 if (column == " <tr>\n" or column == " </tr>\n"):
99 table_di_loc += column
100 continue
101 table_di_loc += " <td>{0}</td>\n".format(column.strip())
102 table_di_loc += " <tr>\n"
104 if not at_least_one_bug_found:
105 table_di_loc += """ <tr>
106 <td colspan='7'> No bugs found </td>
107 </tr>
109 table_di_loc += "</table>\n"
111 # Create the summary table for the loc bugs.
112 table_title_di_loc_sum = "Summary of Location Bugs"
113 table_di_loc_sum = """<table>
114 <caption><b>{}</b></caption>
115 <tr>
116 """.format(table_title_di_loc_sum)
118 header_di_loc_sum = ["LLVM Pass Name", "Number of bugs"]
120 for column in header_di_loc_sum:
121 table_di_loc_sum += " <th>{0}</th>\n".format(column.strip())
122 table_di_loc_sum += " </tr>\n"
124 # Print the summary.
125 row = []
126 for llvm_pass, num in sorted(di_location_bugs_summary.items()):
127 row.append(" <tr>\n")
128 row.append(llvm_pass)
129 row.append(str(num))
130 row.append(" </tr>\n")
131 for column in row:
132 if (column == " <tr>\n" or column == " </tr>\n"):
133 table_di_loc_sum += column
134 continue
135 table_di_loc_sum += " <td>{0}</td>\n".format(column.strip())
136 table_di_loc_sum += " <tr>\n"
138 if not at_least_one_bug_found:
139 table_di_loc_sum += """<tr>
140 <td colspan='2'> No bugs found </td>
141 </tr>
143 table_di_loc_sum += "</table>\n"
145 # Create the table for SP bugs.
146 table_title_di_sp = "SP Bugs found by the Debugify"
147 table_di_sp = """<table>
148 <caption><b>{}</b></caption>
149 <tr>
150 """.format(table_title_di_sp)
152 header_di_sp = ["File", "LLVM Pass Name", "Function Name", "Action"]
154 for column in header_di_sp:
155 table_di_sp += " <th>{0}</th>\n".format(column.strip())
156 table_di_sp += " </tr>\n"
158 at_least_one_bug_found = False
160 # Handle fn bugs.
161 for file, per_file_bugs in di_subprogram_bugs.items():
162 for llvm_pass, per_pass_bugs in per_file_bugs.items():
163 # No SP bugs for the pass.
164 if len(per_pass_bugs) == 0:
165 continue
166 at_least_one_bug_found = True
167 row = []
168 table_di_sp += " </tr>\n"
169 # Get the bugs info.
170 for x in per_pass_bugs:
171 row.append(" <tr>\n")
172 row.append(file)
173 row.append(llvm_pass)
174 row.append(x.fn_name)
175 row.append(x.action)
176 row.append(" </tr>\n")
177 # Dump the bugs info into the table.
178 for column in row:
179 # The same file-pass pair can have multiple bugs.
180 if (column == " <tr>\n" or column == " </tr>\n"):
181 table_di_sp += column
182 continue
183 table_di_sp += " <td>{0}</td>\n".format(column.strip())
184 table_di_sp += " <tr>\n"
186 if not at_least_one_bug_found:
187 table_di_sp += """<tr>
188 <td colspan='4'> No bugs found </td>
189 </tr>
191 table_di_sp += "</table>\n"
193 # Create the summary table for the sp bugs.
194 table_title_di_sp_sum = "Summary of SP Bugs"
195 table_di_sp_sum = """<table>
196 <caption><b>{}</b></caption>
197 <tr>
198 """.format(table_title_di_sp_sum)
200 header_di_sp_sum = ["LLVM Pass Name", "Number of bugs"]
202 for column in header_di_sp_sum:
203 table_di_sp_sum += " <th>{0}</th>\n".format(column.strip())
204 table_di_sp_sum += " </tr>\n"
206 # Print the summary.
207 row = []
208 for llvm_pass, num in sorted(di_sp_bugs_summary.items()):
209 row.append(" <tr>\n")
210 row.append(llvm_pass)
211 row.append(str(num))
212 row.append(" </tr>\n")
213 for column in row:
214 if (column == " <tr>\n" or column == " </tr>\n"):
215 table_di_sp_sum += column
216 continue
217 table_di_sp_sum += " <td>{0}</td>\n".format(column.strip())
218 table_di_sp_sum += " <tr>\n"
220 if not at_least_one_bug_found:
221 table_di_sp_sum += """<tr>
222 <td colspan='2'> No bugs found </td>
223 </tr>
225 table_di_sp_sum += "</table>\n"
227 # Create the table for Variable bugs.
228 table_title_di_var = "Variable Location Bugs found by the Debugify"
229 table_di_var = """<table>
230 <caption><b>{}</b></caption>
231 <tr>
232 """.format(table_title_di_var)
234 header_di_var = ["File", "LLVM Pass Name", "Variable", "Function", "Action"]
236 for column in header_di_var:
237 table_di_var += " <th>{0}</th>\n".format(column.strip())
238 table_di_var += " </tr>\n"
240 at_least_one_bug_found = False
242 # Handle var bugs.
243 for file, per_file_bugs in di_var_bugs.items():
244 for llvm_pass, per_pass_bugs in per_file_bugs.items():
245 # No SP bugs for the pass.
246 if len(per_pass_bugs) == 0:
247 continue
248 at_least_one_bug_found = True
249 row = []
250 table_di_var += " </tr>\n"
251 # Get the bugs info.
252 for x in per_pass_bugs:
253 row.append(" <tr>\n")
254 row.append(file)
255 row.append(llvm_pass)
256 row.append(x.name)
257 row.append(x.fn_name)
258 row.append(x.action)
259 row.append(" </tr>\n")
260 # Dump the bugs info into the table.
261 for column in row:
262 # The same file-pass pair can have multiple bugs.
263 if (column == " <tr>\n" or column == " </tr>\n"):
264 table_di_var += column
265 continue
266 table_di_var += " <td>{0}</td>\n".format(column.strip())
267 table_di_var += " <tr>\n"
269 if not at_least_one_bug_found:
270 table_di_var += """<tr>
271 <td colspan='4'> No bugs found </td>
272 </tr>
274 table_di_var += "</table>\n"
276 # Create the summary table for the sp bugs.
277 table_title_di_var_sum = "Summary of Variable Location Bugs"
278 table_di_var_sum = """<table>
279 <caption><b>{}</b></caption>
280 <tr>
281 """.format(table_title_di_var_sum)
283 header_di_var_sum = ["LLVM Pass Name", "Number of bugs"]
285 for column in header_di_var_sum:
286 table_di_var_sum += " <th>{0}</th>\n".format(column.strip())
287 table_di_var_sum += " </tr>\n"
289 # Print the summary.
290 row = []
291 for llvm_pass, num in sorted(di_var_bugs_summary.items()):
292 row.append(" <tr>\n")
293 row.append(llvm_pass)
294 row.append(str(num))
295 row.append(" </tr>\n")
296 for column in row:
297 if (column == " <tr>\n" or column == " </tr>\n"):
298 table_di_var_sum += column
299 continue
300 table_di_var_sum += " <td>{0}</td>\n".format(column.strip())
301 table_di_var_sum += " <tr>\n"
303 if not at_least_one_bug_found:
304 table_di_var_sum += """<tr>
305 <td colspan='2'> No bugs found </td>
306 </tr>
308 table_di_var_sum += "</table>\n"
310 # Finish the html page.
311 html_footer = """</body>
312 </html>"""
314 new_line = "<br>\n"
316 fileout.writelines(html_header)
317 fileout.writelines(table_di_loc)
318 fileout.writelines(new_line)
319 fileout.writelines(table_di_loc_sum)
320 fileout.writelines(new_line)
321 fileout.writelines(new_line)
322 fileout.writelines(table_di_sp)
323 fileout.writelines(new_line)
324 fileout.writelines(table_di_sp_sum)
325 fileout.writelines(new_line)
326 fileout.writelines(new_line)
327 fileout.writelines(table_di_var)
328 fileout.writelines(new_line)
329 fileout.writelines(table_di_var_sum)
330 fileout.writelines(html_footer)
331 fileout.close()
333 print("The " + html_file + " generated.")
335 # Read the JSON file in chunks.
336 def get_json_chunk(file,start,size):
337 json_parsed = None
338 di_checker_data = []
339 skipped_lines = 0
340 line = 0
342 # The file contains json object per line.
343 # An example of the line (formatted json):
345 # "file": "simple.c",
346 # "pass": "Deduce function attributes in RPO",
347 # "bugs": [
350 # "action": "drop",
351 # "metadata": "DISubprogram",
352 # "name": "fn2"
353 # },
355 # "action": "drop",
356 # "metadata": "DISubprogram",
357 # "name": "fn1"
362 with open(file) as json_objects_file:
363 for json_object_line in json_objects_file:
364 line += 1
365 if line < start:
366 continue
367 if line >= start+size:
368 break
369 try:
370 json_object = loads(json_object_line)
371 except:
372 skipped_lines += 1
373 else:
374 di_checker_data.append(json_object)
376 return (di_checker_data, skipped_lines, line)
378 # Parse the program arguments.
379 def parse_program_args(parser):
380 parser.add_argument("file_name", type=str, help="json file to process")
381 parser.add_argument("html_file", type=str, help="html file to output data")
382 parser.add_argument("-compress", action="store_true", help="create reduced html report")
384 return parser.parse_args()
386 def Main():
387 parser = argparse.ArgumentParser()
388 opts = parse_program_args(parser)
390 if not opts.html_file.endswith('.html'):
391 print ("error: The output file must be '.html'.")
392 sys.exit(1)
394 # Use the defaultdict in order to make multidim dicts.
395 di_location_bugs = defaultdict(lambda: defaultdict(dict))
396 di_subprogram_bugs = defaultdict(lambda: defaultdict(dict))
397 di_variable_bugs = defaultdict(lambda: defaultdict(dict))
399 # Use the ordered dict to make a summary.
400 di_location_bugs_summary = OrderedDict()
401 di_sp_bugs_summary = OrderedDict()
402 di_var_bugs_summary = OrderedDict()
404 # Compress similar bugs.
405 # DILocBugs with same pass & instruction name.
406 di_loc_pass_instr_set = set()
407 # DISPBugs with same pass & function name.
408 di_sp_pass_fn_set = set()
409 # DIVarBugs with same pass & variable name.
410 di_var_pass_var_set = set()
412 start_line = 0
413 chunk_size = 1000000
414 end_line = chunk_size - 1
415 skipped_lines = 0
416 skipped_bugs = 0
417 # Process each chunk of 1 million JSON lines.
418 while True:
419 if start_line > end_line:
420 break
421 (debug_info_bugs, skipped, end_line) = get_json_chunk(opts.file_name,start_line,chunk_size)
422 start_line += chunk_size
423 skipped_lines += skipped
425 # Map the bugs into the file-pass pairs.
426 for bugs_per_pass in debug_info_bugs:
427 try:
428 bugs_file = bugs_per_pass["file"]
429 bugs_pass = bugs_per_pass["pass"]
430 bugs = bugs_per_pass["bugs"][0]
431 except:
432 skipped_lines += 1
433 continue
435 di_loc_bugs = []
436 di_sp_bugs = []
437 di_var_bugs = []
439 # Omit duplicated bugs.
440 di_loc_set = set()
441 di_sp_set = set()
442 di_var_set = set()
443 for bug in bugs:
444 try:
445 bugs_metadata = bug["metadata"]
446 except:
447 skipped_bugs += 1
448 continue
450 if bugs_metadata == "DILocation":
451 try:
452 action = bug["action"]
453 bb_name = bug["bb-name"]
454 fn_name = bug["fn-name"]
455 instr = bug["instr"]
456 except:
457 skipped_bugs += 1
458 continue
459 di_loc_bug = DILocBug(action, bb_name, fn_name, instr)
460 if not str(di_loc_bug) in di_loc_set:
461 di_loc_set.add(str(di_loc_bug))
462 if opts.compress:
463 pass_instr = bugs_pass + instr
464 if not pass_instr in di_loc_pass_instr_set:
465 di_loc_pass_instr_set.add(pass_instr)
466 di_loc_bugs.append(di_loc_bug)
467 else:
468 di_loc_bugs.append(di_loc_bug)
470 # Fill the summary dict.
471 if bugs_pass in di_location_bugs_summary:
472 di_location_bugs_summary[bugs_pass] += 1
473 else:
474 di_location_bugs_summary[bugs_pass] = 1
475 elif bugs_metadata == "DISubprogram":
476 try:
477 action = bug["action"]
478 name = bug["name"]
479 except:
480 skipped_bugs += 1
481 continue
482 di_sp_bug = DISPBug(action, name)
483 if not str(di_sp_bug) in di_sp_set:
484 di_sp_set.add(str(di_sp_bug))
485 if opts.compress:
486 pass_fn = bugs_pass + name
487 if not pass_fn in di_sp_pass_fn_set:
488 di_sp_pass_fn_set.add(pass_fn)
489 di_sp_bugs.append(di_sp_bug)
490 else:
491 di_sp_bugs.append(di_sp_bug)
493 # Fill the summary dict.
494 if bugs_pass in di_sp_bugs_summary:
495 di_sp_bugs_summary[bugs_pass] += 1
496 else:
497 di_sp_bugs_summary[bugs_pass] = 1
498 elif bugs_metadata == "dbg-var-intrinsic":
499 try:
500 action = bug["action"]
501 fn_name = bug["fn-name"]
502 name = bug["name"]
503 except:
504 skipped_bugs += 1
505 continue
506 di_var_bug = DIVarBug(action, name, fn_name)
507 if not str(di_var_bug) in di_var_set:
508 di_var_set.add(str(di_var_bug))
509 if opts.compress:
510 pass_var = bugs_pass + name
511 if not pass_var in di_var_pass_var_set:
512 di_var_pass_var_set.add(pass_var)
513 di_var_bugs.append(di_var_bug)
514 else:
515 di_var_bugs.append(di_var_bug)
517 # Fill the summary dict.
518 if bugs_pass in di_var_bugs_summary:
519 di_var_bugs_summary[bugs_pass] += 1
520 else:
521 di_var_bugs_summary[bugs_pass] = 1
522 else:
523 # Unsupported metadata.
524 skipped_bugs += 1
525 continue
527 di_location_bugs[bugs_file][bugs_pass] = di_loc_bugs
528 di_subprogram_bugs[bugs_file][bugs_pass] = di_sp_bugs
529 di_variable_bugs[bugs_file][bugs_pass] = di_var_bugs
531 generate_html_report(di_location_bugs, di_subprogram_bugs, di_variable_bugs, \
532 di_location_bugs_summary, di_sp_bugs_summary, \
533 di_var_bugs_summary, opts.html_file)
535 if skipped_lines > 0:
536 print ("Skipped lines: " + str(skipped_lines))
537 if skipped_bugs > 0:
538 print ("Skipped bugs: " + str(skipped_bugs))
540 if __name__ == "__main__":
541 Main()
542 sys.exit(0)