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 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
309 TypeToRegisterSet[IceType_v16i1] = VectorRegisters; | 309 TypeToRegisterSet[IceType_v16i1] = VectorRegisters; |
310 TypeToRegisterSet[IceType_v16i8] = VectorRegisters; | 310 TypeToRegisterSet[IceType_v16i8] = VectorRegisters; |
311 TypeToRegisterSet[IceType_v8i16] = VectorRegisters; | 311 TypeToRegisterSet[IceType_v8i16] = VectorRegisters; |
312 TypeToRegisterSet[IceType_v4i32] = VectorRegisters; | 312 TypeToRegisterSet[IceType_v4i32] = VectorRegisters; |
313 TypeToRegisterSet[IceType_v4f32] = VectorRegisters; | 313 TypeToRegisterSet[IceType_v4f32] = VectorRegisters; |
314 } | 314 } |
315 | 315 |
316 void TargetX8632::translateO2() { | 316 void TargetX8632::translateO2() { |
317 TimerMarker T(TimerStack::TT_O2, Func); | 317 TimerMarker T(TimerStack::TT_O2, Func); |
318 | 318 |
319 initFakeKilledScratchRegisters(); | |
320 | |
319 if (!Ctx->getFlags().PhiEdgeSplit) { | 321 if (!Ctx->getFlags().PhiEdgeSplit) { |
320 // Lower Phi instructions. | 322 // Lower Phi instructions. |
321 Func->placePhiLoads(); | 323 Func->placePhiLoads(); |
322 if (Func->hasError()) | 324 if (Func->hasError()) |
323 return; | 325 return; |
324 Func->placePhiStores(); | 326 Func->placePhiStores(); |
325 if (Func->hasError()) | 327 if (Func->hasError()) |
326 return; | 328 return; |
327 Func->deletePhis(); | 329 Func->deletePhis(); |
328 if (Func->hasError()) | 330 if (Func->hasError()) |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
404 Func->dump("After branch optimization"); | 406 Func->dump("After branch optimization"); |
405 | 407 |
406 // Nop insertion | 408 // Nop insertion |
407 if (shouldDoNopInsertion()) { | 409 if (shouldDoNopInsertion()) { |
408 Func->doNopInsertion(); | 410 Func->doNopInsertion(); |
409 } | 411 } |
410 } | 412 } |
411 | 413 |
412 void TargetX8632::translateOm1() { | 414 void TargetX8632::translateOm1() { |
413 TimerMarker T(TimerStack::TT_Om1, Func); | 415 TimerMarker T(TimerStack::TT_Om1, Func); |
416 | |
417 initFakeKilledScratchRegisters(); | |
418 | |
414 Func->placePhiLoads(); | 419 Func->placePhiLoads(); |
415 if (Func->hasError()) | 420 if (Func->hasError()) |
416 return; | 421 return; |
417 Func->placePhiStores(); | 422 Func->placePhiStores(); |
418 if (Func->hasError()) | 423 if (Func->hasError()) |
419 return; | 424 return; |
420 Func->deletePhis(); | 425 Func->deletePhis(); |
421 if (Func->hasError()) | 426 if (Func->hasError()) |
422 return; | 427 return; |
423 Func->dump("After Phi lowering"); | 428 Func->dump("After Phi lowering"); |
(...skipping 1438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1862 Context.insert(InstFakeDef::create(Func, ReturnRegHi)); | 1867 Context.insert(InstFakeDef::create(Func, ReturnRegHi)); |
1863 | 1868 |
1864 // Add the appropriate offset to esp. The call instruction takes care | 1869 // Add the appropriate offset to esp. The call instruction takes care |
1865 // of resetting the stack offset during emission. | 1870 // of resetting the stack offset during emission. |
1866 if (ParameterAreaSizeBytes) { | 1871 if (ParameterAreaSizeBytes) { |
1867 Variable *esp = Func->getTarget()->getPhysicalRegister(RegX8632::Reg_esp); | 1872 Variable *esp = Func->getTarget()->getPhysicalRegister(RegX8632::Reg_esp); |
1868 _add(esp, Ctx->getConstantInt32(IceType_i32, ParameterAreaSizeBytes)); | 1873 _add(esp, Ctx->getConstantInt32(IceType_i32, ParameterAreaSizeBytes)); |
1869 } | 1874 } |
1870 | 1875 |
1871 // Insert a register-kill pseudo instruction. | 1876 // Insert a register-kill pseudo instruction. |
1872 VarList KilledRegs; | 1877 assert(!FakeKilledScratchRegisters.empty()); |
1873 for (SizeT i = 0; i < ScratchRegs.size(); ++i) { | 1878 Context.insert( |
1874 if (ScratchRegs[i]) | 1879 InstFakeKill::create(Func, FakeKilledScratchRegisters, NewCall)); |
1875 KilledRegs.push_back(Func->getTarget()->getPhysicalRegister(i)); | |
1876 } | |
1877 Context.insert(InstFakeKill::create(Func, KilledRegs, NewCall)); | |
1878 | 1880 |
1879 // Generate a FakeUse to keep the call live if necessary. | 1881 // Generate a FakeUse to keep the call live if necessary. |
1880 if (Instr->hasSideEffects() && ReturnReg) { | 1882 if (Instr->hasSideEffects() && ReturnReg) { |
1881 Inst *FakeUse = InstFakeUse::create(Func, ReturnReg); | 1883 Inst *FakeUse = InstFakeUse::create(Func, ReturnReg); |
1882 Context.insert(FakeUse); | 1884 Context.insert(FakeUse); |
1883 } | 1885 } |
1884 | 1886 |
1885 if (!Dest) | 1887 if (!Dest) |
1886 return; | 1888 return; |
1887 | 1889 |
(...skipping 2644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4532 continue; | 4534 continue; |
4533 // Don't consider a FakeKill instruction, because (currently) it | 4535 // Don't consider a FakeKill instruction, because (currently) it |
4534 // is only used to kill all scratch registers at a call site, and | 4536 // is only used to kill all scratch registers at a call site, and |
4535 // we don't want to black-list all scratch registers during the | 4537 // we don't want to black-list all scratch registers during the |
4536 // call lowering. This could become a problem since it relies on | 4538 // call lowering. This could become a problem since it relies on |
4537 // the lowering sequence not keeping any infinite-weight variables | 4539 // the lowering sequence not keeping any infinite-weight variables |
4538 // live across a call. TODO(stichnot): Consider replacing this | 4540 // live across a call. TODO(stichnot): Consider replacing this |
4539 // whole postLower() implementation with a robust local register | 4541 // whole postLower() implementation with a robust local register |
4540 // allocator, for example compute live ranges only for pre-colored | 4542 // allocator, for example compute live ranges only for pre-colored |
4541 // and infinite-weight variables and run the existing linear-scan | 4543 // and infinite-weight variables and run the existing linear-scan |
4542 // allocator. | 4544 // allocator. |
jvoung (off chromium)
2014/11/04 16:47:07
Maybe this can be an assert that isa<InstFakeKill>
Jim Stichnoth
2014/11/04 17:10:39
Done.
| |
4543 if (llvm::isa<InstFakeKill>(Inst)) | |
4544 continue; | |
4545 for (SizeT SrcNum = 0; SrcNum < Inst->getSrcSize(); ++SrcNum) { | 4545 for (SizeT SrcNum = 0; SrcNum < Inst->getSrcSize(); ++SrcNum) { |
4546 Operand *Src = Inst->getSrc(SrcNum); | 4546 Operand *Src = Inst->getSrc(SrcNum); |
4547 SizeT NumVars = Src->getNumVars(); | 4547 SizeT NumVars = Src->getNumVars(); |
4548 for (SizeT J = 0; J < NumVars; ++J) { | 4548 for (SizeT J = 0; J < NumVars; ++J) { |
4549 const Variable *Var = Src->getVar(J); | 4549 const Variable *Var = Src->getVar(J); |
4550 // Track last uses of all variables, regardless of whether | 4550 // Track last uses of all variables, regardless of whether |
4551 // they are pre-colored or infinite-weight. | 4551 // they are pre-colored or infinite-weight. |
4552 LastUses[Var] = Inst; | 4552 LastUses[Var] = Inst; |
4553 if (!Var->hasReg()) | 4553 if (!Var->hasReg()) |
4554 continue; | 4554 continue; |
4555 WhiteList[Var->getRegNum()] = false; | 4555 WhiteList[Var->getRegNum()] = false; |
4556 } | 4556 } |
4557 } | 4557 } |
4558 } | 4558 } |
4559 // The second pass colors infinite-weight variables. | 4559 // The second pass colors infinite-weight variables. |
4560 llvm::SmallBitVector AvailableRegisters = WhiteList; | 4560 llvm::SmallBitVector AvailableRegisters = WhiteList; |
4561 llvm::SmallBitVector FreedRegisters(WhiteList.size()); | 4561 llvm::SmallBitVector FreedRegisters(WhiteList.size()); |
4562 for (Inst *Inst : Context) { | 4562 for (Inst *Inst : Context) { |
4563 FreedRegisters.reset(); | 4563 FreedRegisters.reset(); |
4564 if (Inst->isDeleted()) | 4564 if (Inst->isDeleted()) |
4565 continue; | 4565 continue; |
4566 // Skip FakeKill instructions like above. | |
4567 if (llvm::isa<InstFakeKill>(Inst)) | |
4568 continue; | |
4569 // Iterate over all variables referenced in the instruction, | 4566 // Iterate over all variables referenced in the instruction, |
4570 // including the Dest variable (if any). If the variable is | 4567 // including the Dest variable (if any). If the variable is |
4571 // marked as infinite-weight, find it a register. If this | 4568 // marked as infinite-weight, find it a register. If this |
4572 // instruction is the last use of the variable in the lowered | 4569 // instruction is the last use of the variable in the lowered |
4573 // sequence, release the register to the free list after this | 4570 // sequence, release the register to the free list after this |
4574 // instruction is completely processed. Note that the first pass | 4571 // instruction is completely processed. Note that the first pass |
4575 // ignores the Dest operand, under the assumption that a | 4572 // ignores the Dest operand, under the assumption that a |
4576 // pre-colored Dest will appear as a source operand in some | 4573 // pre-colored Dest will appear as a source operand in some |
4577 // subsequent instruction in the lowered sequence. | 4574 // subsequent instruction in the lowered sequence. |
4578 Variable *Dest = Inst->getDest(); | 4575 Variable *Dest = Inst->getDest(); |
4579 SizeT NumSrcs = Inst->getSrcSize(); | 4576 SizeT NumSrcs = Inst->getSrcSize(); |
4580 if (Dest) | 4577 if (Dest) |
4581 ++NumSrcs; | 4578 ++NumSrcs; |
4579 if (NumSrcs == 0) | |
4580 continue; | |
4582 OperandList Srcs(NumSrcs); | 4581 OperandList Srcs(NumSrcs); |
4583 for (SizeT i = 0; i < Inst->getSrcSize(); ++i) | 4582 for (SizeT i = 0; i < Inst->getSrcSize(); ++i) |
4584 Srcs[i] = Inst->getSrc(i); | 4583 Srcs[i] = Inst->getSrc(i); |
4585 if (Dest) | 4584 if (Dest) |
4586 Srcs[NumSrcs - 1] = Dest; | 4585 Srcs[NumSrcs - 1] = Dest; |
4587 for (SizeT SrcNum = 0; SrcNum < NumSrcs; ++SrcNum) { | 4586 for (SizeT SrcNum = 0; SrcNum < NumSrcs; ++SrcNum) { |
4588 Operand *Src = Srcs[SrcNum]; | 4587 Operand *Src = Srcs[SrcNum]; |
4589 SizeT NumVars = Src->getNumVars(); | 4588 SizeT NumVars = Src->getNumVars(); |
4590 for (SizeT J = 0; J < NumVars; ++J) { | 4589 for (SizeT J = 0; J < NumVars; ++J) { |
4591 Variable *Var = Src->getVar(J); | 4590 Variable *Var = Src->getVar(J); |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4724 } else if (IsConstant || IsExternal) | 4723 } else if (IsConstant || IsExternal) |
4725 Str << "\t.zero\t" << Size << "\n"; | 4724 Str << "\t.zero\t" << Size << "\n"; |
4726 // Size is part of .comm. | 4725 // Size is part of .comm. |
4727 | 4726 |
4728 if (IsConstant || HasNonzeroInitializer || IsExternal) | 4727 if (IsConstant || HasNonzeroInitializer || IsExternal) |
4729 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4728 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
4730 // Size is part of .comm. | 4729 // Size is part of .comm. |
4731 } | 4730 } |
4732 | 4731 |
4733 } // end of namespace Ice | 4732 } // end of namespace Ice |
OLD | NEW |