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 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
548 } | 548 } |
549 } | 549 } |
550 | 550 |
551 void TargetX8632::sortByAlignment(VarList &Dest, const VarList &Source) const { | 551 void TargetX8632::sortByAlignment(VarList &Dest, const VarList &Source) const { |
552 // Sort the variables into buckets according to the log of their width | 552 // Sort the variables into buckets according to the log of their width |
553 // in bytes. | 553 // in bytes. |
554 const SizeT NumBuckets = | 554 const SizeT NumBuckets = |
555 X86_LOG2_OF_MAX_STACK_SLOT_SIZE - X86_LOG2_OF_MIN_STACK_SLOT_SIZE + 1; | 555 X86_LOG2_OF_MAX_STACK_SLOT_SIZE - X86_LOG2_OF_MIN_STACK_SLOT_SIZE + 1; |
556 VarList Buckets[NumBuckets]; | 556 VarList Buckets[NumBuckets]; |
557 | 557 |
558 for (VarList::const_iterator I = Source.begin(), E = Source.end(); I != E; | 558 for (Variable *Var : Source) { |
559 ++I) { | |
560 Variable *Var = *I; | |
561 uint32_t NaturalAlignment = typeWidthInBytesOnStack(Var->getType()); | 559 uint32_t NaturalAlignment = typeWidthInBytesOnStack(Var->getType()); |
562 SizeT LogNaturalAlignment = llvm::findFirstSet(NaturalAlignment); | 560 SizeT LogNaturalAlignment = llvm::findFirstSet(NaturalAlignment); |
563 assert(LogNaturalAlignment >= X86_LOG2_OF_MIN_STACK_SLOT_SIZE); | 561 assert(LogNaturalAlignment >= X86_LOG2_OF_MIN_STACK_SLOT_SIZE); |
564 assert(LogNaturalAlignment <= X86_LOG2_OF_MAX_STACK_SLOT_SIZE); | 562 assert(LogNaturalAlignment <= X86_LOG2_OF_MAX_STACK_SLOT_SIZE); |
565 SizeT BucketIndex = LogNaturalAlignment - X86_LOG2_OF_MIN_STACK_SLOT_SIZE; | 563 SizeT BucketIndex = LogNaturalAlignment - X86_LOG2_OF_MIN_STACK_SLOT_SIZE; |
566 Buckets[BucketIndex].push_back(Var); | 564 Buckets[BucketIndex].push_back(Var); |
567 } | 565 } |
568 | 566 |
569 for (SizeT I = 0, E = NumBuckets; I < E; ++I) { | 567 for (SizeT I = 0, E = NumBuckets; I < E; ++I) { |
570 VarList &List = Buckets[NumBuckets - I - 1]; | 568 VarList &List = Buckets[NumBuckets - I - 1]; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 const VarList &Variables = Func->getVariables(); | 689 const VarList &Variables = Func->getVariables(); |
692 const VarList &Args = Func->getArgs(); | 690 const VarList &Args = Func->getArgs(); |
693 VarList SpilledVariables, SortedSpilledVariables, VariablesLinkedToSpillSlots; | 691 VarList SpilledVariables, SortedSpilledVariables, VariablesLinkedToSpillSlots; |
694 | 692 |
695 // If there is a separate locals area, this specifies the alignment | 693 // If there is a separate locals area, this specifies the alignment |
696 // for it. | 694 // for it. |
697 uint32_t LocalsSlotsAlignmentBytes = 0; | 695 uint32_t LocalsSlotsAlignmentBytes = 0; |
698 // The entire spill locations area gets aligned to largest natural | 696 // The entire spill locations area gets aligned to largest natural |
699 // alignment of the variables that have a spill slot. | 697 // alignment of the variables that have a spill slot. |
700 uint32_t SpillAreaAlignmentBytes = 0; | 698 uint32_t SpillAreaAlignmentBytes = 0; |
701 for (VarList::const_iterator I = Variables.begin(), E = Variables.end(); | 699 for (Variable *Var : Variables) { |
702 I != E; ++I) { | |
703 Variable *Var = *I; | |
704 if (Var->hasReg()) { | 700 if (Var->hasReg()) { |
705 RegsUsed[Var->getRegNum()] = true; | 701 RegsUsed[Var->getRegNum()] = true; |
706 continue; | 702 continue; |
707 } | 703 } |
708 // An argument either does not need a stack slot (if passed in a | 704 // An argument either does not need a stack slot (if passed in a |
709 // register) or already has one (if passed on the stack). | 705 // register) or already has one (if passed on the stack). |
710 if (Var->getIsArg()) | 706 if (Var->getIsArg()) |
711 continue; | 707 continue; |
712 // An unreferenced variable doesn't need a stack slot. | 708 // An unreferenced variable doesn't need a stack slot. |
713 if (ComputedLiveRanges && Var->getLiveRange().isEmpty()) | 709 if (ComputedLiveRanges && Var->getLiveRange().isEmpty()) |
714 continue; | 710 continue; |
715 // A spill slot linked to a variable with a stack slot should reuse | 711 // A spill slot linked to a variable with a stack slot should reuse |
716 // that stack slot. | 712 // that stack slot. |
717 if (SpillVariable *SpillVar = llvm::dyn_cast<SpillVariable>(Var)) { | 713 if (SpillVariable *SpillVar = llvm::dyn_cast<SpillVariable>(Var)) { |
718 assert(Var->getWeight() == RegWeight::Zero); | 714 assert(Var->getWeight() == RegWeight::Zero); |
719 if (!SpillVar->getLinkedTo()->hasReg()) { | 715 if (!SpillVar->getLinkedTo()->hasReg()) { |
720 VariablesLinkedToSpillSlots.push_back(Var); | 716 VariablesLinkedToSpillSlots.push_back(Var); |
721 continue; | 717 continue; |
722 } | 718 } |
723 } | 719 } |
724 SpilledVariables.push_back(Var); | 720 SpilledVariables.push_back(Var); |
725 } | 721 } |
726 | 722 |
727 SortedSpilledVariables.reserve(SpilledVariables.size()); | 723 SortedSpilledVariables.reserve(SpilledVariables.size()); |
728 sortByAlignment(SortedSpilledVariables, SpilledVariables); | 724 sortByAlignment(SortedSpilledVariables, SpilledVariables); |
729 for (VarList::const_iterator I = SortedSpilledVariables.begin(), | 725 for (Variable *Var : SortedSpilledVariables) { |
730 E = SortedSpilledVariables.end(); | |
731 I != E; ++I) { | |
732 Variable *Var = *I; | |
733 size_t Increment = typeWidthInBytesOnStack(Var->getType()); | 726 size_t Increment = typeWidthInBytesOnStack(Var->getType()); |
734 if (!SpillAreaAlignmentBytes) | 727 if (!SpillAreaAlignmentBytes) |
735 SpillAreaAlignmentBytes = Increment; | 728 SpillAreaAlignmentBytes = Increment; |
736 if (SimpleCoalescing && VMetadata->isTracked(Var)) { | 729 if (SimpleCoalescing && VMetadata->isTracked(Var)) { |
737 if (VMetadata->isMultiBlock(Var)) { | 730 if (VMetadata->isMultiBlock(Var)) { |
738 GlobalsSize += Increment; | 731 GlobalsSize += Increment; |
739 } else { | 732 } else { |
740 SizeT NodeIndex = VMetadata->getLocalUseNode(Var)->getIndex(); | 733 SizeT NodeIndex = VMetadata->getLocalUseNode(Var)->getIndex(); |
741 LocalsSize[NodeIndex] += Increment; | 734 LocalsSize[NodeIndex] += Increment; |
742 if (LocalsSize[NodeIndex] > SpillAreaSizeBytes) | 735 if (LocalsSize[NodeIndex] > SpillAreaSizeBytes) |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 ++NumXmmArgs; | 823 ++NumXmmArgs; |
831 continue; | 824 continue; |
832 } | 825 } |
833 finishArgumentLowering(Arg, FramePtr, BasicFrameOffset, InArgsSizeBytes); | 826 finishArgumentLowering(Arg, FramePtr, BasicFrameOffset, InArgsSizeBytes); |
834 } | 827 } |
835 | 828 |
836 // Fill in stack offsets for locals. | 829 // Fill in stack offsets for locals. |
837 size_t GlobalsSpaceUsed = SpillAreaPaddingBytes; | 830 size_t GlobalsSpaceUsed = SpillAreaPaddingBytes; |
838 LocalsSize.assign(LocalsSize.size(), 0); | 831 LocalsSize.assign(LocalsSize.size(), 0); |
839 size_t NextStackOffset = GlobalsSpaceUsed; | 832 size_t NextStackOffset = GlobalsSpaceUsed; |
840 for (VarList::const_iterator I = SortedSpilledVariables.begin(), | 833 for (Variable *Var : SortedSpilledVariables) { |
841 E = SortedSpilledVariables.end(); | |
842 I != E; ++I) { | |
843 Variable *Var = *I; | |
844 size_t Increment = typeWidthInBytesOnStack(Var->getType()); | 834 size_t Increment = typeWidthInBytesOnStack(Var->getType()); |
845 if (SimpleCoalescing && VMetadata->isTracked(Var)) { | 835 if (SimpleCoalescing && VMetadata->isTracked(Var)) { |
846 if (VMetadata->isMultiBlock(Var)) { | 836 if (VMetadata->isMultiBlock(Var)) { |
847 GlobalsSpaceUsed += Increment; | 837 GlobalsSpaceUsed += Increment; |
848 NextStackOffset = GlobalsSpaceUsed; | 838 NextStackOffset = GlobalsSpaceUsed; |
849 } else { | 839 } else { |
850 SizeT NodeIndex = VMetadata->getLocalUseNode(Var)->getIndex(); | 840 SizeT NodeIndex = VMetadata->getLocalUseNode(Var)->getIndex(); |
851 LocalsSize[NodeIndex] += Increment; | 841 LocalsSize[NodeIndex] += Increment; |
852 NextStackOffset = SpillAreaPaddingBytes + | 842 NextStackOffset = SpillAreaPaddingBytes + |
853 GlobalsAndSubsequentPaddingSize + | 843 GlobalsAndSubsequentPaddingSize + |
854 LocalsSize[NodeIndex]; | 844 LocalsSize[NodeIndex]; |
855 } | 845 } |
856 } else { | 846 } else { |
857 NextStackOffset += Increment; | 847 NextStackOffset += Increment; |
858 } | 848 } |
859 if (IsEbpBasedFrame) | 849 if (IsEbpBasedFrame) |
860 Var->setStackOffset(-NextStackOffset); | 850 Var->setStackOffset(-NextStackOffset); |
861 else | 851 else |
862 Var->setStackOffset(SpillAreaSizeBytes - NextStackOffset); | 852 Var->setStackOffset(SpillAreaSizeBytes - NextStackOffset); |
863 } | 853 } |
864 this->FrameSizeLocals = NextStackOffset - SpillAreaPaddingBytes; | 854 this->FrameSizeLocals = NextStackOffset - SpillAreaPaddingBytes; |
865 this->HasComputedFrame = true; | 855 this->HasComputedFrame = true; |
866 | 856 |
867 // Assign stack offsets to variables that have been linked to spilled | 857 // Assign stack offsets to variables that have been linked to spilled |
868 // variables. | 858 // variables. |
869 for (VarList::const_iterator I = VariablesLinkedToSpillSlots.begin(), | 859 for (Variable *Var : VariablesLinkedToSpillSlots) { |
870 E = VariablesLinkedToSpillSlots.end(); | |
871 I != E; ++I) { | |
872 Variable *Var = *I; | |
873 Variable *Linked = (llvm::cast<SpillVariable>(Var))->getLinkedTo(); | 860 Variable *Linked = (llvm::cast<SpillVariable>(Var))->getLinkedTo(); |
874 Var->setStackOffset(Linked->getStackOffset()); | 861 Var->setStackOffset(Linked->getStackOffset()); |
875 } | 862 } |
876 | 863 |
877 if (Func->getContext()->isVerbose(IceV_Frame)) { | 864 if (Func->getContext()->isVerbose(IceV_Frame)) { |
878 Ostream &Str = Func->getContext()->getStrDump(); | 865 Ostream &Str = Func->getContext()->getStrDump(); |
879 | 866 |
880 Str << "Stack layout:\n"; | 867 Str << "Stack layout:\n"; |
881 uint32_t EspAdjustmentPaddingSize = | 868 uint32_t EspAdjustmentPaddingSize = |
882 SpillAreaSizeBytes - LocalsSpillAreaSize - | 869 SpillAreaSizeBytes - LocalsSpillAreaSize - |
(...skipping 14 matching lines...) Expand all Loading... |
897 << " spill area alignment = " << SpillAreaAlignmentBytes << " bytes\n" | 884 << " spill area alignment = " << SpillAreaAlignmentBytes << " bytes\n" |
898 << " locals spill area alignment = " << LocalsSlotsAlignmentBytes | 885 << " locals spill area alignment = " << LocalsSlotsAlignmentBytes |
899 << " bytes\n" | 886 << " bytes\n" |
900 << " is ebp based = " << IsEbpBasedFrame << "\n"; | 887 << " is ebp based = " << IsEbpBasedFrame << "\n"; |
901 } | 888 } |
902 } | 889 } |
903 | 890 |
904 void TargetX8632::addEpilog(CfgNode *Node) { | 891 void TargetX8632::addEpilog(CfgNode *Node) { |
905 InstList &Insts = Node->getInsts(); | 892 InstList &Insts = Node->getInsts(); |
906 InstList::reverse_iterator RI, E; | 893 InstList::reverse_iterator RI, E; |
| 894 // TODO(stichnot): Use llvm::make_range with LLVM 3.5. |
907 for (RI = Insts.rbegin(), E = Insts.rend(); RI != E; ++RI) { | 895 for (RI = Insts.rbegin(), E = Insts.rend(); RI != E; ++RI) { |
908 if (llvm::isa<InstX8632Ret>(*RI)) | 896 if (llvm::isa<InstX8632Ret>(*RI)) |
909 break; | 897 break; |
910 } | 898 } |
911 if (RI == E) | 899 if (RI == E) |
912 return; | 900 return; |
913 | 901 |
914 // Convert the reverse_iterator position into its corresponding | 902 // Convert the reverse_iterator position into its corresponding |
915 // (forward) iterator position. | 903 // (forward) iterator position. |
916 InstList::iterator InsertPoint = RI.base(); | 904 InstList::iterator InsertPoint = RI.base(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
972 | 960 |
973 template <typename T> void TargetX8632::emitConstantPool() const { | 961 template <typename T> void TargetX8632::emitConstantPool() const { |
974 Ostream &Str = Ctx->getStrEmit(); | 962 Ostream &Str = Ctx->getStrEmit(); |
975 Type Ty = T::Ty; | 963 Type Ty = T::Ty; |
976 SizeT Align = typeAlignInBytes(Ty); | 964 SizeT Align = typeAlignInBytes(Ty); |
977 ConstantList Pool = Ctx->getConstantPool(Ty); | 965 ConstantList Pool = Ctx->getConstantPool(Ty); |
978 | 966 |
979 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align | 967 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align |
980 << "\n"; | 968 << "\n"; |
981 Str << "\t.align\t" << Align << "\n"; | 969 Str << "\t.align\t" << Align << "\n"; |
982 for (ConstantList::const_iterator I = Pool.begin(), E = Pool.end(); I != E; | 970 for (Constant *C : Pool) { |
983 ++I) { | 971 typename T::IceType *Const = llvm::cast<typename T::IceType>(C); |
984 typename T::IceType *Const = llvm::cast<typename T::IceType>(*I); | |
985 typename T::PrimitiveFpType Value = Const->getValue(); | 972 typename T::PrimitiveFpType Value = Const->getValue(); |
986 // Use memcpy() to copy bits from Value into RawValue in a way | 973 // Use memcpy() to copy bits from Value into RawValue in a way |
987 // that avoids breaking strict-aliasing rules. | 974 // that avoids breaking strict-aliasing rules. |
988 typename T::PrimitiveIntType RawValue; | 975 typename T::PrimitiveIntType RawValue; |
989 memcpy(&RawValue, &Value, sizeof(Value)); | 976 memcpy(&RawValue, &Value, sizeof(Value)); |
990 char buf[30]; | 977 char buf[30]; |
991 int CharsPrinted = | 978 int CharsPrinted = |
992 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); | 979 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); |
993 assert(CharsPrinted >= 0 && | 980 assert(CharsPrinted >= 0 && |
994 (size_t)CharsPrinted < llvm::array_lengthof(buf)); | 981 (size_t)CharsPrinted < llvm::array_lengthof(buf)); |
(...skipping 3330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4325 RegExclude |= RegSet_FramePointer; | 4312 RegExclude |= RegSet_FramePointer; |
4326 llvm::SmallBitVector WhiteList = getRegisterSet(RegInclude, RegExclude); | 4313 llvm::SmallBitVector WhiteList = getRegisterSet(RegInclude, RegExclude); |
4327 // Make one pass to black-list pre-colored registers. TODO: If | 4314 // Make one pass to black-list pre-colored registers. TODO: If |
4328 // there was some prior register allocation pass that made register | 4315 // there was some prior register allocation pass that made register |
4329 // assignments, those registers need to be black-listed here as | 4316 // assignments, those registers need to be black-listed here as |
4330 // well. | 4317 // well. |
4331 llvm::DenseMap<const Variable *, const Inst *> LastUses; | 4318 llvm::DenseMap<const Variable *, const Inst *> LastUses; |
4332 // The first pass also keeps track of which instruction is the last | 4319 // The first pass also keeps track of which instruction is the last |
4333 // use for each infinite-weight variable. After the last use, the | 4320 // use for each infinite-weight variable. After the last use, the |
4334 // variable is released to the free list. | 4321 // variable is released to the free list. |
4335 for (InstList::iterator I = Context.getCur(), E = Context.getEnd(); I != E; | 4322 for (Inst *Inst : Context) { |
4336 ++I) { | |
4337 const Inst *Inst = *I; | |
4338 if (Inst->isDeleted()) | 4323 if (Inst->isDeleted()) |
4339 continue; | 4324 continue; |
4340 // Don't consider a FakeKill instruction, because (currently) it | 4325 // Don't consider a FakeKill instruction, because (currently) it |
4341 // is only used to kill all scratch registers at a call site, and | 4326 // is only used to kill all scratch registers at a call site, and |
4342 // we don't want to black-list all scratch registers during the | 4327 // we don't want to black-list all scratch registers during the |
4343 // call lowering. This could become a problem since it relies on | 4328 // call lowering. This could become a problem since it relies on |
4344 // the lowering sequence not keeping any infinite-weight variables | 4329 // the lowering sequence not keeping any infinite-weight variables |
4345 // live across a call. TODO(stichnot): Consider replacing this | 4330 // live across a call. TODO(stichnot): Consider replacing this |
4346 // whole postLower() implementation with a robust local register | 4331 // whole postLower() implementation with a robust local register |
4347 // allocator, for example compute live ranges only for pre-colored | 4332 // allocator, for example compute live ranges only for pre-colored |
(...skipping 11 matching lines...) Expand all Loading... |
4359 LastUses[Var] = Inst; | 4344 LastUses[Var] = Inst; |
4360 if (!Var->hasReg()) | 4345 if (!Var->hasReg()) |
4361 continue; | 4346 continue; |
4362 WhiteList[Var->getRegNum()] = false; | 4347 WhiteList[Var->getRegNum()] = false; |
4363 } | 4348 } |
4364 } | 4349 } |
4365 } | 4350 } |
4366 // The second pass colors infinite-weight variables. | 4351 // The second pass colors infinite-weight variables. |
4367 llvm::SmallBitVector AvailableRegisters = WhiteList; | 4352 llvm::SmallBitVector AvailableRegisters = WhiteList; |
4368 llvm::SmallBitVector FreedRegisters(WhiteList.size()); | 4353 llvm::SmallBitVector FreedRegisters(WhiteList.size()); |
4369 for (InstList::iterator I = Context.getCur(), E = Context.getEnd(); I != E; | 4354 for (Inst *Inst : Context) { |
4370 ++I) { | |
4371 FreedRegisters.reset(); | 4355 FreedRegisters.reset(); |
4372 const Inst *Inst = *I; | |
4373 if (Inst->isDeleted()) | 4356 if (Inst->isDeleted()) |
4374 continue; | 4357 continue; |
4375 // Skip FakeKill instructions like above. | 4358 // Skip FakeKill instructions like above. |
4376 if (llvm::isa<InstFakeKill>(Inst)) | 4359 if (llvm::isa<InstFakeKill>(Inst)) |
4377 continue; | 4360 continue; |
4378 // Iterate over all variables referenced in the instruction, | 4361 // Iterate over all variables referenced in the instruction, |
4379 // including the Dest variable (if any). If the variable is | 4362 // including the Dest variable (if any). If the variable is |
4380 // marked as infinite-weight, find it a register. If this | 4363 // marked as infinite-weight, find it a register. If this |
4381 // instruction is the last use of the variable in the lowered | 4364 // instruction is the last use of the variable in the lowered |
4382 // sequence, release the register to the free list after this | 4365 // sequence, release the register to the free list after this |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4535 Str << "\t.align\t" << Align << "\n"; | 4518 Str << "\t.align\t" << Align << "\n"; |
4536 Str << MangledName << ":\n"; | 4519 Str << MangledName << ":\n"; |
4537 for (SizeT i = 0; i < Size; ++i) { | 4520 for (SizeT i = 0; i < Size; ++i) { |
4538 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; | 4521 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; |
4539 } | 4522 } |
4540 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4523 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
4541 } | 4524 } |
4542 } | 4525 } |
4543 | 4526 |
4544 } // end of namespace Ice | 4527 } // end of namespace Ice |
OLD | NEW |