16
16
else :
17
17
DEFAULT_DIR = "/tmp/py_stats/"
18
18
19
- #Create list of all instruction names
20
- specialized = iter (opcode ._specialized_opmap .keys ())
21
- opname = ["<0>" ]
22
- for name in opcode .opname [1 :]:
23
- if name .startswith ("<" ):
24
- try :
25
- name = next (specialized )
26
- except StopIteration :
27
- pass
28
- opname .append (name )
29
-
30
- # opcode_name --> opcode
31
- # Sort alphabetically.
32
- opmap = {name : i for i , name in enumerate (opname )}
33
- opmap = dict (sorted (opmap .items ()))
34
-
35
19
TOTAL = "specialization.hit" , "specialization.miss" , "execution_count"
36
20
37
21
def format_ratio (num , den ):
@@ -200,12 +184,12 @@ def gather_stats(input):
200
184
raise ValueError (f"{ input :r} is not a file or directory path" )
201
185
202
186
def extract_opcode_stats (stats ):
203
- opcode_stats = [ {} for _ in range ( 256 ) ]
187
+ opcode_stats = collections . defaultdict ( dict )
204
188
for key , value in stats .items ():
205
189
if not key .startswith ("opcode" ):
206
190
continue
207
- n , _ , rest = key [7 :].partition ("]" )
208
- opcode_stats [int ( n ) ][rest .strip ("." )] = value
191
+ name , _ , rest = key [7 :].partition ("]" )
192
+ opcode_stats [name ][rest .strip ("." )] = value
209
193
return opcode_stats
210
194
211
195
def parse_kinds (spec_src , prefix = "SPEC_FAIL" ):
@@ -246,11 +230,10 @@ def categorized_counts(opcode_stats):
246
230
specialized_instructions = {
247
231
op for op in opcode ._specialized_opmap .keys ()
248
232
if "__" not in op }
249
- for i , opcode_stat in enumerate ( opcode_stats ):
233
+ for name , opcode_stat in opcode_stats . items ( ):
250
234
if "execution_count" not in opcode_stat :
251
235
continue
252
236
count = opcode_stat ['execution_count' ]
253
- name = opname [i ]
254
237
if "specializable" in opcode_stat :
255
238
not_specialized += count
256
239
elif name in specialized_instructions :
@@ -314,13 +297,13 @@ def emit_table(header, rows):
314
297
315
298
def calculate_execution_counts (opcode_stats , total ):
316
299
counts = []
317
- for i , opcode_stat in enumerate ( opcode_stats ):
300
+ for name , opcode_stat in opcode_stats . items ( ):
318
301
if "execution_count" in opcode_stat :
319
302
count = opcode_stat ['execution_count' ]
320
303
miss = 0
321
304
if "specializable" not in opcode_stat :
322
305
miss = opcode_stat .get ("specialization.miss" )
323
- counts .append ((count , opname [ i ] , miss ))
306
+ counts .append ((count , name , miss ))
324
307
counts .sort (reverse = True )
325
308
cumulative = 0
326
309
rows = []
@@ -381,16 +364,17 @@ def get_defines():
381
364
def emit_specialization_stats (opcode_stats ):
382
365
defines = get_defines ()
383
366
with Section ("Specialization stats" , summary = "specialization stats by family" ):
384
- for i , opcode_stat in enumerate (opcode_stats ):
385
- name = opname [i ]
367
+ for name , opcode_stat in opcode_stats .items ():
386
368
print_specialization_stats (name , opcode_stat , defines )
387
369
388
370
def emit_comparative_specialization_stats (base_opcode_stats , head_opcode_stats ):
389
371
defines = get_defines ()
390
372
with Section ("Specialization stats" , summary = "specialization stats by family" ):
391
- for i , (base_opcode_stat , head_opcode_stat ) in enumerate (zip (base_opcode_stats , head_opcode_stats )):
392
- name = opname [i ]
393
- print_comparative_specialization_stats (name , base_opcode_stat , head_opcode_stat , defines )
373
+ opcodes = set (base_opcode_stats .keys ()) & set (head_opcode_stats .keys ())
374
+ for opcode in opcodes :
375
+ print_comparative_specialization_stats (
376
+ opcode , base_opcode_stats [opcode ], head_opcode_stats [opcode ], defines
377
+ )
394
378
395
379
def calculate_specialization_effectiveness (opcode_stats , total ):
396
380
basic , not_specialized , specialized = categorized_counts (opcode_stats )
@@ -407,12 +391,12 @@ def emit_specialization_overview(opcode_stats, total):
407
391
for title , field in (("Deferred" , "specialization.deferred" ), ("Misses" , "specialization.miss" )):
408
392
total = 0
409
393
counts = []
410
- for i , opcode_stat in enumerate ( opcode_stats ):
394
+ for name , opcode_stat in opcode_stats . items ( ):
411
395
# Avoid double counting misses
412
396
if title == "Misses" and "specializable" in opcode_stat :
413
397
continue
414
398
value = opcode_stat .get (field , 0 )
415
- counts .append ((value , opname [ i ] ))
399
+ counts .append ((value , name ))
416
400
total += value
417
401
counts .sort (reverse = True )
418
402
if total :
@@ -539,29 +523,27 @@ def emit_comparative_gc_stats(base_stats, head_stats):
539
523
540
524
def get_total (opcode_stats ):
541
525
total = 0
542
- for opcode_stat in opcode_stats :
526
+ for opcode_stat in opcode_stats . values () :
543
527
if "execution_count" in opcode_stat :
544
528
total += opcode_stat ['execution_count' ]
545
529
return total
546
530
547
531
def emit_pair_counts (opcode_stats , total ):
548
532
pair_counts = []
549
- for i , opcode_stat in enumerate (opcode_stats ):
550
- if i == 0 :
551
- continue
533
+ for name_i , opcode_stat in opcode_stats .items ():
552
534
for key , value in opcode_stat .items ():
553
535
if key .startswith ("pair_count" ):
554
- x , _ , _ = key [11 :].partition ("]" )
536
+ name_j , _ , _ = key [11 :].partition ("]" )
555
537
if value :
556
- pair_counts .append ((value , (i , int ( x ) )))
538
+ pair_counts .append ((value , (name_i , name_j )))
557
539
with Section ("Pair counts" , summary = "Pair counts for top 100 pairs" ):
558
540
pair_counts .sort (reverse = True )
559
541
cumulative = 0
560
542
rows = []
561
543
for (count , pair ) in itertools .islice (pair_counts , 100 ):
562
- i , j = pair
544
+ name_i , name_j = pair
563
545
cumulative += count
564
- rows .append ((opname [ i ] + " " + opname [ j ] , count , format_ratio (count , total ),
546
+ rows .append ((f" { name_i } { name_j } " , count , format_ratio (count , total ),
565
547
format_ratio (cumulative , total )))
566
548
emit_table (("Pair" , "Count:" , "Self:" , "Cumulative:" ),
567
549
rows
@@ -577,18 +559,18 @@ def emit_pair_counts(opcode_stats, total):
577
559
successors [first ][second ] = count
578
560
total_predecessors [second ] += count
579
561
total_successors [first ] += count
580
- for name , i in opmap . items ():
581
- total1 = total_predecessors [i ]
582
- total2 = total_successors [i ]
562
+ for name in opcode_stats . keys ():
563
+ total1 = total_predecessors [name ]
564
+ total2 = total_successors [name ]
583
565
if total1 == 0 and total2 == 0 :
584
566
continue
585
567
pred_rows = succ_rows = ()
586
568
if total1 :
587
- pred_rows = [(opname [ pred ] , count , f"{ count / total1 :.1%} " )
588
- for (pred , count ) in predecessors [i ].most_common (5 )]
569
+ pred_rows = [(pred , count , f"{ count / total1 :.1%} " )
570
+ for (pred , count ) in predecessors [name ].most_common (5 )]
589
571
if total2 :
590
- succ_rows = [(opname [ succ ] , count , f"{ count / total2 :.1%} " )
591
- for (succ , count ) in successors [i ].most_common (5 )]
572
+ succ_rows = [(succ , count , f"{ count / total2 :.1%} " )
573
+ for (succ , count ) in successors [name ].most_common (5 )]
592
574
with Section (name , 3 , f"Successors and predecessors for { name } " ):
593
575
emit_table (("Predecessors" , "Count:" , "Percentage:" ),
594
576
pred_rows
0 commit comments