Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(216)

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 619893002: Subzero: Auto-awesome iterators. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Use AsmCodeByte instead of uint8_t Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceTargetLoweringX8632.h ('k') | src/IceTimerTree.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceTargetLoweringX8632.h ('k') | src/IceTimerTree.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698