[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / utils / llvm-mca-compare.py
blob72c875d4244225ce6c81ed23415ae61cd6c7163e
1 #!/usr/bin/env python3
3 import argparse
4 import sys
5 from json import loads
6 from subprocess import Popen, PIPE
8 # Holds code regions statistics.
9 class Summary:
10 def __init__(
11 self,
12 name,
13 block_rthroughput,
14 dispatch_width,
15 ipc,
16 instructions,
17 iterations,
18 total_cycles,
19 total_uops,
20 uops_per_cycle,
21 iteration_resource_pressure,
22 name_target_info_resources,
24 self.name = name
25 self.block_rthroughput = block_rthroughput
26 self.dispatch_width = dispatch_width
27 self.ipc = ipc
28 self.instructions = instructions
29 self.iterations = iterations
30 self.total_cycles = total_cycles
31 self.total_uops = total_uops
32 self.uops_per_cycle = uops_per_cycle
33 self.iteration_resource_pressure = iteration_resource_pressure
34 self.name_target_info_resources = name_target_info_resources
37 # Parse the program arguments.
38 def parse_program_args(parser):
39 parser.add_argument(
40 "file_names",
41 nargs="+",
42 type=str,
43 help="Names of files which llvm-mca tool process.",
45 parser.add_argument(
46 "--llvm-mca-binary",
47 nargs=1,
48 required=True,
49 type=str,
50 action="store",
51 metavar="[=<path to llvm-mca>]",
52 help="Specified relative path to binary of llvm-mca.",
54 parser.add_argument(
55 "--args",
56 nargs=1,
57 type=str,
58 action="store",
59 metavar="[='-option1=<arg> -option2=<arg> ...']",
60 default=["-"],
61 help="Forward options to lvm-mca tool.",
63 parser.add_argument(
64 "-v",
65 action="store_true",
66 default=False,
67 help="More details about the running lvm-mca tool.",
69 return parser.parse_args()
72 # Returns the name of the file to be analyzed from the path it is on.
73 def get_filename_from_path(path):
74 index_of_slash = path.rfind("/")
75 return path[(index_of_slash + 1) : len(path)]
78 # Returns the results of the running llvm-mca tool for the input file.
79 def run_llvm_mca_tool(opts, file_name):
80 # Get the path of the llvm-mca binary file.
81 llvm_mca_cmd = opts.llvm_mca_binary[0]
83 # The statistics llvm-mca options.
84 if opts.args[0] != "-":
85 llvm_mca_cmd += " " + opts.args[0]
86 llvm_mca_cmd += " -json"
88 # Set file which llvm-mca tool will process.
89 llvm_mca_cmd += " " + file_name
91 if opts.v:
92 print("run: $ " + llvm_mca_cmd + "\n")
94 # Generate the stats with the llvm-mca.
95 subproc = Popen(
96 llvm_mca_cmd.split(" "),
97 stdin=PIPE,
98 stdout=PIPE,
99 stderr=PIPE,
100 universal_newlines=True,
103 cmd_stdout, cmd_stderr = subproc.communicate()
105 try:
106 json_parsed = loads(cmd_stdout)
107 except:
108 print("error: No valid llvm-mca statistics found.")
109 print(cmd_stderr)
110 sys.exit(1)
112 if opts.v:
113 print("Simulation Parameters: ")
114 simulation_parameters = json_parsed["SimulationParameters"]
115 for key in simulation_parameters:
116 print(key, ":", simulation_parameters[key])
117 print("\n")
119 code_regions_len = len(json_parsed["CodeRegions"])
120 array_of_code_regions = [None] * code_regions_len
122 for i in range(code_regions_len):
123 code_region_instructions_len = len(
124 json_parsed["CodeRegions"][i]["Instructions"]
126 target_info_resources_len = len(json_parsed["TargetInfo"]["Resources"])
127 iteration_resource_pressure = ["-" for k in range(target_info_resources_len)]
128 resource_pressure_info = json_parsed["CodeRegions"][i]["ResourcePressureView"][
129 "ResourcePressureInfo"
132 name_target_info_resources = [" "] + json_parsed["TargetInfo"]["Resources"]
134 for s in range(len(resource_pressure_info)):
135 obj_of_resource_pressure_info = resource_pressure_info[s]
136 if (
137 obj_of_resource_pressure_info["InstructionIndex"]
138 == code_region_instructions_len
140 iteration_resource_pressure[
141 obj_of_resource_pressure_info["ResourceIndex"]
142 ] = str(round(obj_of_resource_pressure_info["ResourceUsage"], 2))
144 array_of_code_regions[i] = Summary(
145 file_name,
146 json_parsed["CodeRegions"][i]["SummaryView"]["BlockRThroughput"],
147 json_parsed["CodeRegions"][i]["SummaryView"]["DispatchWidth"],
148 json_parsed["CodeRegions"][i]["SummaryView"]["IPC"],
149 json_parsed["CodeRegions"][i]["SummaryView"]["Instructions"],
150 json_parsed["CodeRegions"][i]["SummaryView"]["Iterations"],
151 json_parsed["CodeRegions"][i]["SummaryView"]["TotalCycles"],
152 json_parsed["CodeRegions"][i]["SummaryView"]["TotaluOps"],
153 json_parsed["CodeRegions"][i]["SummaryView"]["uOpsPerCycle"],
154 iteration_resource_pressure,
155 name_target_info_resources,
158 return array_of_code_regions
161 # Print statistics in console for single file or for multiple files.
162 def console_print_results(matrix_of_code_regions, opts):
163 try:
164 import termtables as tt
165 except ImportError:
166 print("error: termtables not found.")
167 sys.exit(1)
169 headers_names = [None] * (len(opts.file_names) + 1)
170 headers_names[0] = " "
172 max_code_regions = 0
174 print("Input files:")
175 for i in range(len(matrix_of_code_regions)):
176 if max_code_regions < len(matrix_of_code_regions[i]):
177 max_code_regions = len(matrix_of_code_regions[i])
178 print("[f" + str(i + 1) + "]: " + get_filename_from_path(opts.file_names[i]))
179 headers_names[i + 1] = "[f" + str(i + 1) + "]: "
181 print("\nITERATIONS: " + str(matrix_of_code_regions[0][0].iterations) + "\n")
183 for i in range(max_code_regions):
185 print(
186 "\n-----------------------------------------\nCode region: "
187 + str(i + 1)
188 + "\n"
191 table_values = [
192 [[None] for i in range(len(matrix_of_code_regions) + 1)] for j in range(7)
195 table_values[0][0] = "Instructions: "
196 table_values[1][0] = "Total Cycles: "
197 table_values[2][0] = "Total uOps: "
198 table_values[3][0] = "Dispatch Width: "
199 table_values[4][0] = "uOps Per Cycle: "
200 table_values[5][0] = "IPC: "
201 table_values[6][0] = "Block RThroughput: "
203 for j in range(len(matrix_of_code_regions)):
204 if len(matrix_of_code_regions[j]) > i:
205 table_values[0][j + 1] = str(matrix_of_code_regions[j][i].instructions)
206 table_values[1][j + 1] = str(matrix_of_code_regions[j][i].total_cycles)
207 table_values[2][j + 1] = str(matrix_of_code_regions[j][i].total_uops)
208 table_values[3][j + 1] = str(
209 matrix_of_code_regions[j][i].dispatch_width
211 table_values[4][j + 1] = str(
212 round(matrix_of_code_regions[j][i].uops_per_cycle, 2)
214 table_values[5][j + 1] = str(round(matrix_of_code_regions[j][i].ipc, 2))
215 table_values[6][j + 1] = str(
216 round(matrix_of_code_regions[j][i].block_rthroughput, 2)
218 else:
219 table_values[0][j + 1] = "-"
220 table_values[1][j + 1] = "-"
221 table_values[2][j + 1] = "-"
222 table_values[3][j + 1] = "-"
223 table_values[4][j + 1] = "-"
224 table_values[5][j + 1] = "-"
225 table_values[6][j + 1] = "-"
227 tt.print(
228 table_values,
229 header=headers_names,
230 style=tt.styles.ascii_thin_double,
231 padding=(0, 1),
234 print("\nResource pressure per iteration: \n")
236 table_values = [
238 [None]
239 for i in range(
240 len(matrix_of_code_regions[0][0].iteration_resource_pressure) + 1
243 for j in range(len(matrix_of_code_regions) + 1)
246 table_values[0] = matrix_of_code_regions[0][0].name_target_info_resources
248 for j in range(len(matrix_of_code_regions)):
249 if len(matrix_of_code_regions[j]) > i:
250 table_values[j + 1] = [
251 "[f" + str(j + 1) + "]: "
252 ] + matrix_of_code_regions[j][i].iteration_resource_pressure
253 else:
254 table_values[j + 1] = ["[f" + str(j + 1) + "]: "] + len(
255 matrix_of_code_regions[0][0].iteration_resource_pressure
256 ) * ["-"]
258 tt.print(
259 table_values,
260 style=tt.styles.ascii_thin_double,
261 padding=(0, 1),
263 print("\n")
266 def Main():
267 parser = argparse.ArgumentParser()
268 opts = parse_program_args(parser)
270 matrix_of_code_regions = [None] * len(opts.file_names)
272 for i in range(len(opts.file_names)):
273 matrix_of_code_regions[i] = run_llvm_mca_tool(opts, opts.file_names[i])
274 console_print_results(matrix_of_code_regions, opts)
277 if __name__ == "__main__":
278 Main()
279 sys.exit(0)