@@ -559,6 +559,22 @@ def genOrderFile(args):
559559
560560 return 0
561561
562+ def filter_bolt_optimized (inputs , instrumented_outputs )
563+ new_inputs = []
564+ new_instrumented_ouputs = []
565+ for input , instrumented_output in zip (inputs , instrumented_outputs ):
566+ output = subprocess .check_output (
567+ [opts .readelf , "-WS" , input ], universal_newlines = True
568+ )
569+
570+ # This binary has already been bolt-optimized, so skip further processing.
571+ if re .search ("\\ .bolt\\ .org\\ .text" , output , re .MULTILINE ):
572+ print (f"Skipping { input } , it's already instrumented" )
573+ else :
574+ new_inputs .append (input )
575+ new_instrumented_ouputs .append (instrumented_output )
576+ return new_inputs , new_instrumented_ouputs
577+
562578
563579def bolt_optimize (args ):
564580 parser = argparse .ArgumentParser ("%prog [options] " )
@@ -574,47 +590,66 @@ def bolt_optimize(args):
574590
575591 opts = parser .parse_args (args )
576592
577- output = subprocess . check_output (
578- [ opts .readelf , "-WS" , opts . input ], universal_newlines = True
579- )
593+ inputs = opts . input . split ( ';' )
594+ instrumented_outputs = opts .instrumented_output . split ( ';' )
595+ assert len ( inputs ) == len ( instrumented_outputs ), "inconsistent --input / --instrumented-output arguments"
580596
581- # This binary has already been bolt-optimized, so skip further processing.
582- if re . search ( " \\ .bolt \\ .org \\ .text" , output , re . MULTILINE ) :
597+ inputs , instrumented_outputs = filter_bolt_optimized ( inputs , instrumented_outputs )
598+ if not inputs :
583599 return 0
584600
601+ environ = os .environ .copy ()
585602 if opts .method == "INSTRUMENT" :
586- process = subprocess .run (
587- [
588- opts .bolt ,
589- opts .input ,
590- "-o" ,
591- opts .instrumented_output ,
592- "-instrument" ,
593- "--instrumentation-file-append-pid" ,
594- f"--instrumentation-file={ opts .fdata } " ,
595- ],
596- stdout = subprocess .PIPE ,
597- stderr = subprocess .STDOUT ,
598- text = True ,
599- )
603+ preloads = []
604+ for input , instrumented_output in zip (inputs , instrumented_outputs ):
605+ args = [
606+ opts .bolt ,
607+ input ,
608+ "-o" ,
609+ instrumented_output ,
610+ "-instrument" ,
611+ "--instrumentation-file-append-pid" ,
612+ f"--instrumentation-file={ opts .fdata } " ,
613+ ]
614+ print ("Running: " + " " .join (args ))
615+ process = subprocess .run (
616+ args ,
617+ stdout = subprocess .PIPE ,
618+ stderr = subprocess .STDOUT ,
619+ text = True ,
620+ )
600621
601- print (process .args )
602- for line in process .stdout :
603- sys .stdout .write (line )
604- process .check_returncode ()
622+ for line in process .stdout :
623+ sys .stdout .write (line )
624+ process .check_returncode ()
605625
606- process = subprocess .run (
607- [
626+ output = subprocess .check_output (
627+ [opts .readelf , "--file-header" , input ], universal_newlines = True
628+ )
629+ if re .search (r"Type:\s*((Shared)|(DYN))" , output ):
630+ # force using the instrumented version
631+ preloads .append (instrumented_output )
632+
633+ if preloads :
634+ print ("Patching execution environment for dynamic library" )
635+ environ ["LD_PRELOAD" ] = os .pathsep .join (preloads )
636+
637+
638+ args = [
608639 sys .executable ,
609640 opts .lit ,
610- os .path .join (opts .perf_training_binary_dir , "bolt-fdata" ),
611- ],
641+ "-v" ,
642+ os .path .join (opts .perf_training_binary_dir , f"bolt-fdata" ),
643+ ]
644+ print ("Running: " + " " .join (args ))
645+ process = subprocess .run (
646+ args ,
612647 stdout = subprocess .PIPE ,
613648 stderr = subprocess .STDOUT ,
614649 text = True ,
650+ env = environ ,
615651 )
616652
617- print (process .args )
618653 for line in process .stdout :
619654 sys .stdout .write (line )
620655 process .check_returncode ()
@@ -624,35 +659,37 @@ def bolt_optimize(args):
624659
625660 merge_fdata ([opts .merge_fdata , opts .fdata , opts .perf_training_binary_dir ])
626661
627- shutil .copy (opts .input , f"{ opts .input } -prebolt" )
662+ for input in inputs :
663+ shutil .copy (input , f"{ input } -prebolt" )
628664
629- process = subprocess .run (
630- [
631- opts .bolt ,
632- f"{ opts .input } -prebolt" ,
633- "-o" ,
634- opts .input ,
635- "-data" ,
636- opts .fdata ,
637- "-reorder-blocks=ext-tsp" ,
638- "-reorder-functions=cdsort" ,
639- "-split-functions" ,
640- "-split-all-cold" ,
641- "-split-eh" ,
642- "-dyno-stats" ,
643- "-use-gnu-stack" ,
644- "-update-debug-sections" ,
645- "-nl" if opts .method == "PERF" else "" ,
646- ],
647- stdout = subprocess .PIPE ,
648- stderr = subprocess .STDOUT ,
649- text = True ,
650- )
665+ args = [
666+ opts .bolt ,
667+ f"{ input } -prebolt" ,
668+ "-o" ,
669+ input ,
670+ "-data" ,
671+ opts .fdata ,
672+ "-reorder-blocks=ext-tsp" ,
673+ "-reorder-functions=cdsort" ,
674+ "-split-functions" ,
675+ "-split-all-cold" ,
676+ "-split-eh" ,
677+ "-dyno-stats" ,
678+ "-use-gnu-stack" ,
679+ "-update-debug-sections" ,
680+ "-nl" if opts .method == "PERF" else "" ,
681+ ]
682+ print ("Running: " + " " .join (args ))
683+ process = subprocess .run (
684+ args ,
685+ stdout = subprocess .PIPE ,
686+ stderr = subprocess .STDOUT ,
687+ text = True ,
688+ )
651689
652- print (process .args )
653- for line in process .stdout :
654- sys .stdout .write (line )
655- process .check_returncode ()
690+ for line in process .stdout :
691+ sys .stdout .write (line )
692+ process .check_returncode ()
656693
657694
658695commands = {
0 commit comments