OLD | NEW |
1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file implements the TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 TypeToRegisterSet[IceType_v8i1] = VectorRegisters; | 295 TypeToRegisterSet[IceType_v8i1] = VectorRegisters; |
296 TypeToRegisterSet[IceType_v16i1] = VectorRegisters; | 296 TypeToRegisterSet[IceType_v16i1] = VectorRegisters; |
297 TypeToRegisterSet[IceType_v16i8] = VectorRegisters; | 297 TypeToRegisterSet[IceType_v16i8] = VectorRegisters; |
298 TypeToRegisterSet[IceType_v8i16] = VectorRegisters; | 298 TypeToRegisterSet[IceType_v8i16] = VectorRegisters; |
299 TypeToRegisterSet[IceType_v4i32] = VectorRegisters; | 299 TypeToRegisterSet[IceType_v4i32] = VectorRegisters; |
300 TypeToRegisterSet[IceType_v4f32] = VectorRegisters; | 300 TypeToRegisterSet[IceType_v4f32] = VectorRegisters; |
301 } | 301 } |
302 | 302 |
303 void TargetX8632::translateO2() { | 303 void TargetX8632::translateO2() { |
304 GlobalContext *Context = Func->getContext(); | 304 GlobalContext *Context = Func->getContext(); |
| 305 static TimerIdT IDO2 = GlobalContext::getTimerID("O2"); |
| 306 TimerMarker T(IDO2, Context); |
305 | 307 |
306 // Lower Phi instructions. | 308 // Lower Phi instructions. |
307 Timer T_placePhiLoads; | |
308 Func->placePhiLoads(); | 309 Func->placePhiLoads(); |
309 if (Func->hasError()) | 310 if (Func->hasError()) |
310 return; | 311 return; |
311 T_placePhiLoads.printElapsedUs(Context, "placePhiLoads()"); | |
312 Timer T_placePhiStores; | |
313 Func->placePhiStores(); | 312 Func->placePhiStores(); |
314 if (Func->hasError()) | 313 if (Func->hasError()) |
315 return; | 314 return; |
316 T_placePhiStores.printElapsedUs(Context, "placePhiStores()"); | |
317 Timer T_deletePhis; | |
318 Func->deletePhis(); | 315 Func->deletePhis(); |
319 if (Func->hasError()) | 316 if (Func->hasError()) |
320 return; | 317 return; |
321 T_deletePhis.printElapsedUs(Context, "deletePhis()"); | |
322 Func->dump("After Phi lowering"); | 318 Func->dump("After Phi lowering"); |
323 | 319 |
324 // Address mode optimization. | 320 // Address mode optimization. |
325 Timer T_doAddressOpt; | |
326 Func->getVMetadata()->init(); | 321 Func->getVMetadata()->init(); |
327 Func->doAddressOpt(); | 322 Func->doAddressOpt(); |
328 T_doAddressOpt.printElapsedUs(Context, "doAddressOpt()"); | |
329 | 323 |
330 // Argument lowering | 324 // Argument lowering |
331 Timer T_argLowering; | |
332 Func->doArgLowering(); | 325 Func->doArgLowering(); |
333 T_argLowering.printElapsedUs(Context, "lowerArguments()"); | |
334 | 326 |
335 // Target lowering. This requires liveness analysis for some parts | 327 // Target lowering. This requires liveness analysis for some parts |
336 // of the lowering decisions, such as compare/branch fusing. If | 328 // of the lowering decisions, such as compare/branch fusing. If |
337 // non-lightweight liveness analysis is used, the instructions need | 329 // non-lightweight liveness analysis is used, the instructions need |
338 // to be renumbered first. TODO: This renumbering should only be | 330 // to be renumbered first. TODO: This renumbering should only be |
339 // necessary if we're actually calculating live intervals, which we | 331 // necessary if we're actually calculating live intervals, which we |
340 // only do for register allocation. | 332 // only do for register allocation. |
341 Timer T_renumber1; | |
342 Func->renumberInstructions(); | 333 Func->renumberInstructions(); |
343 if (Func->hasError()) | 334 if (Func->hasError()) |
344 return; | 335 return; |
345 T_renumber1.printElapsedUs(Context, "renumberInstructions()"); | |
346 | 336 |
347 // TODO: It should be sufficient to use the fastest liveness | 337 // TODO: It should be sufficient to use the fastest liveness |
348 // calculation, i.e. livenessLightweight(). However, for some | 338 // calculation, i.e. livenessLightweight(). However, for some |
349 // reason that slows down the rest of the translation. Investigate. | 339 // reason that slows down the rest of the translation. Investigate. |
350 Timer T_liveness1; | |
351 Func->liveness(Liveness_Basic); | 340 Func->liveness(Liveness_Basic); |
352 if (Func->hasError()) | 341 if (Func->hasError()) |
353 return; | 342 return; |
354 T_liveness1.printElapsedUs(Context, "liveness()"); | |
355 Func->dump("After x86 address mode opt"); | 343 Func->dump("After x86 address mode opt"); |
356 | 344 |
357 Timer T_genCode; | |
358 Func->genCode(); | 345 Func->genCode(); |
359 if (Func->hasError()) | 346 if (Func->hasError()) |
360 return; | 347 return; |
361 T_genCode.printElapsedUs(Context, "genCode()"); | |
362 | 348 |
363 // Register allocation. This requires instruction renumbering and | 349 // Register allocation. This requires instruction renumbering and |
364 // full liveness analysis. | 350 // full liveness analysis. |
365 Timer T_renumber2; | |
366 Func->renumberInstructions(); | 351 Func->renumberInstructions(); |
367 if (Func->hasError()) | 352 if (Func->hasError()) |
368 return; | 353 return; |
369 T_renumber2.printElapsedUs(Context, "renumberInstructions()"); | |
370 Timer T_liveness2; | |
371 Func->liveness(Liveness_Intervals); | 354 Func->liveness(Liveness_Intervals); |
372 if (Func->hasError()) | 355 if (Func->hasError()) |
373 return; | 356 return; |
374 T_liveness2.printElapsedUs(Context, "liveness()"); | |
375 // Validate the live range computations. Do it outside the timing | 357 // Validate the live range computations. Do it outside the timing |
376 // code. TODO: Put this under a flag. | 358 // code. TODO: Put this under a flag. |
377 bool ValidLiveness = Func->validateLiveness(); | 359 bool ValidLiveness = Func->validateLiveness(); |
378 assert(ValidLiveness); | 360 assert(ValidLiveness); |
379 (void)ValidLiveness; // used only in assert() | 361 (void)ValidLiveness; // used only in assert() |
380 ComputedLiveRanges = true; | 362 ComputedLiveRanges = true; |
381 // The post-codegen dump is done here, after liveness analysis and | 363 // The post-codegen dump is done here, after liveness analysis and |
382 // associated cleanup, to make the dump cleaner and more useful. | 364 // associated cleanup, to make the dump cleaner and more useful. |
383 Func->dump("After initial x8632 codegen"); | 365 Func->dump("After initial x8632 codegen"); |
384 Timer T_regAlloc; | |
385 Func->getVMetadata()->init(); | 366 Func->getVMetadata()->init(); |
386 regAlloc(); | 367 regAlloc(); |
387 if (Func->hasError()) | 368 if (Func->hasError()) |
388 return; | 369 return; |
389 T_regAlloc.printElapsedUs(Context, "regAlloc()"); | |
390 Func->dump("After linear scan regalloc"); | 370 Func->dump("After linear scan regalloc"); |
391 | 371 |
392 // Stack frame mapping. | 372 // Stack frame mapping. |
393 Timer T_genFrame; | |
394 Func->genFrame(); | 373 Func->genFrame(); |
395 if (Func->hasError()) | 374 if (Func->hasError()) |
396 return; | 375 return; |
397 T_genFrame.printElapsedUs(Context, "genFrame()"); | |
398 Func->dump("After stack frame mapping"); | 376 Func->dump("After stack frame mapping"); |
399 | 377 |
400 // Branch optimization. This needs to be done just before code | 378 // Branch optimization. This needs to be done just before code |
401 // emission. In particular, no transformations that insert or | 379 // emission. In particular, no transformations that insert or |
402 // reorder CfgNodes should be done after branch optimization. We go | 380 // reorder CfgNodes should be done after branch optimization. We go |
403 // ahead and do it before nop insertion to reduce the amount of work | 381 // ahead and do it before nop insertion to reduce the amount of work |
404 // needed for searching for opportunities. | 382 // needed for searching for opportunities. |
405 Func->doBranchOpt(); | 383 Func->doBranchOpt(); |
406 Func->dump("After branch optimization"); | 384 Func->dump("After branch optimization"); |
407 | 385 |
408 // Nop insertion | 386 // Nop insertion |
409 if (shouldDoNopInsertion()) { | 387 if (shouldDoNopInsertion()) { |
410 Func->doNopInsertion(); | 388 Func->doNopInsertion(); |
411 } | 389 } |
412 } | 390 } |
413 | 391 |
414 void TargetX8632::translateOm1() { | 392 void TargetX8632::translateOm1() { |
415 GlobalContext *Context = Func->getContext(); | 393 GlobalContext *Context = Func->getContext(); |
416 Timer T_placePhiLoads; | 394 static TimerIdT IDOm1 = GlobalContext::getTimerID("Om1"); |
| 395 TimerMarker T(IDOm1, Context); |
417 Func->placePhiLoads(); | 396 Func->placePhiLoads(); |
418 if (Func->hasError()) | 397 if (Func->hasError()) |
419 return; | 398 return; |
420 T_placePhiLoads.printElapsedUs(Context, "placePhiLoads()"); | |
421 Timer T_placePhiStores; | |
422 Func->placePhiStores(); | 399 Func->placePhiStores(); |
423 if (Func->hasError()) | 400 if (Func->hasError()) |
424 return; | 401 return; |
425 T_placePhiStores.printElapsedUs(Context, "placePhiStores()"); | |
426 Timer T_deletePhis; | |
427 Func->deletePhis(); | 402 Func->deletePhis(); |
428 if (Func->hasError()) | 403 if (Func->hasError()) |
429 return; | 404 return; |
430 T_deletePhis.printElapsedUs(Context, "deletePhis()"); | |
431 Func->dump("After Phi lowering"); | 405 Func->dump("After Phi lowering"); |
432 | 406 |
433 Timer T_argLowering; | |
434 Func->doArgLowering(); | 407 Func->doArgLowering(); |
435 T_argLowering.printElapsedUs(Context, "lowerArguments()"); | |
436 | 408 |
437 Timer T_genCode; | |
438 Func->genCode(); | 409 Func->genCode(); |
439 if (Func->hasError()) | 410 if (Func->hasError()) |
440 return; | 411 return; |
441 T_genCode.printElapsedUs(Context, "genCode()"); | |
442 Func->dump("After initial x8632 codegen"); | 412 Func->dump("After initial x8632 codegen"); |
443 | 413 |
444 Timer T_genFrame; | |
445 Func->genFrame(); | 414 Func->genFrame(); |
446 if (Func->hasError()) | 415 if (Func->hasError()) |
447 return; | 416 return; |
448 T_genFrame.printElapsedUs(Context, "genFrame()"); | |
449 Func->dump("After stack frame mapping"); | 417 Func->dump("After stack frame mapping"); |
450 | 418 |
451 // Nop insertion | 419 // Nop insertion |
452 if (shouldDoNopInsertion()) { | 420 if (shouldDoNopInsertion()) { |
453 Func->doNopInsertion(); | 421 Func->doNopInsertion(); |
454 } | 422 } |
455 } | 423 } |
456 | 424 |
457 bool TargetX8632::doBranchOpt(Inst *I, const CfgNode *NextNode) { | 425 bool TargetX8632::doBranchOpt(Inst *I, const CfgNode *NextNode) { |
458 if (InstX8632Br *Br = llvm::dyn_cast<InstX8632Br>(I)) { | 426 if (InstX8632Br *Br = llvm::dyn_cast<InstX8632Br>(I)) { |
(...skipping 4099 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4558 Str << "\t.align\t" << Align << "\n"; | 4526 Str << "\t.align\t" << Align << "\n"; |
4559 Str << MangledName << ":\n"; | 4527 Str << MangledName << ":\n"; |
4560 for (SizeT i = 0; i < Size; ++i) { | 4528 for (SizeT i = 0; i < Size; ++i) { |
4561 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; | 4529 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; |
4562 } | 4530 } |
4563 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4531 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
4564 } | 4532 } |
4565 } | 4533 } |
4566 | 4534 |
4567 } // end of namespace Ice | 4535 } // end of namespace Ice |
OLD | NEW |