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 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 } | 538 } |
539 } | 539 } |
540 | 540 |
541 void TargetX8632::sortByAlignment(VarList &Dest, const VarList &Source) const { | 541 void TargetX8632::sortByAlignment(VarList &Dest, const VarList &Source) const { |
542 // Sort the variables into buckets according to the log of their width | 542 // Sort the variables into buckets according to the log of their width |
543 // in bytes. | 543 // in bytes. |
544 const SizeT NumBuckets = | 544 const SizeT NumBuckets = |
545 X86_LOG2_OF_MAX_STACK_SLOT_SIZE - X86_LOG2_OF_MIN_STACK_SLOT_SIZE + 1; | 545 X86_LOG2_OF_MAX_STACK_SLOT_SIZE - X86_LOG2_OF_MIN_STACK_SLOT_SIZE + 1; |
546 VarList Buckets[NumBuckets]; | 546 VarList Buckets[NumBuckets]; |
547 | 547 |
548 for (VarList::const_iterator I = Source.begin(), E = Source.end(); I != E; | 548 for (auto &Var : Source) { |
549 ++I) { | |
550 Variable *Var = *I; | |
551 uint32_t NaturalAlignment = typeWidthInBytesOnStack(Var->getType()); | 549 uint32_t NaturalAlignment = typeWidthInBytesOnStack(Var->getType()); |
552 SizeT LogNaturalAlignment = llvm::findFirstSet(NaturalAlignment); | 550 SizeT LogNaturalAlignment = llvm::findFirstSet(NaturalAlignment); |
553 assert(LogNaturalAlignment >= X86_LOG2_OF_MIN_STACK_SLOT_SIZE); | 551 assert(LogNaturalAlignment >= X86_LOG2_OF_MIN_STACK_SLOT_SIZE); |
554 assert(LogNaturalAlignment <= X86_LOG2_OF_MAX_STACK_SLOT_SIZE); | 552 assert(LogNaturalAlignment <= X86_LOG2_OF_MAX_STACK_SLOT_SIZE); |
555 SizeT BucketIndex = LogNaturalAlignment - X86_LOG2_OF_MIN_STACK_SLOT_SIZE; | 553 SizeT BucketIndex = LogNaturalAlignment - X86_LOG2_OF_MIN_STACK_SLOT_SIZE; |
556 Buckets[BucketIndex].push_back(Var); | 554 Buckets[BucketIndex].push_back(Var); |
557 } | 555 } |
558 | 556 |
559 for (SizeT I = 0, E = NumBuckets; I < E; ++I) { | 557 for (SizeT I = 0, E = NumBuckets; I < E; ++I) { |
560 VarList &List = Buckets[NumBuckets - I - 1]; | 558 VarList &List = Buckets[NumBuckets - I - 1]; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 const VarList &Variables = Func->getVariables(); | 679 const VarList &Variables = Func->getVariables(); |
682 const VarList &Args = Func->getArgs(); | 680 const VarList &Args = Func->getArgs(); |
683 VarList SpilledVariables, SortedSpilledVariables, VariablesLinkedToSpillSlots; | 681 VarList SpilledVariables, SortedSpilledVariables, VariablesLinkedToSpillSlots; |
684 | 682 |
685 // If there is a separate locals area, this specifies the alignment | 683 // If there is a separate locals area, this specifies the alignment |
686 // for it. | 684 // for it. |
687 uint32_t LocalsSlotsAlignmentBytes = 0; | 685 uint32_t LocalsSlotsAlignmentBytes = 0; |
688 // The entire spill locations area gets aligned to largest natural | 686 // The entire spill locations area gets aligned to largest natural |
689 // alignment of the variables that have a spill slot. | 687 // alignment of the variables that have a spill slot. |
690 uint32_t SpillAreaAlignmentBytes = 0; | 688 uint32_t SpillAreaAlignmentBytes = 0; |
691 for (VarList::const_iterator I = Variables.begin(), E = Variables.end(); | 689 for (auto &Var : Variables) { |
692 I != E; ++I) { | |
693 Variable *Var = *I; | |
694 if (Var->hasReg()) { | 690 if (Var->hasReg()) { |
695 RegsUsed[Var->getRegNum()] = true; | 691 RegsUsed[Var->getRegNum()] = true; |
696 continue; | 692 continue; |
697 } | 693 } |
698 // An argument either does not need a stack slot (if passed in a | 694 // An argument either does not need a stack slot (if passed in a |
699 // register) or already has one (if passed on the stack). | 695 // register) or already has one (if passed on the stack). |
700 if (Var->getIsArg()) | 696 if (Var->getIsArg()) |
701 continue; | 697 continue; |
702 // An unreferenced variable doesn't need a stack slot. | 698 // An unreferenced variable doesn't need a stack slot. |
703 if (ComputedLiveRanges && Var->getLiveRange().isEmpty()) | 699 if (ComputedLiveRanges && Var->getLiveRange().isEmpty()) |
704 continue; | 700 continue; |
705 // A spill slot linked to a variable with a stack slot should reuse | 701 // A spill slot linked to a variable with a stack slot should reuse |
706 // that stack slot. | 702 // that stack slot. |
707 if (SpillVariable *SpillVar = llvm::dyn_cast<SpillVariable>(Var)) { | 703 if (SpillVariable *SpillVar = llvm::dyn_cast<SpillVariable>(Var)) { |
708 assert(Var->getWeight() == RegWeight::Zero); | 704 assert(Var->getWeight() == RegWeight::Zero); |
709 if (!SpillVar->getLinkedTo()->hasReg()) { | 705 if (!SpillVar->getLinkedTo()->hasReg()) { |
710 VariablesLinkedToSpillSlots.push_back(Var); | 706 VariablesLinkedToSpillSlots.push_back(Var); |
711 continue; | 707 continue; |
712 } | 708 } |
713 } | 709 } |
714 SpilledVariables.push_back(Var); | 710 SpilledVariables.push_back(Var); |
715 } | 711 } |
716 | 712 |
717 SortedSpilledVariables.reserve(SpilledVariables.size()); | 713 SortedSpilledVariables.reserve(SpilledVariables.size()); |
718 sortByAlignment(SortedSpilledVariables, SpilledVariables); | 714 sortByAlignment(SortedSpilledVariables, SpilledVariables); |
719 for (VarList::const_iterator I = SortedSpilledVariables.begin(), | 715 for (auto &Var : SortedSpilledVariables) { |
720 E = SortedSpilledVariables.end(); | |
721 I != E; ++I) { | |
722 Variable *Var = *I; | |
723 size_t Increment = typeWidthInBytesOnStack(Var->getType()); | 716 size_t Increment = typeWidthInBytesOnStack(Var->getType()); |
724 if (!SpillAreaAlignmentBytes) | 717 if (!SpillAreaAlignmentBytes) |
725 SpillAreaAlignmentBytes = Increment; | 718 SpillAreaAlignmentBytes = Increment; |
726 if (SimpleCoalescing && VMetadata->isTracked(Var)) { | 719 if (SimpleCoalescing && VMetadata->isTracked(Var)) { |
727 if (VMetadata->isMultiBlock(Var)) { | 720 if (VMetadata->isMultiBlock(Var)) { |
728 GlobalsSize += Increment; | 721 GlobalsSize += Increment; |
729 } else { | 722 } else { |
730 SizeT NodeIndex = VMetadata->getLocalUseNode(Var)->getIndex(); | 723 SizeT NodeIndex = VMetadata->getLocalUseNode(Var)->getIndex(); |
731 LocalsSize[NodeIndex] += Increment; | 724 LocalsSize[NodeIndex] += Increment; |
732 if (LocalsSize[NodeIndex] > SpillAreaSizeBytes) | 725 if (LocalsSize[NodeIndex] > SpillAreaSizeBytes) |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
820 ++NumXmmArgs; | 813 ++NumXmmArgs; |
821 continue; | 814 continue; |
822 } | 815 } |
823 finishArgumentLowering(Arg, FramePtr, BasicFrameOffset, InArgsSizeBytes); | 816 finishArgumentLowering(Arg, FramePtr, BasicFrameOffset, InArgsSizeBytes); |
824 } | 817 } |
825 | 818 |
826 // Fill in stack offsets for locals. | 819 // Fill in stack offsets for locals. |
827 size_t GlobalsSpaceUsed = SpillAreaPaddingBytes; | 820 size_t GlobalsSpaceUsed = SpillAreaPaddingBytes; |
828 LocalsSize.assign(LocalsSize.size(), 0); | 821 LocalsSize.assign(LocalsSize.size(), 0); |
829 size_t NextStackOffset = GlobalsSpaceUsed; | 822 size_t NextStackOffset = GlobalsSpaceUsed; |
830 for (VarList::const_iterator I = SortedSpilledVariables.begin(), | 823 for (auto &Var : SortedSpilledVariables) { |
831 E = SortedSpilledVariables.end(); | |
832 I != E; ++I) { | |
833 Variable *Var = *I; | |
834 size_t Increment = typeWidthInBytesOnStack(Var->getType()); | 824 size_t Increment = typeWidthInBytesOnStack(Var->getType()); |
835 if (SimpleCoalescing && VMetadata->isTracked(Var)) { | 825 if (SimpleCoalescing && VMetadata->isTracked(Var)) { |
836 if (VMetadata->isMultiBlock(Var)) { | 826 if (VMetadata->isMultiBlock(Var)) { |
837 GlobalsSpaceUsed += Increment; | 827 GlobalsSpaceUsed += Increment; |
838 NextStackOffset = GlobalsSpaceUsed; | 828 NextStackOffset = GlobalsSpaceUsed; |
839 } else { | 829 } else { |
840 SizeT NodeIndex = VMetadata->getLocalUseNode(Var)->getIndex(); | 830 SizeT NodeIndex = VMetadata->getLocalUseNode(Var)->getIndex(); |
841 LocalsSize[NodeIndex] += Increment; | 831 LocalsSize[NodeIndex] += Increment; |
842 NextStackOffset = SpillAreaPaddingBytes + | 832 NextStackOffset = SpillAreaPaddingBytes + |
843 GlobalsAndSubsequentPaddingSize + | 833 GlobalsAndSubsequentPaddingSize + |
844 LocalsSize[NodeIndex]; | 834 LocalsSize[NodeIndex]; |
845 } | 835 } |
846 } else { | 836 } else { |
847 NextStackOffset += Increment; | 837 NextStackOffset += Increment; |
848 } | 838 } |
849 if (IsEbpBasedFrame) | 839 if (IsEbpBasedFrame) |
850 Var->setStackOffset(-NextStackOffset); | 840 Var->setStackOffset(-NextStackOffset); |
851 else | 841 else |
852 Var->setStackOffset(SpillAreaSizeBytes - NextStackOffset); | 842 Var->setStackOffset(SpillAreaSizeBytes - NextStackOffset); |
853 } | 843 } |
854 this->FrameSizeLocals = NextStackOffset - SpillAreaPaddingBytes; | 844 this->FrameSizeLocals = NextStackOffset - SpillAreaPaddingBytes; |
855 this->HasComputedFrame = true; | 845 this->HasComputedFrame = true; |
856 | 846 |
857 // Assign stack offsets to variables that have been linked to spilled | 847 // Assign stack offsets to variables that have been linked to spilled |
858 // variables. | 848 // variables. |
859 for (VarList::const_iterator I = VariablesLinkedToSpillSlots.begin(), | 849 for (auto &Var : VariablesLinkedToSpillSlots) { |
860 E = VariablesLinkedToSpillSlots.end(); | |
861 I != E; ++I) { | |
862 Variable *Var = *I; | |
863 Variable *Linked = (llvm::cast<SpillVariable>(Var))->getLinkedTo(); | 850 Variable *Linked = (llvm::cast<SpillVariable>(Var))->getLinkedTo(); |
864 Var->setStackOffset(Linked->getStackOffset()); | 851 Var->setStackOffset(Linked->getStackOffset()); |
865 } | 852 } |
866 | 853 |
867 if (Func->getContext()->isVerbose(IceV_Frame)) { | 854 if (Func->getContext()->isVerbose(IceV_Frame)) { |
868 Ostream &Str = Func->getContext()->getStrDump(); | 855 Ostream &Str = Func->getContext()->getStrDump(); |
869 | 856 |
870 Str << "Stack layout:\n"; | 857 Str << "Stack layout:\n"; |
871 uint32_t EspAdjustmentPaddingSize = | 858 uint32_t EspAdjustmentPaddingSize = |
872 SpillAreaSizeBytes - LocalsSpillAreaSize - | 859 SpillAreaSizeBytes - LocalsSpillAreaSize - |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 | 949 |
963 template <typename T> void TargetX8632::emitConstantPool() const { | 950 template <typename T> void TargetX8632::emitConstantPool() const { |
964 Ostream &Str = Ctx->getStrEmit(); | 951 Ostream &Str = Ctx->getStrEmit(); |
965 Type Ty = T::Ty; | 952 Type Ty = T::Ty; |
966 SizeT Align = typeAlignInBytes(Ty); | 953 SizeT Align = typeAlignInBytes(Ty); |
967 ConstantList Pool = Ctx->getConstantPool(Ty); | 954 ConstantList Pool = Ctx->getConstantPool(Ty); |
968 | 955 |
969 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align | 956 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align |
970 << "\n"; | 957 << "\n"; |
971 Str << "\t.align\t" << Align << "\n"; | 958 Str << "\t.align\t" << Align << "\n"; |
972 for (ConstantList::const_iterator I = Pool.begin(), E = Pool.end(); I != E; | 959 for (auto &I : Pool) { |
973 ++I) { | 960 typename T::IceType *Const = llvm::cast<typename T::IceType>(I); |
974 typename T::IceType *Const = llvm::cast<typename T::IceType>(*I); | |
975 typename T::PrimitiveFpType Value = Const->getValue(); | 961 typename T::PrimitiveFpType Value = Const->getValue(); |
976 // Use memcpy() to copy bits from Value into RawValue in a way | 962 // Use memcpy() to copy bits from Value into RawValue in a way |
977 // that avoids breaking strict-aliasing rules. | 963 // that avoids breaking strict-aliasing rules. |
978 typename T::PrimitiveIntType RawValue; | 964 typename T::PrimitiveIntType RawValue; |
979 memcpy(&RawValue, &Value, sizeof(Value)); | 965 memcpy(&RawValue, &Value, sizeof(Value)); |
980 char buf[30]; | 966 char buf[30]; |
981 int CharsPrinted = | 967 int CharsPrinted = |
982 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); | 968 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); |
983 assert(CharsPrinted >= 0 && | 969 assert(CharsPrinted >= 0 && |
984 (size_t)CharsPrinted < llvm::array_lengthof(buf)); | 970 (size_t)CharsPrinted < llvm::array_lengthof(buf)); |
(...skipping 3331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4316 RegExclude |= RegSet_FramePointer; | 4302 RegExclude |= RegSet_FramePointer; |
4317 llvm::SmallBitVector WhiteList = getRegisterSet(RegInclude, RegExclude); | 4303 llvm::SmallBitVector WhiteList = getRegisterSet(RegInclude, RegExclude); |
4318 // Make one pass to black-list pre-colored registers. TODO: If | 4304 // Make one pass to black-list pre-colored registers. TODO: If |
4319 // there was some prior register allocation pass that made register | 4305 // there was some prior register allocation pass that made register |
4320 // assignments, those registers need to be black-listed here as | 4306 // assignments, those registers need to be black-listed here as |
4321 // well. | 4307 // well. |
4322 llvm::DenseMap<const Variable *, const Inst *> LastUses; | 4308 llvm::DenseMap<const Variable *, const Inst *> LastUses; |
4323 // The first pass also keeps track of which instruction is the last | 4309 // The first pass also keeps track of which instruction is the last |
4324 // use for each infinite-weight variable. After the last use, the | 4310 // use for each infinite-weight variable. After the last use, the |
4325 // variable is released to the free list. | 4311 // variable is released to the free list. |
4326 for (InstList::iterator I = Context.getCur(), E = Context.getEnd(); I != E; | 4312 for (auto I = Context.getCur(), E = Context.getEnd(); I != E; ++I) { |
4327 ++I) { | |
4328 const Inst *Inst = *I; | 4313 const Inst *Inst = *I; |
4329 if (Inst->isDeleted()) | 4314 if (Inst->isDeleted()) |
4330 continue; | 4315 continue; |
4331 // Don't consider a FakeKill instruction, because (currently) it | 4316 // Don't consider a FakeKill instruction, because (currently) it |
4332 // is only used to kill all scratch registers at a call site, and | 4317 // is only used to kill all scratch registers at a call site, and |
4333 // we don't want to black-list all scratch registers during the | 4318 // we don't want to black-list all scratch registers during the |
4334 // call lowering. This could become a problem since it relies on | 4319 // call lowering. This could become a problem since it relies on |
4335 // the lowering sequence not keeping any infinite-weight variables | 4320 // the lowering sequence not keeping any infinite-weight variables |
4336 // live across a call. TODO(stichnot): Consider replacing this | 4321 // live across a call. TODO(stichnot): Consider replacing this |
4337 // whole postLower() implementation with a robust local register | 4322 // whole postLower() implementation with a robust local register |
(...skipping 12 matching lines...) Expand all Loading... |
4350 LastUses[Var] = Inst; | 4335 LastUses[Var] = Inst; |
4351 if (!Var->hasReg()) | 4336 if (!Var->hasReg()) |
4352 continue; | 4337 continue; |
4353 WhiteList[Var->getRegNum()] = false; | 4338 WhiteList[Var->getRegNum()] = false; |
4354 } | 4339 } |
4355 } | 4340 } |
4356 } | 4341 } |
4357 // The second pass colors infinite-weight variables. | 4342 // The second pass colors infinite-weight variables. |
4358 llvm::SmallBitVector AvailableRegisters = WhiteList; | 4343 llvm::SmallBitVector AvailableRegisters = WhiteList; |
4359 llvm::SmallBitVector FreedRegisters(WhiteList.size()); | 4344 llvm::SmallBitVector FreedRegisters(WhiteList.size()); |
4360 for (InstList::iterator I = Context.getCur(), E = Context.getEnd(); I != E; | 4345 for (auto I = Context.getCur(), E = Context.getEnd(); I != E; ++I) { |
4361 ++I) { | |
4362 FreedRegisters.reset(); | 4346 FreedRegisters.reset(); |
4363 const Inst *Inst = *I; | 4347 const Inst *Inst = *I; |
4364 if (Inst->isDeleted()) | 4348 if (Inst->isDeleted()) |
4365 continue; | 4349 continue; |
4366 // Skip FakeKill instructions like above. | 4350 // Skip FakeKill instructions like above. |
4367 if (llvm::isa<InstFakeKill>(Inst)) | 4351 if (llvm::isa<InstFakeKill>(Inst)) |
4368 continue; | 4352 continue; |
4369 // Iterate over all variables referenced in the instruction, | 4353 // Iterate over all variables referenced in the instruction, |
4370 // including the Dest variable (if any). If the variable is | 4354 // including the Dest variable (if any). If the variable is |
4371 // marked as infinite-weight, find it a register. If this | 4355 // marked as infinite-weight, find it a register. If this |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4526 Str << "\t.align\t" << Align << "\n"; | 4510 Str << "\t.align\t" << Align << "\n"; |
4527 Str << MangledName << ":\n"; | 4511 Str << MangledName << ":\n"; |
4528 for (SizeT i = 0; i < Size; ++i) { | 4512 for (SizeT i = 0; i < Size; ++i) { |
4529 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; | 4513 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; |
4530 } | 4514 } |
4531 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4515 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
4532 } | 4516 } |
4533 } | 4517 } |
4534 | 4518 |
4535 } // end of namespace Ice | 4519 } // end of namespace Ice |
OLD | NEW |