2323# read options from config file llvm-bolt-wrapper.ini in script CWD
2424#
2525# [config]
26- # base_bolt = /full/path/to/llvm-bolt.real # mandatory
27- # cmp_bolt = /full/path/to/other/llvm-bolt # mandatory
28- # verbose # optional, defaults to False
29- # keep_tmp # optional, defaults to False
30- # no_minimize # optional, defaults to False
31- # run_sequentially # optional, defaults to False
32- # compare_output # optional, defaults to False
33- # timing_file = timing1.log # optional, defaults to timing.log
26+ # # mandatory
27+ # base_bolt = /full/path/to/llvm-bolt.real
28+ # cmp_bolt = /full/path/to/other/llvm-bolt
29+ # # optional, default to False
30+ # verbose
31+ # keep_tmp
32+ # no_minimize
33+ # run_sequentially
34+ # compare_output
35+ # skip_binary_cmp
36+ # # optional, defaults to timing.log in CWD
37+ # timing_file = timing1.log
3438
3539cfg = configparser .ConfigParser (allow_no_value = True )
3640cfgs = cfg .read ("llvm-bolt-wrapper.ini" )
@@ -56,6 +60,7 @@ def get_cfg(key):
5660NO_MINIMIZE = get_cfg ('no_minimize' )
5761RUN_SEQUENTIALLY = get_cfg ('run_sequentially' )
5862COMPARE_OUTPUT = get_cfg ('compare_output' )
63+ SKIP_BINARY_CMP = get_cfg ('skip_binary_cmp' )
5964TIMING_FILE = cfg ['config' ].get ('timing_file' , 'timing.log' )
6065
6166# perf2bolt mode
@@ -75,6 +80,8 @@ def get_cfg(key):
7580 'BOLT-INFO: BOLT version' ,
7681 '^Args: ' ,
7782 '^BOLT-DEBUG:' ,
83+ 'BOLT-INFO:.*data.*output data' ,
84+ 'WARNING: reading perf data directly' ,
7885]
7986
8087def run_cmd (cmd ):
@@ -124,26 +131,26 @@ def write_to(txt, filename, mode='w'):
124131def wait (proc ):
125132 try :
126133 out , err = proc .communicate (timeout = 9000 )
127- except TimeoutExpired :
134+ except subprocess . TimeoutExpired :
128135 proc .kill ()
129136 out , err = proc .communicate ()
130137 return out , err
131138
132- def compare_logs (main , cmp ):
139+ def compare_logs (main , cmp , skip_end = 0 ):
133140 '''
134141 Compares logs but allows for certain lines to be excluded from comparison.
135142 Returns None on success, mismatch otherwise.
136143 '''
137- for main_line , cmp_line in zip (main .splitlines (), cmp .splitlines ()):
138- if main_line != cmp_line :
144+ for lhs , rhs in list ( zip (main .splitlines (), cmp .splitlines ()))[: - skip_end ] :
145+ if lhs != rhs :
139146 # check skip patterns
140147 for skip in SKIP_MATCH :
141148 # both lines must contain the pattern
142- if re .search (skip , main_line ) and re .search (skip , cmp_line ):
149+ if re .search (skip , lhs ) and re .search (skip , rhs ):
143150 break
144151 # otherwise return mismatching lines
145152 else :
146- return (main_line , cmp_line )
153+ return (lhs , rhs )
147154 return None
148155
149156def fmt_cmp (cmp_tuple ):
@@ -196,18 +203,18 @@ def main():
196203 args = prepend_dash (args )
197204
198205 # run both BOLT binaries
199- main_bolt = run_bolt (BASE_BOLT , args + unknownargs )
206+ main_bolt = run_bolt (BASE_BOLT , unknownargs + args )
200207 if RUN_SEQUENTIALLY :
201208 main_out , main_err = wait (main_bolt )
202- cmp_bolt = run_bolt (CMP_BOLT , cmp_args + unknownargs )
209+ cmp_bolt = run_bolt (CMP_BOLT , unknownargs + cmp_args )
203210 else :
204- cmp_bolt = run_bolt (CMP_BOLT , cmp_args + unknownargs )
211+ cmp_bolt = run_bolt (CMP_BOLT , unknownargs + cmp_args )
205212 main_out , main_err = wait (main_bolt )
206213 cmp_out , cmp_err = wait (cmp_bolt )
207214
208215 # compare logs
209216 out = compare_logs (main_out , cmp_out )
210- err = compare_logs (main_err , cmp_err )
217+ err = compare_logs (main_err , cmp_err , skip_end = 1 ) # skips the line with time
211218 if (main_bolt .returncode != cmp_bolt .returncode or
212219 (COMPARE_OUTPUT and (out or err ))):
213220 print (tmp )
@@ -225,20 +232,26 @@ def main():
225232 # report binary timing as csv: output binary; base bolt real; cmp bolt real
226233 report_real_time (main_binary , main_err , cmp_err )
227234
228- cmp_proc = subprocess .run (['cmp' , main_binary , cmp_binary ],
229- capture_output = True , text = True )
230- if cmp_proc .returncode :
231- # check if ELF headers match
232- hdr = compare_headers (main_binary , cmp_binary )
233- if hdr :
234- print (fmt_cmp (hdr ))
235- write_to (fmt_cmp (hdr ), os .path .join (tmp , 'headers.txt' ))
236- exit ("headers mismatch" )
237- # check which section has the first mismatch
238- mismatch_offset = parse_cmp_offset (cmp_proc .stdout )
239- print (mismatch_offset )
240- # since headers match, check which section this offset falls into
241- exit ("binaries mismatch" )
235+ if not SKIP_BINARY_CMP :
236+ cmp_proc = subprocess .run (['cmp' , main_binary , cmp_binary ],
237+ capture_output = True , text = True )
238+ if cmp_proc .returncode :
239+ # check if output is an ELF file (magic bytes)
240+ with open (main_binary , 'rb' ) as f :
241+ magic = f .read (4 )
242+ if magic != b'\x7f ELF' :
243+ exit ("output mismatch" )
244+ # check if ELF headers match
245+ hdr = compare_headers (main_binary , cmp_binary )
246+ if hdr :
247+ print (fmt_cmp (hdr ))
248+ write_to (fmt_cmp (hdr ), os .path .join (tmp , 'headers.txt' ))
249+ exit ("headers mismatch" )
250+ # check which section has the first mismatch
251+ mismatch_offset = parse_cmp_offset (cmp_proc .stdout )
252+ print (mismatch_offset )
253+ # since headers match, check which section this offset falls into
254+ exit ("binaries mismatch" )
242255
243256 # temp files are only cleaned on success
244257 if not KEEP_TMP :
0 commit comments