| 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 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 Func->liveness(Liveness_Intervals); | 368 Func->liveness(Liveness_Intervals); |
| 369 if (Func->hasError()) | 369 if (Func->hasError()) |
| 370 return; | 370 return; |
| 371 // Validate the live range computations. The expensive validation | 371 // Validate the live range computations. The expensive validation |
| 372 // call is deliberately only made when assertions are enabled. | 372 // call is deliberately only made when assertions are enabled. |
| 373 assert(Func->validateLiveness()); | 373 assert(Func->validateLiveness()); |
| 374 // The post-codegen dump is done here, after liveness analysis and | 374 // The post-codegen dump is done here, after liveness analysis and |
| 375 // associated cleanup, to make the dump cleaner and more useful. | 375 // associated cleanup, to make the dump cleaner and more useful. |
| 376 Func->dump("After initial x8632 codegen"); | 376 Func->dump("After initial x8632 codegen"); |
| 377 Func->getVMetadata()->init(VMK_All); | 377 Func->getVMetadata()->init(VMK_All); |
| 378 regAlloc(); | 378 regAlloc(RAK_Global); |
| 379 if (Func->hasError()) | 379 if (Func->hasError()) |
| 380 return; | 380 return; |
| 381 Func->dump("After linear scan regalloc"); | 381 Func->dump("After linear scan regalloc"); |
| 382 | 382 |
| 383 if (Ctx->getFlags().PhiEdgeSplit) { | 383 if (Ctx->getFlags().PhiEdgeSplit) { |
| 384 Func->advancedPhiLowering(); | 384 Func->advancedPhiLowering(); |
| 385 Func->dump("After advanced Phi lowering"); | 385 Func->dump("After advanced Phi lowering"); |
| 386 } | 386 } |
| 387 | 387 |
| 388 // Stack frame mapping. | 388 // Stack frame mapping. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 return; | 422 return; |
| 423 Func->dump("After Phi lowering"); | 423 Func->dump("After Phi lowering"); |
| 424 | 424 |
| 425 Func->doArgLowering(); | 425 Func->doArgLowering(); |
| 426 | 426 |
| 427 Func->genCode(); | 427 Func->genCode(); |
| 428 if (Func->hasError()) | 428 if (Func->hasError()) |
| 429 return; | 429 return; |
| 430 Func->dump("After initial x8632 codegen"); | 430 Func->dump("After initial x8632 codegen"); |
| 431 | 431 |
| 432 regAlloc(RAK_InfOnly); |
| 433 if (Func->hasError()) |
| 434 return; |
| 435 Func->dump("After regalloc of infinite-weight variables"); |
| 436 |
| 432 Func->genFrame(); | 437 Func->genFrame(); |
| 433 if (Func->hasError()) | 438 if (Func->hasError()) |
| 434 return; | 439 return; |
| 435 Func->dump("After stack frame mapping"); | 440 Func->dump("After stack frame mapping"); |
| 436 | 441 |
| 437 // Nop insertion | 442 // Nop insertion |
| 438 if (shouldDoNopInsertion()) { | 443 if (shouldDoNopInsertion()) { |
| 439 Func->doNopInsertion(); | 444 Func->doNopInsertion(); |
| 440 } | 445 } |
| 441 } | 446 } |
| (...skipping 4063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4505 assert(Type != IceType_i64); | 4510 assert(Type != IceType_i64); |
| 4506 Variable *Reg = Func->makeVariable(Type); | 4511 Variable *Reg = Func->makeVariable(Type); |
| 4507 if (RegNum == Variable::NoRegister) | 4512 if (RegNum == Variable::NoRegister) |
| 4508 Reg->setWeightInfinite(); | 4513 Reg->setWeightInfinite(); |
| 4509 else | 4514 else |
| 4510 Reg->setRegNum(RegNum); | 4515 Reg->setRegNum(RegNum); |
| 4511 return Reg; | 4516 return Reg; |
| 4512 } | 4517 } |
| 4513 | 4518 |
| 4514 void TargetX8632::postLower() { | 4519 void TargetX8632::postLower() { |
| 4515 if (Ctx->getOptLevel() != Opt_m1) { | 4520 if (Ctx->getOptLevel() == Opt_m1) |
| 4516 // Find two-address non-SSA instructions where Dest==Src0, and set | |
| 4517 // the DestNonKillable flag to keep liveness analysis consistent. | |
| 4518 for (auto Inst = Context.begin(), E = Context.end(); Inst != E; ++Inst) { | |
| 4519 if (Inst->isDeleted()) | |
| 4520 continue; | |
| 4521 if (Variable *Dest = Inst->getDest()) { | |
| 4522 // TODO(stichnot): We may need to consider all source | |
| 4523 // operands, not just the first one, if using 3-address | |
| 4524 // instructions. | |
| 4525 if (Inst->getSrcSize() > 0 && Inst->getSrc(0) == Dest) | |
| 4526 Inst->setDestNonKillable(); | |
| 4527 } | |
| 4528 } | |
| 4529 return; | 4521 return; |
| 4530 } | 4522 // Find two-address non-SSA instructions where Dest==Src0, and set |
| 4531 // TODO: Avoid recomputing WhiteList every instruction. | 4523 // the DestNonKillable flag to keep liveness analysis consistent. |
| 4532 RegSetMask RegInclude = RegSet_All; | |
| 4533 RegSetMask RegExclude = RegSet_StackPointer; | |
| 4534 if (hasFramePointer()) | |
| 4535 RegExclude |= RegSet_FramePointer; | |
| 4536 llvm::SmallBitVector WhiteList = getRegisterSet(RegInclude, RegExclude); | |
| 4537 // Make one pass to black-list pre-colored registers. TODO: If | |
| 4538 // there was some prior register allocation pass that made register | |
| 4539 // assignments, those registers need to be black-listed here as | |
| 4540 // well. | |
| 4541 llvm::DenseMap<const Variable *, const Inst *> LastUses; | |
| 4542 // The first pass also keeps track of which instruction is the last | |
| 4543 // use for each infinite-weight variable. After the last use, the | |
| 4544 // variable is released to the free list. | |
| 4545 for (auto Inst = Context.begin(), E = Context.end(); Inst != E; ++Inst) { | 4524 for (auto Inst = Context.begin(), E = Context.end(); Inst != E; ++Inst) { |
| 4546 if (Inst->isDeleted()) | 4525 if (Inst->isDeleted()) |
| 4547 continue; | 4526 continue; |
| 4548 // Don't consider a FakeKill instruction, because (currently) it | 4527 if (Variable *Dest = Inst->getDest()) { |
| 4549 // is only used to kill all scratch registers at a call site, and | 4528 // TODO(stichnot): We may need to consider all source |
| 4550 // we don't want to black-list all scratch registers during the | 4529 // operands, not just the first one, if using 3-address |
| 4551 // call lowering. This could become a problem since it relies on | 4530 // instructions. |
| 4552 // the lowering sequence not keeping any infinite-weight variables | 4531 if (Inst->getSrcSize() > 0 && Inst->getSrc(0) == Dest) |
| 4553 // live across a call. TODO(stichnot): Consider replacing this | 4532 Inst->setDestNonKillable(); |
| 4554 // whole postLower() implementation with a robust local register | |
| 4555 // allocator, for example compute live ranges only for pre-colored | |
| 4556 // and infinite-weight variables and run the existing linear-scan | |
| 4557 // allocator. | |
| 4558 assert(!llvm::isa<InstFakeKill>(Inst) || Inst->getSrcSize() == 0); | |
| 4559 for (SizeT SrcNum = 0; SrcNum < Inst->getSrcSize(); ++SrcNum) { | |
| 4560 Operand *Src = Inst->getSrc(SrcNum); | |
| 4561 SizeT NumVars = Src->getNumVars(); | |
| 4562 for (SizeT J = 0; J < NumVars; ++J) { | |
| 4563 const Variable *Var = Src->getVar(J); | |
| 4564 // Track last uses of all variables, regardless of whether | |
| 4565 // they are pre-colored or infinite-weight. | |
| 4566 LastUses[Var] = Inst; | |
| 4567 if (!Var->hasReg()) | |
| 4568 continue; | |
| 4569 WhiteList[Var->getRegNum()] = false; | |
| 4570 } | |
| 4571 } | 4533 } |
| 4572 } | 4534 } |
| 4573 // The second pass colors infinite-weight variables. | |
| 4574 llvm::SmallBitVector AvailableRegisters = WhiteList; | |
| 4575 llvm::SmallBitVector FreedRegisters(WhiteList.size()); | |
| 4576 for (auto Inst = Context.begin(), E = Context.end(); Inst != E; ++Inst) { | |
| 4577 FreedRegisters.reset(); | |
| 4578 if (Inst->isDeleted()) | |
| 4579 continue; | |
| 4580 // Iterate over all variables referenced in the instruction, | |
| 4581 // including the Dest variable (if any). If the variable is | |
| 4582 // marked as infinite-weight, find it a register. If this | |
| 4583 // instruction is the last use of the variable in the lowered | |
| 4584 // sequence, release the register to the free list after this | |
| 4585 // instruction is completely processed. Note that the first pass | |
| 4586 // ignores the Dest operand, under the assumption that a | |
| 4587 // pre-colored Dest will appear as a source operand in some | |
| 4588 // subsequent instruction in the lowered sequence. | |
| 4589 Variable *Dest = Inst->getDest(); | |
| 4590 SizeT NumSrcs = Inst->getSrcSize(); | |
| 4591 if (Dest) | |
| 4592 ++NumSrcs; | |
| 4593 if (NumSrcs == 0) | |
| 4594 continue; | |
| 4595 OperandList Srcs(NumSrcs); | |
| 4596 for (SizeT i = 0; i < Inst->getSrcSize(); ++i) | |
| 4597 Srcs[i] = Inst->getSrc(i); | |
| 4598 if (Dest) | |
| 4599 Srcs[NumSrcs - 1] = Dest; | |
| 4600 for (SizeT SrcNum = 0; SrcNum < NumSrcs; ++SrcNum) { | |
| 4601 Operand *Src = Srcs[SrcNum]; | |
| 4602 SizeT NumVars = Src->getNumVars(); | |
| 4603 for (SizeT J = 0; J < NumVars; ++J) { | |
| 4604 Variable *Var = Src->getVar(J); | |
| 4605 if (!Var->hasReg() && Var->getWeight().isInf()) { | |
| 4606 llvm::SmallBitVector AvailableTypedRegisters = | |
| 4607 AvailableRegisters & getRegisterSetForType(Var->getType()); | |
| 4608 assert(AvailableTypedRegisters.any()); | |
| 4609 int32_t RegNum = AvailableTypedRegisters.find_first(); | |
| 4610 Var->setRegNum(RegNum); | |
| 4611 AvailableRegisters[RegNum] = false; | |
| 4612 } | |
| 4613 if (Var->hasReg()) { | |
| 4614 int32_t RegNum = Var->getRegNum(); | |
| 4615 assert(!AvailableRegisters[RegNum]); | |
| 4616 if (LastUses[Var] == Inst) { | |
| 4617 if (WhiteList[RegNum]) | |
| 4618 FreedRegisters[RegNum] = true; | |
| 4619 } | |
| 4620 } | |
| 4621 } | |
| 4622 } | |
| 4623 AvailableRegisters |= FreedRegisters; | |
| 4624 } | |
| 4625 } | 4535 } |
| 4626 | 4536 |
| 4627 template <> void ConstantInteger32::emit(GlobalContext *Ctx) const { | 4537 template <> void ConstantInteger32::emit(GlobalContext *Ctx) const { |
| 4628 Ostream &Str = Ctx->getStrEmit(); | 4538 Ostream &Str = Ctx->getStrEmit(); |
| 4629 Str << "$" << (int32_t)getValue(); | 4539 Str << "$" << (int32_t)getValue(); |
| 4630 } | 4540 } |
| 4631 | 4541 |
| 4632 template <> void ConstantInteger64::emit(GlobalContext *) const { | 4542 template <> void ConstantInteger64::emit(GlobalContext *) const { |
| 4633 llvm_unreachable("Not expecting to emit 64-bit integers"); | 4543 llvm_unreachable("Not expecting to emit 64-bit integers"); |
| 4634 } | 4544 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4737 } else if (IsConstant || IsExternal) | 4647 } else if (IsConstant || IsExternal) |
| 4738 Str << "\t.zero\t" << Size << "\n"; | 4648 Str << "\t.zero\t" << Size << "\n"; |
| 4739 // Size is part of .comm. | 4649 // Size is part of .comm. |
| 4740 | 4650 |
| 4741 if (IsConstant || HasNonzeroInitializer || IsExternal) | 4651 if (IsConstant || HasNonzeroInitializer || IsExternal) |
| 4742 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4652 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
| 4743 // Size is part of .comm. | 4653 // Size is part of .comm. |
| 4744 } | 4654 } |
| 4745 | 4655 |
| 4746 } // end of namespace Ice | 4656 } // end of namespace Ice |
| OLD | NEW |