Jianliang Shen | 9b4ba11 | 2022-01-19 14:57:04 +0800 | [diff] [blame] | 1 | # ------------------------------------------------------------------------------ |
| 2 | # Copyright (c) 2021-2022, Arm Limited. All rights reserved. |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 3 | # |
| 4 | # SPDX-License-Identifier: BSD-3-Clause |
| 5 | # |
Jianliang Shen | 9b4ba11 | 2022-01-19 14:57:04 +0800 | [diff] [blame] | 6 | # ------------------------------------------------------------------------------ |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 7 | |
| 8 | import sqlite3 |
| 9 | import argparse |
| 10 | |
| 11 | def diff_summary(): |
| 12 | cursor1 = cur1.execute("select * from Summary") |
| 13 | cursor2 = cur2.execute("select * from Summary") |
| 14 | for row in cursor1: |
Jianliang Shen | 9b4ba11 | 2022-01-19 14:57:04 +0800 | [diff] [blame] | 15 | data1 = [row[0], row[1], row[2], row[3], row[6], row[7]] |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 16 | for row in cursor2: |
Jianliang Shen | 9b4ba11 | 2022-01-19 14:57:04 +0800 | [diff] [blame] | 17 | data2 = [row[0], row[1], row[2], row[3], row[6], row[7]] |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 18 | text = ["Code size:", "RO data:", "RW data:", |
| 19 | "ZI data:", "Flash size:", "RAM size:"] |
| 20 | |
| 21 | for i in range(6): |
| 22 | delta = data2[i] - data1[i] |
| 23 | |
| 24 | print("{:<12}{:<5}\t{:<8}B\t\t{:<8.2f}KB". |
| 25 | format(text[i], |
| 26 | "+++" if delta > 0 else "---", |
| 27 | abs(delta), |
| 28 | abs(delta)/1024)) |
| 29 | |
| 30 | def diff_function(): |
| 31 | cursor1 = cur1.execute("select * from Function") |
| 32 | func_name_list = [] |
| 33 | total_code_change = 0 |
| 34 | for row in cursor1: |
| 35 | func_name1 = row[0] |
| 36 | func_size1 = row[2] |
| 37 | func_obj_name1 = row[4] |
| 38 | cursor2 = cur2.execute("select * from Function WHERE name = '{}' and obj_file = '{}'". |
| 39 | format(func_name1, func_obj_name1)) |
| 40 | if len(list(cursor2)) > 0: |
| 41 | cursor2 = cur2.execute("select * from Function WHERE name = '{}' and obj_file = '{}'". |
| 42 | format(func_name1, func_obj_name1)) |
| 43 | for row in cursor2: |
| 44 | func_name2 = row[0] |
| 45 | func_size2 = row[2] |
| 46 | func_obj_name2 = row[4] |
| 47 | delta = func_size2 - func_size1 |
| 48 | if delta != 0: |
| 49 | func_name_list.append({'name': func_name1, |
| 50 | 'delta': abs(delta), |
| 51 | 'sign': "+++" if delta > 0 else "---", |
| 52 | 'obj': func_obj_name1}) |
| 53 | total_code_change += delta |
| 54 | else: |
| 55 | func_name_list.append({'name': func_name1, |
| 56 | 'delta': func_size1, |
| 57 | 'sign': "del", |
| 58 | 'obj': func_obj_name1}) |
| 59 | total_code_change -= func_size1 |
| 60 | |
| 61 | cursor2 = cur2.execute("select * from Function") |
| 62 | for row in cursor2: |
| 63 | func_name2 = row[0] |
| 64 | func_size2 = row[2] |
| 65 | func_obj_name2 = row[4] |
| 66 | cursor1 = cur1.execute("select * from Function WHERE name = '{}' and obj_file = '{}'". |
| 67 | format(func_name2, func_obj_name2)) |
| 68 | if len(list(cursor1)) == 0: |
| 69 | func_name_list.append({'name': func_name2, |
| 70 | 'delta': func_size2, |
| 71 | 'sign': "new", |
| 72 | 'obj': func_obj_name2}) |
| 73 | total_code_change += func_size2 |
| 74 | |
| 75 | func_name_list = sorted(func_name_list, |
| 76 | key=lambda i: i['delta'], |
| 77 | reverse=True) |
| 78 | print("─" * 120) |
| 79 | print("{:<50}{:<10}{:<10}{:<50}".format( |
| 80 | "Function name", "Status", "Delta", "Object file")) |
| 81 | print("─" * 120) |
| 82 | for s in func_name_list: |
| 83 | print("{:<50}{:<10}{:<10}{:<50}".format( |
| 84 | s['name'], s['sign'], s['delta'], s['obj'])) |
| 85 | print("─" * 120) |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame^] | 86 | print("Total Function Size change = {:<6} B\t= {:<8.2f} KB".format( |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 87 | total_code_change, total_code_change/1024)) |
| 88 | print("─" * 120) |
| 89 | |
| 90 | |
| 91 | def diff_data(data_type): |
| 92 | cursor1 = cur1.execute("select * from Data where type = '{}'".format(data_type)) |
| 93 | data_name_list = [] |
| 94 | total_data_change = 0 |
| 95 | for row in cursor1: |
| 96 | data_name1 = row[0] |
| 97 | data_size1 = row[2] |
| 98 | data_obj_name1 = row[5] |
| 99 | cursor2 = cur2.execute("select * from Data WHERE name = '{}' and obj_file = '{}' and type = '{}'". |
| 100 | format(data_name1, data_obj_name1, data_type)) |
| 101 | if len(list(cursor2)) > 0: |
| 102 | cursor2 = cur2.execute("select * from Data WHERE name = '{}' and obj_file = '{}' and type = '{}'". |
| 103 | format(data_name1, data_obj_name1, data_type)) |
| 104 | for row in cursor2: |
| 105 | data_name2 = row[0] |
| 106 | data_size2 = row[2] |
| 107 | data_obj_name2 = row[5] |
| 108 | delta = data_size2 - data_size1 |
| 109 | if delta != 0: |
| 110 | data_name_list.append({'name': data_name1, |
| 111 | 'delta': abs(delta), |
| 112 | 'sign': "+++" if delta > 0 else "---", |
| 113 | 'obj': data_obj_name1}) |
| 114 | total_data_change += delta |
| 115 | else: |
| 116 | data_name_list.append({'name': data_name1, |
| 117 | 'delta': data_size1, |
| 118 | 'sign': "del", |
| 119 | 'obj': data_obj_name1}) |
| 120 | total_data_change -= data_size1 |
| 121 | |
| 122 | cursor2 = cur2.execute("select * from Data where type = '{}'".format(data_type)) |
| 123 | for row in cursor2: |
| 124 | data_name2 = row[0] |
| 125 | data_size2 = row[2] |
| 126 | data_obj_name2 = row[5] |
| 127 | cursor1 = cur1.execute("select * from Data WHERE name = '{}' and obj_file = '{}' and type = '{}'". |
| 128 | format(data_name2, data_obj_name2, data_type)) |
| 129 | if len(list(cursor1)) == 0: |
| 130 | data_name_list.append({'name': data_name2, |
| 131 | 'delta': data_size2, |
| 132 | 'sign': "new", |
| 133 | 'obj': data_obj_name2}) |
| 134 | total_data_change += data_size2 |
| 135 | |
| 136 | data_name_list = sorted(data_name_list, |
| 137 | key=lambda i: i['delta'], |
| 138 | reverse=True) |
| 139 | print("─" * 130) |
| 140 | print("{:<50}{:<10}{:<10}{:<50}{:<10}".format( |
| 141 | "Data name", "Status", "Delta", "Object file", "Data Type")) |
| 142 | print("─" * 130) |
| 143 | for s in data_name_list: |
| 144 | print("{:<50}{:<10}{:<10}{:<50}{:<10}".format( |
| 145 | s['name'], s['sign'], s['delta'], s['obj'], data_type)) |
| 146 | print("─" * 130) |
| 147 | print("Total {} Data change = {:<6} B\t= {:<8.2f} KB".format( |
| 148 | data_type, total_data_change, total_data_change/1024)) |
| 149 | print("─" * 130) |
| 150 | |
| 151 | |
| 152 | def add_array(array1, array2): |
| 153 | if len(array2) == len(array1): |
| 154 | for i in range(len(array1)): |
| 155 | array1[i] += array2[i] |
| 156 | return array1 |
| 157 | |
| 158 | |
| 159 | def diff_obj(): |
| 160 | cursor1 = cur1.execute("select * from Object") |
| 161 | obj_name_list = [] |
| 162 | for row in cursor1: |
| 163 | obj_name1 = row[0] |
| 164 | obj_flash_size1 = row[2] |
| 165 | obj_ram_size1 = row[3] |
| 166 | obj_code_size1 = row[4] |
| 167 | obj_rodata_size1 = row[5] |
| 168 | obj_rwdata_size1 = row[6] |
| 169 | obj_zidata_size1 = row[7] |
| 170 | cursor2 = cur2.execute("select * from Object WHERE name = '{}'". |
| 171 | format(obj_name1)) |
| 172 | if len(list(cursor2)) > 0: |
| 173 | cursor2 = cur2.execute("select * from Object WHERE name = '{}'". |
| 174 | format(obj_name1)) |
| 175 | for row in cursor2: |
| 176 | obj_name2 = row[0] |
| 177 | if row[2] != obj_flash_size1 or \ |
| 178 | row[3] != obj_ram_size1 or \ |
| 179 | row[4] != obj_code_size1 or \ |
| 180 | row[5] != obj_rodata_size1 or \ |
| 181 | row[6] != obj_rwdata_size1 or \ |
| 182 | row[7] != obj_zidata_size1: |
| 183 | obj_name_list.append({'name': obj_name1, |
| 184 | 'sign': "+/-", |
| 185 | 'delta_array': [row[2] - obj_flash_size1, |
| 186 | row[3] - obj_ram_size1, |
| 187 | row[4] - obj_code_size1, |
| 188 | row[5] - obj_rodata_size1, |
| 189 | row[6] - obj_rwdata_size1, |
| 190 | row[7] - obj_zidata_size1]}) |
| 191 | else: |
| 192 | obj_name_list.append({'name': obj_name1, |
| 193 | 'sign': "del", |
| 194 | 'delta_array': [0-obj_flash_size1, |
| 195 | 0-obj_ram_size1, |
| 196 | 0-obj_code_size1, |
| 197 | 0-obj_rodata_size1, |
| 198 | 0-obj_rwdata_size1, |
| 199 | 0-obj_zidata_size1]}) |
| 200 | cursor2 = cur2.execute("select * from Object") |
| 201 | for row in cursor2: |
| 202 | obj_name2 = row[0] |
| 203 | cursor1 = cur1.execute("select * from Object WHERE name = '{}'". |
| 204 | format(obj_name2)) |
| 205 | if len(list(cursor1)) == 0: |
| 206 | obj_name_list.append({'name': obj_name2, |
| 207 | 'sign': "new", |
| 208 | 'delta_array': [row[2], row[3], |
| 209 | row[4], row[5], |
| 210 | row[6], row[7]]}) |
| 211 | total_change = [0, 0, 0, 0, 0, 0] |
| 212 | obj_name_list = sorted(obj_name_list, |
| 213 | key=lambda i: abs( |
| 214 | i['delta_array'][0]) + abs(i['delta_array'][1]), |
| 215 | reverse=True) |
| 216 | print("─" * 120) |
| 217 | print("{:<50}{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}".format( |
| 218 | "Object File name", "Status", "Flash", "RAM", "Code", "RO", "RW", "ZI")) |
| 219 | print("─" * 120) |
| 220 | for s in obj_name_list: |
| 221 | total_change = add_array(total_change, s['delta_array']) |
| 222 | print("{:<50}{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}".format(s['name'], |
| 223 | s['sign'], |
| 224 | s['delta_array'][0], |
| 225 | s['delta_array'][1], |
| 226 | s['delta_array'][2], |
| 227 | s['delta_array'][3], |
| 228 | s['delta_array'][4], |
| 229 | s['delta_array'][5])) |
| 230 | key_word = ["Flash", "RAM", "Code size", "RO Data", "RW Data", "ZI Data"] |
| 231 | print("─" * 120) |
| 232 | for i in range(6): |
| 233 | print("{:<27}= {:<6} B\t= {:<8.2f} KB".format("Total obj {} change".format( |
| 234 | key_word[i]), total_change[i], total_change[i]/1024)) |
| 235 | print("─" * 120) |
| 236 | |
| 237 | |
| 238 | def diff_lib(): |
| 239 | cursor1 = cur1.execute("select * from Library") |
| 240 | lib_name_list = [] |
| 241 | for row in cursor1: |
| 242 | lib_name1 = row[0] |
| 243 | lib_flash_size1 = row[1] |
| 244 | lib_ram_size1 = row[2] |
| 245 | lib_code_size1 = row[3] |
| 246 | lib_rodata_size1 = row[4] |
| 247 | lib_rwdata_size1 = row[5] |
| 248 | lib_zidata_size1 = row[6] |
| 249 | cursor2 = cur2.execute("select * from Library WHERE name = '{}'". |
| 250 | format(lib_name1)) |
| 251 | if len(list(cursor2)) > 0: |
| 252 | cursor2 = cur2.execute("select * from Library WHERE name = '{}'". |
| 253 | format(lib_name1)) |
| 254 | for row in cursor2: |
| 255 | lib_name2 = row[0] |
| 256 | if row[1] != lib_flash_size1 or \ |
| 257 | row[2] != lib_ram_size1 or \ |
| 258 | row[3] != lib_code_size1 or \ |
| 259 | row[4] != lib_rodata_size1 or \ |
| 260 | row[5] != lib_rwdata_size1 or \ |
| 261 | row[6] != lib_zidata_size1: |
| 262 | lib_name_list.append({'name': lib_name1, |
| 263 | 'sign': "+/-", |
| 264 | 'delta_array': [row[1] - lib_flash_size1, |
| 265 | row[2] - lib_ram_size1, |
| 266 | row[3] - lib_code_size1, |
| 267 | row[4] - lib_rodata_size1, |
| 268 | row[5] - lib_rwdata_size1, |
| 269 | row[6] - lib_zidata_size1]}) |
| 270 | else: |
| 271 | lib_name_list.append({'name': lib_name1, |
| 272 | 'sign': "del", |
| 273 | 'delta_array': [0-lib_flash_size1, |
| 274 | 0-lib_ram_size1, |
| 275 | 0-lib_code_size1, |
| 276 | 0-lib_rodata_size1, |
| 277 | 0-lib_rwdata_size1, |
| 278 | 0-lib_zidata_size1]}) |
| 279 | cursor2 = cur2.execute("select * from Library") |
| 280 | for row in cursor2: |
| 281 | lib_name2 = row[0] |
| 282 | cursor1 = cur1.execute("select * from Library WHERE name = '{}'". |
| 283 | format(lib_name2)) |
| 284 | if len(list(cursor1)) == 0: |
| 285 | lib_name_list.append({'name': lib_name2, |
| 286 | 'sign': "new", |
| 287 | 'delta_array': [row[1], row[2], |
| 288 | row[3], row[4], |
| 289 | row[5], row[6]]}) |
| 290 | total_change = [0, 0, 0, 0, 0, 0] |
| 291 | lib_name_list = sorted(lib_name_list, |
| 292 | key=lambda i: abs( |
| 293 | i['delta_array'][0]) + abs(i['delta_array'][1]), |
| 294 | reverse=True) |
| 295 | print("─" * 120) |
| 296 | print("{:<50}{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}".format( |
| 297 | "Library name", "Status", "Flash", "RAM", "Code", "RO", "RW", "ZI")) |
| 298 | print("─" * 120) |
| 299 | for s in lib_name_list: |
| 300 | total_change = add_array(total_change, s['delta_array']) |
| 301 | print("{:<50}{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}".format(s['name'], |
| 302 | s['sign'], |
| 303 | s['delta_array'][0], |
| 304 | s['delta_array'][1], |
| 305 | s['delta_array'][2], |
| 306 | s['delta_array'][3], |
| 307 | s['delta_array'][4], |
| 308 | s['delta_array'][5])) |
| 309 | key_word = ["Flash", "RAM", "Code size", "RO Data", "RW Data", "ZI Data"] |
| 310 | print("─" * 120) |
| 311 | for i in range(6): |
| 312 | print("{:<31}= {:<6} B\t= {:<8.2f} KB".format("Total Library {} change".format(key_word[i]), total_change[i], total_change[i]/1024)) |
| 313 | print("─" * 120) |
| 314 | |
| 315 | def main(args): |
| 316 | global con1, cur1, con2, cur2 |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame^] | 317 | |
| 318 | if args.based_db and args.compared_db: |
| 319 | con1 = sqlite3.connect(args.based_db) |
| 320 | cur1 = con1.cursor() |
| 321 | con2 = sqlite3.connect(args.compared_db) |
| 322 | cur2 = con2.cursor() |
| 323 | else: |
| 324 | print("Error! Two database files shall be input.") |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 325 | if args.diff_function: |
| 326 | diff_function() |
| 327 | if args.diff_data: |
| 328 | diff_data("ZI") |
| 329 | print() |
| 330 | print() |
| 331 | diff_data("RO") |
| 332 | print() |
| 333 | print() |
| 334 | diff_data("RW") |
| 335 | if args.diff_obj: |
| 336 | diff_obj() |
| 337 | if args.diff_lib: |
| 338 | diff_lib() |
| 339 | if args.diff_all: |
| 340 | diff_summary() |
| 341 | |
| 342 | def parse_args(): |
| 343 | parser = argparse.ArgumentParser() |
| 344 | |
Jianliang Shen | 28cce57 | 2022-05-02 21:44:03 +0800 | [diff] [blame^] | 345 | parser.add_argument('based_db', help='based databse') |
| 346 | parser.add_argument('compared_db', help='compared databse') |
| 347 | opt = parser.add_mutually_exclusive_group(required=True) |
| 348 | opt.add_argument('-S', '--diff-Summary', |
| 349 | dest='diff_all', |
| 350 | action='store_true', |
| 351 | help='diff summary') |
| 352 | opt.add_argument('-f', '--diff-function', |
| 353 | dest='diff_function', |
| 354 | action='store_true', |
| 355 | help='diff function') |
| 356 | opt.add_argument('-d', '--diff-data', |
| 357 | dest='diff_data', |
| 358 | action='store_true', |
| 359 | help='diff data') |
| 360 | opt.add_argument('-o', '--diff-obj', |
| 361 | dest='diff_obj', |
| 362 | action='store_true', |
| 363 | help='diff object file') |
| 364 | opt.add_argument('-l', '--diff-lib', |
| 365 | dest='diff_lib', |
| 366 | action='store_true', |
| 367 | help='diff library') |
Jianliang Shen | abf0041 | 2021-11-12 10:58:52 +0800 | [diff] [blame] | 368 | |
| 369 | args = parser.parse_args() |
| 370 | return args |
| 371 | |
| 372 | if __name__ == '__main__': |
| 373 | main(parse_args()) |
| 374 | exit(0) |