OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/python |
| 2 |
| 3 import os |
| 4 import re |
| 5 import StringIO |
| 6 import sys |
| 7 import tempfile |
| 8 import textwrap |
| 9 import tokenize |
| 10 |
| 11 |
| 12 def GetFilesList(root_dir): |
| 13 files = [] |
| 14 blacklist = ['load.ll', 'store.ll'] |
| 15 for (d, _, fs) in os.walk(root_dir): |
| 16 for f in fs: |
| 17 if f.endswith('.ll') and f not in blacklist: |
| 18 files.append(os.path.join(d, f)) |
| 19 return files |
| 20 |
| 21 |
| 22 def MakeRegexRule(match, repl): |
| 23 def Func(line): |
| 24 return re.sub(match, repl, line) |
| 25 return Func |
| 26 |
| 27 |
| 28 def MakeHexRule(match): |
| 29 def Func(line): |
| 30 m = re.match(match, line) |
| 31 if m: |
| 32 if not m.group(2).startswith('0x'): |
| 33 return m.group(1) + ',' + hex(int(m.group(2))) + '\n' |
| 34 return line |
| 35 return Func |
| 36 |
| 37 def MakeHexOpRule(match): |
| 38 def Func(line): |
| 39 m = re.match(match, line) |
| 40 if m: |
| 41 if not (m.group(3).startswith('0x') or m.group(4).startswith('x')): |
| 42 return m.group(1) + m.group(2) + hex(int(m.group(3))) + m.group(4) + '\n
' |
| 43 return line |
| 44 return Func |
| 45 |
| 46 ALL_RULES = [ |
| 47 MakeRegexRule(r' -symbolize', r' --symbolize'), |
| 48 MakeRegexRule(r'(.*-LABEL: .*):', r'\1'), |
| 49 MakeRegexRule(r'dword ptr', r'DWORD PTR'), |
| 50 MakeRegexRule(r' word ptr', r' WORD PTR'), |
| 51 MakeRegexRule(r',word ptr', r',WORD PTR'), |
| 52 MakeRegexRule(r'DWORD ptr', r'DWORD PTR'), |
| 53 MakeRegexRule(r'qword ptr', r'QWORD PTR'), |
| 54 MakeRegexRule(r'QWORD ptr', r'QWORD PTR'), |
| 55 MakeRegexRule(r'byte ptr', r'BYTE PTR'), |
| 56 MakeRegexRule(r'BYTE ptr', r'BYTE PTR'), |
| 57 MakeRegexRule(r'xmmword ptr', r'XMMWORD PTR'), |
| 58 MakeRegexRule(r'xmmword', r'XMMWORD'), |
| 59 MakeRegexRule(r'(; CHECK: .*mov.*), (.*)', r'\1,\2'), |
| 60 MakeRegexRule(r'(; CHECK: .*add.*), (.*)', r'\1,\2'), |
| 61 MakeRegexRule(r'(; CHECK_.*mov.*), (.*)', r'\1,\2'), |
| 62 MakeRegexRule(r'(; CHECK_.*add.*), (.*)', r'\1,\2'), |
| 63 MakeRegexRule(r'(; CHECK-DAG: .*mov.*), (.*)', r'\1,\2'), |
| 64 MakeRegexRule(r'(; CHECK-DAG: .*add.*), (.*)', r'\1,\2'), |
| 65 MakeRegexRule(r'(; CHECK-NEXT: .*mov.*), (.*)', r'\1,\2'), |
| 66 MakeRegexRule(r'(; CHECK-NEXT: .*add.*), (.*)', r'\1,\2'), |
| 67 MakeRegexRule(r'(; OPTM1.*mov.*), (.*)', r'\1,\2'), |
| 68 MakeRegexRule(r'(; OPTM1.*add.*), (.*)', r'\1,\2'), |
| 69 MakeRegexRule(r'(; SSE41: .*), (.*)', r'\1,\2'), |
| 70 MakeRegexRule(r'(; SSE41-NEXT: .*), (.*)', r'\1,\2'), |
| 71 MakeRegexRule(r'(; O2: .*), (.*)', r'\1,\2'), |
| 72 MakeRegexRule(r'(; O2-NEXT: .*), (.*)', r'\1,\2'), |
| 73 MakeRegexRule(r'(; OM1: .*), (.*)', r'\1,\2'), |
| 74 MakeRegexRule(r'(; OM1-NEXT: .*), (.*)', r'\1,\2'), |
| 75 # MakeRegexRule(r'(; CHECK: .*)\+ (.*)', r'\1+\2'), |
| 76 # MakeRegexRule(r'(; CHECK: .*) \+(.*)', r'\1+\2'), |
| 77 MakeRegexRule(r'(; CHECK_.*)\+ (.*)', r'\1+\2'), |
| 78 MakeRegexRule(r'(; CHECK_.*) \+(.*)', r'\1+\2'), |
| 79 # MakeRegexRule(r'(; CHECK-NEXT: .*)\+ (.*)', r'\1+\2'), |
| 80 # MakeRegexRule(r'(; CHECK-NEXT: .*) \+(.*)', r'\1+\2'), |
| 81 MakeRegexRule(r'(; OPTM1.*)\+ (.*)', r'\1+\2'), |
| 82 MakeRegexRule(r'(; OPTM1.*) \+(.*)', r'\1+\2'), |
| 83 # MakeRegexRule(r'(; OPTM1-NEXT: .*)\+ (.*)', r'\1+\2'), |
| 84 # MakeRegexRule(r'(; OPTM1-NEXT: .*) \+(.*)', r'\1+\2'), |
| 85 MakeRegexRule(r'(; O2: .*)\+ (.*)', r'\1-\2'), |
| 86 MakeRegexRule(r'(; O2: .*) \+(.*)', r'\1-\2'), |
| 87 MakeRegexRule(r'(; O2-NEXT: .*)\+ (.*)', r'\1-\2'), |
| 88 MakeRegexRule(r'(; O2-NEXT: .*) \+(.*)', r'\1-\2'), |
| 89 MakeRegexRule(r'(; OM1: .*)\+ (.*)', r'\1-\2'), |
| 90 MakeRegexRule(r'(; OM1: .*) \+(.*)', r'\1-\2'), |
| 91 MakeRegexRule(r'(; OM1-NEXT: .*)\+ (.*)', r'\1-\2'), |
| 92 MakeRegexRule(r'(; OM1-NEXT: .*) \+(.*)', r'\1-\2'), |
| 93 # MakeHexRule(r'(; CHECK: .*), ([0-9]+)$'), |
| 94 # MakeRegexRule(r'(; CHECK: .*)- (.*)', r'\1-\2'), |
| 95 # MakeRegexRule(r'(; CHECK: .*) -(.*)', r'\1-\2'), |
| 96 # MakeRegexRule(r'(; CHECK-NEXT: .*)- (.*)', r'\1-\2'), |
| 97 # MakeRegexRule(r'(; CHECK-NEXT: .*) -(.*)', r'\1-\2'), |
| 98 MakeRegexRule(r'(; OPTM1.*)- (.*)', r'\1-\2'), |
| 99 MakeRegexRule(r'(; OPTM1.*) -(.*)', r'\1-\2'), |
| 100 # MakeRegexRule(r'(; OPTM1-NEXT: .*)- (.*)', r'\1-\2'), |
| 101 # MakeRegexRule(r'(; OPTM1-NEXT: .*) -(.*)', r'\1-\2'), |
| 102 MakeHexRule(r'(; CHECK_.*), ([0-9]+)$'), |
| 103 MakeRegexRule(r'(; CHECK_.*)- (.*)', r'\1-\2'), |
| 104 MakeRegexRule(r'(; CHECK_.*) -(.*)', r'\1-\2'), |
| 105 MakeRegexRule(r'(; O2: .*)- (.*)', r'\1-\2'), |
| 106 MakeRegexRule(r'(; O2: .*) -(.*)', r'\1-\2'), |
| 107 MakeRegexRule(r'(; O2-NEXT: .*)- (.*)', r'\1-\2'), |
| 108 MakeRegexRule(r'(; O2-NEXT: .*) -(.*)', r'\1-\2'), |
| 109 MakeRegexRule(r'(; OM1: .*)- (.*)', r'\1-\2'), |
| 110 MakeRegexRule(r'(; OM1: .*) -(.*)', r'\1-\2'), |
| 111 MakeRegexRule(r'(; OM1-NEXT: .*)- (.*)', r'\1-\2'), |
| 112 MakeRegexRule(r'(; OM1-NEXT: .*) -(.*)', r'\1-\2'), |
| 113 # MakeHexRule(r'(; CHECK: .*), ([0-9]+)$'), |
| 114 MakeHexRule(r'(; CHECK_.*), ([0-9]+)$'), |
| 115 MakeHexRule(r'(; OPTM1.*), ([0-9]+)$'), |
| 116 # MakeHexRule(r'(; CHECK-NEXT: .*), ([0-9]+)$'), |
| 117 # MakeHexRule(r'(; OPTM1-NEXT: .*), ([0-9]+)$'), |
| 118 #MakeHexRule(r'(; CHECK: .*),([0-9]+)$'), |
| 119 MakeHexRule(r'(; CHECK_.*),([0-9]+)$'), |
| 120 #MakeHexRule(r'(; OPTM1: .*),([0-9]+)$'), |
| 121 #MakeHexRule(r'(; CHECK-NEXT: .*),([0-9]+)$'), |
| 122 #MakeHexRule(r'(; OPTM1-NEXT: .*),([0-9]+)$'), |
| 123 MakeHexRule(r'(; CHECK-DAG: .*),([0-9]+)$'), |
| 124 MakeHexRule(r'(; CHECK-DAG: .*),([0-9]+)$'), |
| 125 MakeHexRule(r'(; O2: .*),([0-9]+)$'), |
| 126 MakeHexRule(r'(; O2-NEXT: .*),([0-9]+)$'), |
| 127 MakeHexRule(r'(; OM1: .*),([0-9]+)$'), |
| 128 MakeHexRule(r'(; OM1-NEXT: .*),([0-9]+)$'), |
| 129 MakeHexRule(r'(; SSE41: .*),([0-9]+)$'), |
| 130 MakeHexRule(r'(; SSE41: .*),([0-9]+)$'), |
| 131 MakeHexRule(r'(; SSE41-NEXT: .*),([0-9]+)$'), |
| 132 MakeHexRule(r'(; SSE41-NEXT: .*),([0-9]+)$'), |
| 133 # This one is too blunt too, and usually they all double up the 0x0x. |
| 134 # MakeHexOpRule(r'(; CHECK-NOT: .*)( )([0-9]+)(.*)'), |
| 135 # MakeHexOpRule(r'(; CHECK: .*)(\+)([0-9]+)(.*)'), |
| 136 MakeHexOpRule(r'(; CHECK_.*)(\+)([0-9]+)(.*)'), |
| 137 MakeHexOpRule(r'(; OPTM1.*[xp])(\+)([0-9]+)(.*)'), |
| 138 # MakeHexOpRule(r'(; CHECK-NEXT: .*)(\+)([0-9]+)(.*)'), |
| 139 # MakeHexOpRule(r'(; OPTM1-NEXT: .*)(\+)([0-9]+)(.*)'), |
| 140 # MakeHexOpRule(r'(; CHECK: .*[xp])(-)([0-9]+)(.*)'), |
| 141 MakeHexOpRule(r'(; CHECK_.*[xp])(-)([0-9]+)(.*)'), |
| 142 MakeHexOpRule(r'(; OPTM1.*[xp])(-)([0-9]+)(.*)'), |
| 143 # MakeHexOpRule(r'(; CHECK-NEXT: .*[xp])(-)([0-9]+)(.*)'), |
| 144 # MakeHexOpRule(r'(; OPTM1-NEXT: .*[xp])(-)([0-9]+)(.*)'), |
| 145 # This one is too blunt (convert indirect calls and non asm too). |
| 146 #MakeRegexRule(r'(; CHECK: .*call) (.*)', r'\1 {{.*}} R_{{.*}} \2'), |
| 147 #MakeRegexRule(r'(; CHECK-NEXT: .*call) (.*)', r'\1 {{.*}} R_{{.*}} \2'), |
| 148 #MakeRegexRule(r'(; OPTM1: .*call) (.*)', r'\1 {{.*}} R_{{.*}} \2'), |
| 149 #MakeRegexRule(r'(; OPTM1-NEXT: .*call) (.*)', r'\1 {{.*}} R_{{.*}} \2'), |
| 150 ] |
| 151 |
| 152 |
| 153 def ApplyOnelinersToLine(line): |
| 154 for r in ALL_RULES: |
| 155 line = r(line) |
| 156 return line |
| 157 |
| 158 |
| 159 def ApplyOnelinersToFile(filename): |
| 160 print 'ApplyOnelinersToFile: %s' % filename |
| 161 with open(filename, 'r') as orig: |
| 162 # Create a temp file in the same directory so that it can be moved. |
| 163 # Otherwise, we cannot move out of a different filesystem like /tmp |
| 164 with tempfile.NamedTemporaryFile(dir=os.path.dirname(filename), |
| 165 delete=False) as temp: |
| 166 for line in orig.readlines(): |
| 167 newline = ApplyOnelinersToLine(line) |
| 168 if line != newline: |
| 169 print 'Rewriting %s' % line |
| 170 print 'To %s' % newline |
| 171 temp.write(newline) |
| 172 os.rename(temp.name, filename) |
| 173 |
| 174 |
| 175 # THIS DOESN'T WORK YET... The spacing between tokens is all messed up. |
| 176 def ConvertNumbersToHexLine(line): |
| 177 if not line.startswith('; CHECK'): |
| 178 return line |
| 179 result = [] |
| 180 g = tokenize.generate_tokens(StringIO.StringIO(line).readline) |
| 181 for toknum, tokval, _, _, _ in g: |
| 182 if toknum == tokenize.NUMBER: |
| 183 print 'Abouts to convert :%s ' % tokval |
| 184 result.append((tokenize.NUMBER, hex(int(tokval)))) |
| 185 else: |
| 186 result.append((toknum, tokval)) |
| 187 return tokenize.untokenize(result) |
| 188 |
| 189 |
| 190 def ConvertNumbersToHex(filename): |
| 191 print 'ConvertNumbersToHex: %s' % filename |
| 192 with open(filename, 'r') as orig: |
| 193 # Create a temp file in the same directory so that it can be moved. |
| 194 # Otherwise, we cannot move out of a different filesystem like /tmp |
| 195 with tempfile.NamedTemporaryFile(dir=os.path.dirname(filename), |
| 196 delete=False) as temp: |
| 197 for line in orig.readlines(): |
| 198 newline = ConvertNumbersToHexLine(line) |
| 199 if line != newline: |
| 200 print 'Rewriting %s' % line |
| 201 print 'To %s' % newline |
| 202 temp.write(newline) |
| 203 os.rename(temp.name, filename) |
| 204 |
| 205 |
| 206 def ApplyFunkyHeaderChanges3(lines): |
| 207 if len(lines) != 3: |
| 208 return False, None |
| 209 new1 = re.sub(r'; RUN: %p2i -i %s (.*) \\', |
| 210 r'; RUN: %p2i -i %s --assemble --disassemble \1 \\', |
| 211 lines[0]) |
| 212 match1 = new1 != lines[0] |
| 213 match2 = re.match( |
| 214 r'; RUN: \| llvm-mc -triple=i686-none-nacl -filetype=obj \\', lines[1]) |
| 215 new3 = re.sub( |
| 216 r'; RUN: \| llvm-objdump -d --symbolize -x86-asm-syntax=intel - \| (.*)', |
| 217 r'; RUN: | \1', |
| 218 lines[2]) |
| 219 match3 = new3 != lines[2] |
| 220 # Try w/ -r also. |
| 221 if not match3: |
| 222 new3 = re.sub( |
| 223 r'; RUN: \| llvm-objdump -d -r --symbolize -x86-asm-syntax=intel - \| (.
*)', |
| 224 r'; RUN: | \1', |
| 225 lines[2]) |
| 226 match3 = new3 != lines[2] |
| 227 if not (match1 and match2 and match3): |
| 228 return False, None |
| 229 maybe_wrap = textwrap.wrap(new1, 80, break_on_hyphens=False) |
| 230 if len(maybe_wrap) > 1: |
| 231 maybe_wrap[0] = maybe_wrap[0] + ' \\\n' |
| 232 for i in xrange(1, len(maybe_wrap)): |
| 233 maybe_wrap[i] = r'; RUN: ' + maybe_wrap[i] + '\n' |
| 234 return True, maybe_wrap + [new3] |
| 235 else: |
| 236 return True, [new1, new3] |
| 237 |
| 238 |
| 239 def ApplyFunkyHeaderChanges4(lines): |
| 240 if len(lines) != 4: |
| 241 return False, None |
| 242 new1 = re.sub(r'; RUN: %p2i -i %s (.*) \\', |
| 243 r'; RUN: %p2i -i %s --assemble --disassemble \1 \\', |
| 244 lines[0]) |
| 245 match1 = new1 != lines[0] |
| 246 match2 = re.match( |
| 247 r'; RUN: \| llvm-mc -triple=i686-none-nacl -filetype=obj \\', lines[1]) |
| 248 match3 = re.match( |
| 249 r'; RUN: \| llvm-objdump -d --symbolize -x86-asm-syntax=intel - \\', |
| 250 lines[2]) |
| 251 if not match3: |
| 252 match3 = re.match( |
| 253 r'; RUN: \| llvm-objdump -d -r --symbolize -x86-asm-syntax=intel - \\', |
| 254 lines[2]) |
| 255 match4 = re.match(r'; RUN: \| File.*', lines[3]) |
| 256 # There's no real change needed, but need to know if there's a match. |
| 257 new4 = lines[3] |
| 258 if not (match1 and match2 and match3 and match4): |
| 259 return False, None |
| 260 maybe_wrap = textwrap.wrap(new1, 80, break_on_hyphens=False) |
| 261 if len(maybe_wrap) > 1: |
| 262 maybe_wrap[0] = maybe_wrap[0] + ' \\\n' |
| 263 for i in xrange(1, len(maybe_wrap)): |
| 264 maybe_wrap[i] = r'; RUN: ' + maybe_wrap[i] + '\n' |
| 265 return True, maybe_wrap + [new4] |
| 266 else: |
| 267 return True, [new1, new4] |
| 268 |
| 269 |
| 270 def UndoTheCallTransformation(lines): |
| 271 if len(lines) != 2: |
| 272 return False, None |
| 273 match1 = re.match(r'(; CHECK: .*call)', lines[0]) |
| 274 new2 = re.sub( |
| 275 r'; CHECK-NEXT: (R_{{.*}} .*)', |
| 276 r' {{.*}} \1', |
| 277 lines[1]) |
| 278 match2 = new2 != lines[1] |
| 279 if not (match1 and match2): |
| 280 return False, None |
| 281 return True, [match1.group(1) + new2] |
| 282 |
| 283 |
| 284 def FixLockChecks(lines): |
| 285 if len(lines) != 2: |
| 286 return False, None |
| 287 match1 = re.match(r'(; CHECK: lock)', lines[0]) |
| 288 match2 = re.match(r'; CHECK-NEXT: (.*)', lines[1]) |
| 289 if not (match1 and match2): |
| 290 return False, None |
| 291 return True, [r'; CHECK: lock ' + match2.group(1) + '\n'] |
| 292 |
| 293 |
| 294 def ApplyMultiLineEdits(filename, applier, num_lines): |
| 295 print 'ApplyMultiLineEdits (%d): %s' % (num_lines, filename) |
| 296 with open(filename, 'r') as orig: |
| 297 lines = orig.readlines() |
| 298 for i in xrange(0, len(lines) - (num_lines + 1)): |
| 299 linesubs = lines[i:i + num_lines] |
| 300 matched, newlines = applier(linesubs) |
| 301 if matched: |
| 302 print 'Rewriting %s' % linesubs |
| 303 print 'To %s' % newlines |
| 304 lines = lines[0:i] + newlines + lines[i + num_lines:] |
| 305 with tempfile.NamedTemporaryFile(dir=os.path.dirname(filename), |
| 306 delete=False) as temp: |
| 307 for l in lines: |
| 308 temp.write(l) |
| 309 os.rename(temp.name, filename) |
| 310 |
| 311 |
| 312 def Main(argv): |
| 313 if len(argv) != 1: |
| 314 print 'Expected a directory base as args, got %s' % argv |
| 315 files = GetFilesList(argv[0]) |
| 316 for f in files: |
| 317 ApplyMultiLineEdits(f, ApplyFunkyHeaderChanges3, 3) |
| 318 ApplyMultiLineEdits(f, ApplyFunkyHeaderChanges4, 4) |
| 319 # ApplyMultiLineEdits(f, UndoTheCallTransformation, 2) |
| 320 ApplyMultiLineEdits(f, FixLockChecks, 2) |
| 321 ApplyOnelinersToFile(f) |
| 322 # ConvertNumbersToHex(f) |
| 323 return 0 |
| 324 |
| 325 |
| 326 if __name__ == '__main__': |
| 327 sys.exit(Main(sys.argv[1:])) |
OLD | NEW |