blob: f5aae110fbf93698445d4ac7da74beb848a9f86e [file] [log] [blame]
Xiaofei Baibca03e52021-09-09 09:42:37 +00001#!/usr/bin/env python3
2
3"""
Xiaofei Baibca03e52021-09-09 09:42:37 +00004This script is for comparing the size of the library files from two
5different Git revisions within an Mbed TLS repository.
6The results of the comparison is formatted as csv and stored at a
7configurable location.
8Note: must be run from Mbed TLS root.
9"""
10
11# Copyright The Mbed TLS Contributors
12# SPDX-License-Identifier: Apache-2.0
13#
14# Licensed under the Apache License, Version 2.0 (the "License"); you may
15# not use this file except in compliance with the License.
16# You may obtain a copy of the License at
17#
18# http://www.apache.org/licenses/LICENSE-2.0
19#
20# Unless required by applicable law or agreed to in writing, software
21# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
22# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23# See the License for the specific language governing permissions and
24# limitations under the License.
25
26import argparse
27import os
Yanray Wang16ebc572023-05-30 18:10:20 +080028import re
Xiaofei Baibca03e52021-09-09 09:42:37 +000029import subprocess
30import sys
Yanray Wang16ebc572023-05-30 18:10:20 +080031import typing
Yanray Wang23bd5322023-05-24 11:03:59 +080032from enum import Enum
Xiaofei Baibca03e52021-09-09 09:42:37 +000033
Yanray Wang16ebc572023-05-30 18:10:20 +080034from mbedtls_dev import typing_util
Gilles Peskined9071e72022-09-18 21:17:09 +020035from mbedtls_dev import build_tree
36
Yanray Wang23bd5322023-05-24 11:03:59 +080037class SupportedArch(Enum):
38 """Supported architecture for code size measurement."""
39 AARCH64 = 'aarch64'
40 AARCH32 = 'aarch32'
Yanray Wangaba71582023-05-29 16:45:56 +080041 ARMV8_M = 'armv8-m'
Yanray Wang23bd5322023-05-24 11:03:59 +080042 X86_64 = 'x86_64'
43 X86 = 'x86'
44
Yanray Wang6a862582023-05-24 12:24:38 +080045CONFIG_TFM_MEDIUM_MBEDCRYPTO_H = "../configs/tfm_mbedcrypto_config_profile_medium.h"
46CONFIG_TFM_MEDIUM_PSA_CRYPTO_H = "../configs/crypto_config_profile_medium.h"
47class SupportedConfig(Enum):
48 """Supported configuration for code size measurement."""
49 DEFAULT = 'default'
50 TFM_MEDIUM = 'tfm-medium'
51
Yanray Wang16ebc572023-05-30 18:10:20 +080052# Static library
53MBEDTLS_STATIC_LIB = {
54 'CRYPTO': 'library/libmbedcrypto.a',
55 'X509': 'library/libmbedx509.a',
56 'TLS': 'library/libmbedtls.a',
57}
58
Yanray Wang23bd5322023-05-24 11:03:59 +080059DETECT_ARCH_CMD = "cc -dM -E - < /dev/null"
60def detect_arch() -> str:
61 """Auto-detect host architecture."""
62 cc_output = subprocess.check_output(DETECT_ARCH_CMD, shell=True).decode()
63 if "__aarch64__" in cc_output:
64 return SupportedArch.AARCH64.value
65 if "__arm__" in cc_output:
66 return SupportedArch.AARCH32.value
67 if "__x86_64__" in cc_output:
68 return SupportedArch.X86_64.value
69 if "__x86__" in cc_output:
70 return SupportedArch.X86.value
71 else:
72 print("Unknown host architecture, cannot auto-detect arch.")
73 sys.exit(1)
Gilles Peskined9071e72022-09-18 21:17:09 +020074
Yanray Wang6a862582023-05-24 12:24:38 +080075class CodeSizeInfo: # pylint: disable=too-few-public-methods
76 """Gather information used to measure code size.
77
78 It collects information about architecture, configuration in order to
79 infer build command for code size measurement.
80 """
81
Yanray Wangc18cd892023-05-31 11:08:04 +080082 SupportedArchConfig = [
83 "-a " + SupportedArch.AARCH64.value + " -c " + SupportedConfig.DEFAULT.value,
84 "-a " + SupportedArch.AARCH32.value + " -c " + SupportedConfig.DEFAULT.value,
85 "-a " + SupportedArch.X86_64.value + " -c " + SupportedConfig.DEFAULT.value,
86 "-a " + SupportedArch.X86.value + " -c " + SupportedConfig.DEFAULT.value,
87 "-a " + SupportedArch.ARMV8_M.value + " -c " + SupportedConfig.TFM_MEDIUM.value,
88 ]
89
Yanray Wang21f17442023-06-01 11:29:06 +080090 def __init__(self, arch: str, config: str, sys_arch: str) -> None:
Yanray Wang6a862582023-05-24 12:24:38 +080091 """
92 arch: architecture to measure code size on.
93 config: configuration type to measure code size with.
94 make_command: command to build library (Inferred from arch and config).
95 """
96 self.arch = arch
97 self.config = config
Yanray Wang21f17442023-06-01 11:29:06 +080098 self.sys_arch = sys_arch
Yanray Wang6a862582023-05-24 12:24:38 +080099 self.make_command = self.set_make_command()
100
101 def set_make_command(self) -> str:
102 """Infer build command based on architecture and configuration."""
103
Yanray Wang21f17442023-06-01 11:29:06 +0800104 if self.config == SupportedConfig.DEFAULT.value and \
105 self.arch == self.sys_arch:
Yanray Wang6a862582023-05-24 12:24:38 +0800106 return 'make -j lib CFLAGS=\'-Os \' '
Yanray Wangaba71582023-05-29 16:45:56 +0800107 elif self.arch == SupportedArch.ARMV8_M.value and \
Yanray Wang6a862582023-05-24 12:24:38 +0800108 self.config == SupportedConfig.TFM_MEDIUM.value:
109 return \
Yanray Wang60430bd2023-05-29 14:48:18 +0800110 'make -j lib CC=armclang \
Yanray Wang6a862582023-05-24 12:24:38 +0800111 CFLAGS=\'--target=arm-arm-none-eabi -mcpu=cortex-m33 -Os \
112 -DMBEDTLS_CONFIG_FILE=\\\"' + CONFIG_TFM_MEDIUM_MBEDCRYPTO_H + '\\\" \
113 -DMBEDTLS_PSA_CRYPTO_CONFIG_FILE=\\\"' + CONFIG_TFM_MEDIUM_PSA_CRYPTO_H + '\\\" \''
114 else:
Yanray Wang21f17442023-06-01 11:29:06 +0800115 print("Unsupported combination of architecture: {} and configuration: {}"
Yanray Wang6a862582023-05-24 12:24:38 +0800116 .format(self.arch, self.config))
Yanray Wangc18cd892023-05-31 11:08:04 +0800117 print("\nPlease use supported combination of architecture and configuration:")
118 for comb in CodeSizeInfo.SupportedArchConfig:
119 print(comb)
Yanray Wang21f17442023-06-01 11:29:06 +0800120 print("\nFor your system, please use:")
121 for comb in CodeSizeInfo.SupportedArchConfig:
122 if "default" in comb and self.sys_arch not in comb:
123 continue
124 print(comb)
Yanray Wang6a862582023-05-24 12:24:38 +0800125 sys.exit(1)
126
Yanray Wang16ebc572023-05-30 18:10:20 +0800127class SizeEntry: # pylint: disable=too-few-public-methods
128 """Data Structure to only store information of code size."""
129 def __init__(self, text, data, bss, dec):
130 self.text = text
131 self.data = data
132 self.bss = bss
133 self.total = dec # total <=> dec
Yanray Wang6a862582023-05-24 12:24:38 +0800134
Yanray Wang16ebc572023-05-30 18:10:20 +0800135class CodeSizeBase:
136 """Code Size Base Class for size record saving and writing."""
137
138 def __init__(self) -> None:
139 """ Variable code_size is used to store size info for any revisions.
140 code_size: (data format)
141 {revision: {module: {file_name: SizeEntry,
142 etc ...
143 },
144 etc ...
145 },
146 etc ...
147 }
148 """
149 self.code_size = {} #type: typing.Dict[str, typing.Dict]
150
151 def set_size_record(self, revision: str, mod: str, size_text: str) -> None:
152 """Store size information for target revision and high-level module.
153
154 size_text Format: text data bss dec hex filename
155 """
156 size_record = {}
157 for line in size_text.splitlines()[1:]:
158 data = line.split()
159 size_record[data[5]] = SizeEntry(data[0], data[1], data[2], data[3])
160 if revision in self.code_size:
161 self.code_size[revision].update({mod: size_record})
162 else:
163 self.code_size[revision] = {mod: size_record}
164
165 def read_size_record(self, revision: str, fname: str) -> None:
166 """Read size information from csv file and write it into code_size.
167
168 fname Format: filename text data bss dec
169 """
170 mod = ""
171 size_record = {}
172 with open(fname, 'r') as csv_file:
173 for line in csv_file:
174 data = line.strip().split()
175 # check if we find the beginning of a module
176 if data and data[0] in MBEDTLS_STATIC_LIB:
177 mod = data[0]
178 continue
179
180 if mod:
181 size_record[data[0]] = \
182 SizeEntry(data[1], data[2], data[3], data[4])
183
184 # check if we hit record for the end of a module
185 m = re.match(r'.?TOTALS', line)
186 if m:
187 if revision in self.code_size:
188 self.code_size[revision].update({mod: size_record})
189 else:
190 self.code_size[revision] = {mod: size_record}
191 mod = ""
192 size_record = {}
193
194 def _size_reader_helper(
195 self,
196 revision: str,
197 output: typing_util.Writable
198 ) -> typing.Iterator[tuple]:
199 """A helper function to peel code_size based on revision."""
200 for mod, file_size in self.code_size[revision].items():
201 output.write("\n" + mod + "\n")
202 for fname, size_entry in file_size.items():
203 yield mod, fname, size_entry
204
205 def write_size_record(
206 self,
207 revision: str,
208 output: typing_util.Writable
209 ) -> None:
210 """Write size information to a file.
211
212 Writing Format: file_name text data bss total(dec)
213 """
214 output.write("{:<30} {:>7} {:>7} {:>7} {:>7}\n"
215 .format("filename", "text", "data", "bss", "total"))
216 for _, fname, size_entry in self._size_reader_helper(revision, output):
217 output.write("{:<30} {:>7} {:>7} {:>7} {:>7}\n"
218 .format(fname, size_entry.text, size_entry.data,\
219 size_entry.bss, size_entry.total))
220
221 def write_comparison(
222 self,
223 old_rev: str,
224 new_rev: str,
225 output: typing_util.Writable
226 ) -> None:
227 """Write comparison result into a file.
228
229 Writing Format: file_name current(total) old(total) change(Byte) change_pct(%)
230 """
231 output.write("{:<30} {:>7} {:>7} {:>7} {:>7}\n"
232 .format("filename", "current", "old", "change", "change%"))
233 for mod, fname, size_entry in self._size_reader_helper(new_rev, output):
234 new_size = int(size_entry.total)
235 # check if we have the file in old revision
236 if fname in self.code_size[old_rev][mod]:
237 old_size = int(self.code_size[old_rev][mod][fname].total)
238 change = new_size - old_size
239 if old_size != 0:
240 change_pct = change / old_size
241 else:
242 change_pct = 0
243 output.write("{:<30} {:>7} {:>7} {:>7} {:>7.2%}\n"
244 .format(fname, new_size, old_size, change, change_pct))
245 else:
246 output.write("{} {}\n".format(fname, new_size))
247
248
249class CodeSizeComparison(CodeSizeBase):
Xiaofei Bai2400b502021-10-21 12:22:58 +0000250 """Compare code size between two Git revisions."""
Xiaofei Baibca03e52021-09-09 09:42:37 +0000251
Yanray Wang72b105f2023-05-31 15:20:39 +0800252 def __init__(
253 self,
254 old_revision: str,
255 new_revision: str,
256 result_dir: str,
257 code_size_info: CodeSizeInfo
258 ) -> None:
Xiaofei Baibca03e52021-09-09 09:42:37 +0000259 """
Yanray Wang6a862582023-05-24 12:24:38 +0800260 old_revision: revision to compare against.
Xiaofei Baibca03e52021-09-09 09:42:37 +0000261 new_revision:
Yanray Wang6a862582023-05-24 12:24:38 +0800262 result_dir: directory for comparison result.
263 code_size_info: an object containing information to build library.
Xiaofei Baibca03e52021-09-09 09:42:37 +0000264 """
Yanray Wang8804db92023-05-30 18:18:18 +0800265 super().__init__()
Xiaofei Baibca03e52021-09-09 09:42:37 +0000266 self.repo_path = "."
267 self.result_dir = os.path.abspath(result_dir)
Xiaofei Bai184e8b62021-10-26 09:23:42 +0000268 os.makedirs(self.result_dir, exist_ok=True)
Xiaofei Baibca03e52021-09-09 09:42:37 +0000269
270 self.csv_dir = os.path.abspath("code_size_records/")
Xiaofei Bai184e8b62021-10-26 09:23:42 +0000271 os.makedirs(self.csv_dir, exist_ok=True)
Xiaofei Baibca03e52021-09-09 09:42:37 +0000272
273 self.old_rev = old_revision
274 self.new_rev = new_revision
275 self.git_command = "git"
Yanray Wang6a862582023-05-24 12:24:38 +0800276 self.make_command = code_size_info.make_command
Yanray Wang369cd962023-05-24 17:13:29 +0800277 self.fname_suffix = "-" + code_size_info.arch + "-" +\
278 code_size_info.config
Xiaofei Baibca03e52021-09-09 09:42:37 +0000279
280 @staticmethod
Yanray Wang72b105f2023-05-31 15:20:39 +0800281 def validate_revision(revision: str) -> bytes:
Xiaofei Baiccd738b2021-11-03 07:12:31 +0000282 result = subprocess.check_output(["git", "rev-parse", "--verify",
283 revision + "^{commit}"], shell=False)
Xiaofei Bai184e8b62021-10-26 09:23:42 +0000284 return result
Xiaofei Bai2400b502021-10-21 12:22:58 +0000285
Yanray Wang72b105f2023-05-31 15:20:39 +0800286 def _create_git_worktree(self, revision: str) -> str:
Xiaofei Baibca03e52021-09-09 09:42:37 +0000287 """Make a separate worktree for revision.
288 Do not modify the current worktree."""
289
Xiaofei Bai184e8b62021-10-26 09:23:42 +0000290 if revision == "current":
Xiaofei Baibca03e52021-09-09 09:42:37 +0000291 print("Using current work directory.")
292 git_worktree_path = self.repo_path
293 else:
294 print("Creating git worktree for", revision)
Xiaofei Bai184e8b62021-10-26 09:23:42 +0000295 git_worktree_path = os.path.join(self.repo_path, "temp-" + revision)
Xiaofei Baibca03e52021-09-09 09:42:37 +0000296 subprocess.check_output(
297 [self.git_command, "worktree", "add", "--detach",
298 git_worktree_path, revision], cwd=self.repo_path,
299 stderr=subprocess.STDOUT
300 )
Aditya Deshpande41a0aad2023-04-13 16:32:21 +0100301
Xiaofei Baibca03e52021-09-09 09:42:37 +0000302 return git_worktree_path
303
Yanray Wang72b105f2023-05-31 15:20:39 +0800304 def _build_libraries(self, git_worktree_path: str) -> None:
Xiaofei Baibca03e52021-09-09 09:42:37 +0000305 """Build libraries in the specified worktree."""
306
307 my_environment = os.environ.copy()
Aditya Deshpande41a0aad2023-04-13 16:32:21 +0100308 try:
309 subprocess.check_output(
310 self.make_command, env=my_environment, shell=True,
311 cwd=git_worktree_path, stderr=subprocess.STDOUT,
312 )
313 except subprocess.CalledProcessError as e:
314 self._handle_called_process_error(e, git_worktree_path)
Xiaofei Baibca03e52021-09-09 09:42:37 +0000315
Yanray Wang72b105f2023-05-31 15:20:39 +0800316 def _gen_code_size_csv(self, revision: str, git_worktree_path: str) -> None:
Xiaofei Baibca03e52021-09-09 09:42:37 +0000317 """Generate code size csv file."""
318
Xiaofei Bai184e8b62021-10-26 09:23:42 +0000319 if revision == "current":
320 print("Measuring code size in current work directory.")
321 else:
322 print("Measuring code size for", revision)
Yanray Wang8804db92023-05-30 18:18:18 +0800323
324 for mod, st_lib in MBEDTLS_STATIC_LIB.items():
325 try:
326 result = subprocess.check_output(
327 ["size", st_lib, "-t"], cwd=git_worktree_path
328 )
329 except subprocess.CalledProcessError as e:
330 self._handle_called_process_error(e, git_worktree_path)
331 size_text = result.decode("utf-8")
332
333 self.set_size_record(revision, mod, size_text)
334
335 print("Generating code size csv for", revision)
336 csv_file = open(os.path.join(self.csv_dir, revision +
337 self.fname_suffix + ".csv"), "w")
338 self.write_size_record(revision, csv_file)
Xiaofei Baibca03e52021-09-09 09:42:37 +0000339
Yanray Wang72b105f2023-05-31 15:20:39 +0800340 def _remove_worktree(self, git_worktree_path: str) -> None:
Xiaofei Baibca03e52021-09-09 09:42:37 +0000341 """Remove temporary worktree."""
342 if git_worktree_path != self.repo_path:
343 print("Removing temporary worktree", git_worktree_path)
344 subprocess.check_output(
345 [self.git_command, "worktree", "remove", "--force",
346 git_worktree_path], cwd=self.repo_path,
347 stderr=subprocess.STDOUT
348 )
349
Yanray Wang72b105f2023-05-31 15:20:39 +0800350 def _get_code_size_for_rev(self, revision: str) -> None:
Xiaofei Baibca03e52021-09-09 09:42:37 +0000351 """Generate code size csv file for the specified git revision."""
352
353 # Check if the corresponding record exists
Yanray Wang369cd962023-05-24 17:13:29 +0800354 csv_fname = revision + self.fname_suffix + ".csv"
Xiaofei Bai184e8b62021-10-26 09:23:42 +0000355 if (revision != "current") and \
Xiaofei Baibca03e52021-09-09 09:42:37 +0000356 os.path.exists(os.path.join(self.csv_dir, csv_fname)):
357 print("Code size csv file for", revision, "already exists.")
Yanray Wang8804db92023-05-30 18:18:18 +0800358 self.read_size_record(revision, os.path.join(self.csv_dir, csv_fname))
Xiaofei Baibca03e52021-09-09 09:42:37 +0000359 else:
360 git_worktree_path = self._create_git_worktree(revision)
361 self._build_libraries(git_worktree_path)
362 self._gen_code_size_csv(revision, git_worktree_path)
363 self._remove_worktree(git_worktree_path)
364
Yanray Wang72b105f2023-05-31 15:20:39 +0800365 def _gen_code_size_comparison(self) -> int:
Xiaofei Baibca03e52021-09-09 09:42:37 +0000366 """Generate results of the size changes between two revisions,
367 old and new. Measured code size results of these two revisions
Xiaofei Bai2400b502021-10-21 12:22:58 +0000368 must be available."""
Xiaofei Baibca03e52021-09-09 09:42:37 +0000369
Yanray Wang369cd962023-05-24 17:13:29 +0800370 res_file = open(os.path.join(self.result_dir, "compare-" +
371 self.old_rev + "-" + self.new_rev +
372 self.fname_suffix +
373 ".csv"), "w")
Xiaofei Bai184e8b62021-10-26 09:23:42 +0000374
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800375 print("Generating comparison results.")
Yanray Wang8804db92023-05-30 18:18:18 +0800376 self.write_comparison(self.old_rev, self.new_rev, res_file)
Xiaofei Baibca03e52021-09-09 09:42:37 +0000377
Xiaofei Bai2400b502021-10-21 12:22:58 +0000378 return 0
Xiaofei Baibca03e52021-09-09 09:42:37 +0000379
Yanray Wang72b105f2023-05-31 15:20:39 +0800380 def get_comparision_results(self) -> int:
Xiaofei Baibca03e52021-09-09 09:42:37 +0000381 """Compare size of library/*.o between self.old_rev and self.new_rev,
382 and generate the result file."""
Gilles Peskined9071e72022-09-18 21:17:09 +0200383 build_tree.check_repo_path()
Xiaofei Baibca03e52021-09-09 09:42:37 +0000384 self._get_code_size_for_rev(self.old_rev)
385 self._get_code_size_for_rev(self.new_rev)
Yanray Wang8804db92023-05-30 18:18:18 +0800386 return self._gen_code_size_comparison()
Xiaofei Baibca03e52021-09-09 09:42:37 +0000387
Aditya Deshpande41a0aad2023-04-13 16:32:21 +0100388 def _handle_called_process_error(self, e: subprocess.CalledProcessError,
Yanray Wang72b105f2023-05-31 15:20:39 +0800389 git_worktree_path: str) -> None:
Aditya Deshpande41a0aad2023-04-13 16:32:21 +0100390 """Handle a CalledProcessError and quit the program gracefully.
391 Remove any extra worktrees so that the script may be called again."""
392
393 # Tell the user what went wrong
394 print("The following command: {} failed and exited with code {}"
395 .format(e.cmd, e.returncode))
396 print("Process output:\n {}".format(str(e.output, "utf-8")))
397
398 # Quit gracefully by removing the existing worktree
399 self._remove_worktree(git_worktree_path)
400 sys.exit(-1)
401
Xiaofei Bai2400b502021-10-21 12:22:58 +0000402def main():
Yanray Wang502c54f2023-05-31 11:41:36 +0800403 parser = argparse.ArgumentParser(description=(__doc__))
404 group_required = parser.add_argument_group(
405 'required arguments',
406 'required arguments to parse for running ' + os.path.basename(__file__))
407 group_required.add_argument(
408 "-o", "--old-rev", type=str, required=True,
409 help="old revision for comparison.")
410
411 group_optional = parser.add_argument_group(
412 'optional arguments',
413 'optional arguments to parse for running ' + os.path.basename(__file__))
414 group_optional.add_argument(
Xiaofei Baibca03e52021-09-09 09:42:37 +0000415 "-r", "--result-dir", type=str, default="comparison",
416 help="directory where comparison result is stored, \
Yanray Wang502c54f2023-05-31 11:41:36 +0800417 default is comparison")
418 group_optional.add_argument(
Xiaofei Bai184e8b62021-10-26 09:23:42 +0000419 "-n", "--new-rev", type=str, default=None,
420 help="new revision for comparison, default is the current work \
Yanray Wang502c54f2023-05-31 11:41:36 +0800421 directory, including uncommitted changes.")
422 group_optional.add_argument(
Yanray Wang23bd5322023-05-24 11:03:59 +0800423 "-a", "--arch", type=str, default=detect_arch(),
424 choices=list(map(lambda s: s.value, SupportedArch)),
425 help="specify architecture for code size comparison, default is the\
Yanray Wang502c54f2023-05-31 11:41:36 +0800426 host architecture.")
427 group_optional.add_argument(
Yanray Wang6a862582023-05-24 12:24:38 +0800428 "-c", "--config", type=str, default=SupportedConfig.DEFAULT.value,
429 choices=list(map(lambda s: s.value, SupportedConfig)),
430 help="specify configuration type for code size comparison,\
Yanray Wang502c54f2023-05-31 11:41:36 +0800431 default is the current MbedTLS configuration.")
Xiaofei Baibca03e52021-09-09 09:42:37 +0000432 comp_args = parser.parse_args()
433
434 if os.path.isfile(comp_args.result_dir):
435 print("Error: {} is not a directory".format(comp_args.result_dir))
436 parser.exit()
437
Xiaofei Bai184e8b62021-10-26 09:23:42 +0000438 validate_res = CodeSizeComparison.validate_revision(comp_args.old_rev)
Xiaofei Baiccd738b2021-11-03 07:12:31 +0000439 old_revision = validate_res.decode().replace("\n", "")
Xiaofei Bai2400b502021-10-21 12:22:58 +0000440
Xiaofei Bai184e8b62021-10-26 09:23:42 +0000441 if comp_args.new_rev is not None:
442 validate_res = CodeSizeComparison.validate_revision(comp_args.new_rev)
Xiaofei Baiccd738b2021-11-03 07:12:31 +0000443 new_revision = validate_res.decode().replace("\n", "")
Xiaofei Bai184e8b62021-10-26 09:23:42 +0000444 else:
445 new_revision = "current"
Xiaofei Bai2400b502021-10-21 12:22:58 +0000446
Yanray Wang21f17442023-06-01 11:29:06 +0800447 code_size_info = CodeSizeInfo(comp_args.arch, comp_args.config,
448 detect_arch())
Yanray Wangaba71582023-05-29 16:45:56 +0800449 print("Measure code size for architecture: {}, configuration: {}"
450 .format(code_size_info.arch, code_size_info.config))
Xiaofei Baibca03e52021-09-09 09:42:37 +0000451 result_dir = comp_args.result_dir
Yanray Wang6a862582023-05-24 12:24:38 +0800452 size_compare = CodeSizeComparison(old_revision, new_revision, result_dir,
453 code_size_info)
Xiaofei Baibca03e52021-09-09 09:42:37 +0000454 return_code = size_compare.get_comparision_results()
455 sys.exit(return_code)
456
457
458if __name__ == "__main__":
Xiaofei Bai2400b502021-10-21 12:22:58 +0000459 main()