@@ -211,12 +211,12 @@ def gather_stats(input):
211
211
else :
212
212
raise ValueError (f"{ input :r} is not a file or directory path" )
213
213
214
- def extract_opcode_stats (stats ):
214
+ def extract_opcode_stats (stats , prefix ):
215
215
opcode_stats = collections .defaultdict (dict )
216
216
for key , value in stats .items ():
217
- if not key .startswith ("opcode" ):
217
+ if not key .startswith (prefix ):
218
218
continue
219
- name , _ , rest = key [7 :].partition ("]" )
219
+ name , _ , rest = key [len ( prefix ) + 2 :].partition ("]" )
220
220
opcode_stats [name ][rest .strip ("." )] = value
221
221
return opcode_stats
222
222
@@ -350,35 +350,38 @@ def emit_execution_counts(opcode_stats, total):
350
350
rows
351
351
)
352
352
353
+ def _emit_comparative_execution_counts (base_rows , head_rows ):
354
+ base_data = dict ((x [0 ], x [1 :]) for x in base_rows )
355
+ head_data = dict ((x [0 ], x [1 :]) for x in head_rows )
356
+ opcodes = set (base_data .keys ()) | set (head_data .keys ())
357
+
358
+ rows = []
359
+ default = [0 , "0.0%" , "0.0%" , 0 ]
360
+ for opcode in opcodes :
361
+ base_entry = base_data .get (opcode , default )
362
+ head_entry = head_data .get (opcode , default )
363
+ if base_entry [0 ] == 0 :
364
+ change = 1
365
+ else :
366
+ change = (head_entry [0 ] - base_entry [0 ]) / base_entry [0 ]
367
+ rows .append (
368
+ (opcode , base_entry [0 ], head_entry [0 ],
369
+ f"{ 100 * change :0.1f} %" ))
370
+
371
+ rows .sort (key = lambda x : - abs (percentage_to_float (x [- 1 ])))
372
+
373
+ emit_table (
374
+ ("Name" , "Base Count:" , "Head Count:" , "Change:" ),
375
+ rows
376
+ )
377
+
353
378
def emit_comparative_execution_counts (
354
- base_opcode_stats , base_total , head_opcode_stats , head_total
379
+ base_opcode_stats , base_total , head_opcode_stats , head_total , level = 2
355
380
):
356
- with Section ("Execution counts" , summary = "execution counts for all instructions" ):
381
+ with Section ("Execution counts" , summary = "execution counts for all instructions" , level = level ):
357
382
base_rows = calculate_execution_counts (base_opcode_stats , base_total )
358
383
head_rows = calculate_execution_counts (head_opcode_stats , head_total )
359
- base_data = dict ((x [0 ], x [1 :]) for x in base_rows )
360
- head_data = dict ((x [0 ], x [1 :]) for x in head_rows )
361
- opcodes = set (base_data .keys ()) | set (head_data .keys ())
362
-
363
- rows = []
364
- default = [0 , "0.0%" , "0.0%" , 0 ]
365
- for opcode in opcodes :
366
- base_entry = base_data .get (opcode , default )
367
- head_entry = head_data .get (opcode , default )
368
- if base_entry [0 ] == 0 :
369
- change = 1
370
- else :
371
- change = (head_entry [0 ] - base_entry [0 ]) / base_entry [0 ]
372
- rows .append (
373
- (opcode , base_entry [0 ], head_entry [0 ],
374
- f"{ 100 * change :0.1f} %" ))
375
-
376
- rows .sort (key = lambda x : - abs (percentage_to_float (x [- 1 ])))
377
-
378
- emit_table (
379
- ("Name" , "Base Count:" , "Head Count:" , "Change:" ),
380
- rows
381
- )
384
+ _emit_comparative_execution_counts (base_rows , head_rows )
382
385
383
386
def get_defines ():
384
387
spec_path = os .path .join (os .path .dirname (__file__ ), "../../Python/specialize.c" )
@@ -611,8 +614,76 @@ def emit_pair_counts(opcode_stats, total):
611
614
succ_rows
612
615
)
613
616
617
+
618
+ def calculate_optimization_stats (stats ):
619
+ attempts = stats ["Optimization attempts" ]
620
+ created = stats ["Optimization traces created" ]
621
+ executed = stats ["Optimization traces executed" ]
622
+ uops = stats ["Optimization uops executed" ]
623
+
624
+ return [
625
+ ("Optimization attempts" , attempts , "" ),
626
+ (
627
+ "Traces created" , created ,
628
+ format_ratio (created , attempts )
629
+ ),
630
+ ("Traces executed" , executed , "" ),
631
+ ("Uops executed" , uops , format_ratio (uops , executed ))
632
+ ]
633
+
634
+
635
+ def calculate_uop_execution_counts (opcode_stats ):
636
+ total = 0
637
+ counts = []
638
+ for name , opcode_stat in opcode_stats .items ():
639
+ if "execution_count" in opcode_stat :
640
+ count = opcode_stat ['execution_count' ]
641
+ counts .append ((count , name ))
642
+ total += count
643
+ counts .sort (reverse = True )
644
+ cumulative = 0
645
+ rows = []
646
+ for (count , name ) in counts :
647
+ cumulative += count
648
+ rows .append ((name , count , format_ratio (count , total ),
649
+ format_ratio (cumulative , total )))
650
+ return rows
651
+
652
+
653
+ def emit_optimization_stats (stats ):
654
+ uop_stats = extract_opcode_stats (stats , "uop" )
655
+
656
+ with Section ("Optimization (Tier 2) stats" , summary = "statistics about the Tier 2 optimizer" ):
657
+ with Section ("Overall stats" , level = 3 ):
658
+ rows = calculate_optimization_stats (stats )
659
+ emit_table (("" , "Count:" , "Ratio:" ), rows )
660
+
661
+ with Section ("Uop stats" , level = 3 ):
662
+ rows = calculate_uop_execution_counts (uop_stats )
663
+ emit_table (
664
+ ("Uop" , "Count:" , "Self:" , "Cumulative:" ),
665
+ rows
666
+ )
667
+
668
+
669
+ def emit_comparative_optimization_stats (base_stats , head_stats ):
670
+ base_uop_stats = extract_opcode_stats (base_stats , "uop" )
671
+ head_uop_stats = extract_opcode_stats (head_stats , "uop" )
672
+
673
+ with Section ("Optimization (Tier 2) stats" , summary = "statistics about the Tier 2 optimizer" ):
674
+ with Section ("Overall stats" , level = 3 ):
675
+ base_rows = calculate_optimization_stats (base_stats )
676
+ head_rows = calculate_optimization_stats (head_stats )
677
+ emit_table (("" , "Base Count:" , "Base Ratio:" , "Head Count:" , "Head Ratio:" ), join_rows (base_rows , head_rows ))
678
+
679
+ with Section ("Uop stats" , level = 3 ):
680
+ base_rows = calculate_uop_execution_counts (base_uop_stats )
681
+ head_rows = calculate_uop_execution_counts (head_uop_stats )
682
+ _emit_comparative_execution_counts (base_rows , head_rows )
683
+
684
+
614
685
def output_single_stats (stats ):
615
- opcode_stats = extract_opcode_stats (stats )
686
+ opcode_stats = extract_opcode_stats (stats , "opcode" )
616
687
total = get_total (opcode_stats )
617
688
emit_execution_counts (opcode_stats , total )
618
689
emit_pair_counts (opcode_stats , total )
@@ -621,15 +692,16 @@ def output_single_stats(stats):
621
692
emit_call_stats (stats , stats ["_stats_defines" ])
622
693
emit_object_stats (stats )
623
694
emit_gc_stats (stats )
695
+ emit_optimization_stats (stats )
624
696
with Section ("Meta stats" , summary = "Meta statistics" ):
625
697
emit_table (("" , "Count:" ), [('Number of data files' , stats ['__nfiles__' ])])
626
698
627
699
628
700
def output_comparative_stats (base_stats , head_stats ):
629
- base_opcode_stats = extract_opcode_stats (base_stats )
701
+ base_opcode_stats = extract_opcode_stats (base_stats , "opcode" )
630
702
base_total = get_total (base_opcode_stats )
631
703
632
- head_opcode_stats = extract_opcode_stats (head_stats )
704
+ head_opcode_stats = extract_opcode_stats (head_stats , "opcode" )
633
705
head_total = get_total (head_opcode_stats )
634
706
635
707
emit_comparative_execution_counts (
@@ -645,6 +717,7 @@ def output_comparative_stats(base_stats, head_stats):
645
717
emit_comparative_call_stats (base_stats , head_stats , head_stats ["_stats_defines" ])
646
718
emit_comparative_object_stats (base_stats , head_stats )
647
719
emit_comparative_gc_stats (base_stats , head_stats )
720
+ emit_comparative_optimization_stats (base_stats , head_stats )
648
721
649
722
def output_stats (inputs , json_output = None ):
650
723
if len (inputs ) == 1 :
0 commit comments