OLD | NEW |
1 //===- subzero/src/IceTargetLowering.cpp - Basic lowering implementation --===// | 1 //===- subzero/src/IceTargetLowering.cpp - Basic lowering implementation --===// |
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 /// \file | 10 /// \file |
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 Dest = Source; | 558 Dest = Source; |
559 // Instead of std::sort, we could do a bucket sort with log2(alignment) as | 559 // Instead of std::sort, we could do a bucket sort with log2(alignment) as |
560 // the buckets, if performance is an issue. | 560 // the buckets, if performance is an issue. |
561 std::sort(Dest.begin(), Dest.end(), | 561 std::sort(Dest.begin(), Dest.end(), |
562 [this](const Variable *V1, const Variable *V2) { | 562 [this](const Variable *V1, const Variable *V2) { |
563 return typeWidthInBytesOnStack(V1->getType()) > | 563 return typeWidthInBytesOnStack(V1->getType()) > |
564 typeWidthInBytesOnStack(V2->getType()); | 564 typeWidthInBytesOnStack(V2->getType()); |
565 }); | 565 }); |
566 } | 566 } |
567 | 567 |
568 namespace { | |
569 bool mightHaveStackSlot(const Variable *Var, const BitVector &IsVarReferenced) { | |
570 if (!IsVarReferenced[Var->getIndex()]) | |
571 return false; | |
572 if (Var->hasReg()) | |
573 return false; | |
574 return true; | |
575 } | |
576 } // end of anonymous namespace | |
577 | |
578 void TargetLowering::getVarStackSlotParams( | 568 void TargetLowering::getVarStackSlotParams( |
579 VarList &SortedSpilledVariables, SmallBitVector &RegsUsed, | 569 VarList &SortedSpilledVariables, SmallBitVector &RegsUsed, |
580 size_t *GlobalsSize, size_t *SpillAreaSizeBytes, | 570 size_t *GlobalsSize, size_t *SpillAreaSizeBytes, |
581 uint32_t *SpillAreaAlignmentBytes, uint32_t *LocalsSlotsAlignmentBytes, | 571 uint32_t *SpillAreaAlignmentBytes, uint32_t *LocalsSlotsAlignmentBytes, |
582 std::function<bool(Variable *)> TargetVarHook) { | 572 std::function<bool(Variable *)> TargetVarHook) { |
583 const VariablesMetadata *VMetadata = Func->getVMetadata(); | 573 const VariablesMetadata *VMetadata = Func->getVMetadata(); |
584 BitVector IsVarReferenced(Func->getNumVariables()); | 574 BitVector IsVarReferenced(Func->getNumVariables()); |
585 for (CfgNode *Node : Func->getNodes()) { | 575 for (CfgNode *Node : Func->getNodes()) { |
586 for (Inst &Instr : Node->getInsts()) { | 576 for (Inst &Instr : Node->getInsts()) { |
587 if (Instr.isDeleted()) | 577 if (Instr.isDeleted()) |
588 continue; | 578 continue; |
589 if (const Variable *Var = Instr.getDest()) | 579 if (const Variable *Var = Instr.getDest()) |
590 IsVarReferenced[Var->getIndex()] = true; | 580 IsVarReferenced[Var->getIndex()] = true; |
591 FOREACH_VAR_IN_INST(Var, Instr) { | 581 FOREACH_VAR_IN_INST(Var, Instr) { |
592 IsVarReferenced[Var->getIndex()] = true; | 582 IsVarReferenced[Var->getIndex()] = true; |
593 } | 583 } |
594 } | 584 } |
595 } | 585 } |
596 | 586 |
597 // Find each variable Var where: | |
598 // - Var is actively referenced | |
599 // - Var does not have a register | |
600 // - Var's furthest ancestor through LinkedTo: Root | |
601 // - Root has no active references, or has a register | |
602 // | |
603 // When any such Var is found, rotate the LinkedTo tree by swapping | |
604 // Var->LinkedTo and Root->LinkedTo. This ensures that when Var needs a stack | |
605 // slot, either its LinkedTo field is nullptr, or Var->getLinkedToRoot() | |
606 // returns a variable with a stack slot. | |
607 for (Variable *Var : Func->getVariables()) { | |
608 if (!mightHaveStackSlot(Var, IsVarReferenced)) | |
609 continue; | |
610 if (Variable *Root = Var->getLinkedToRoot()) { | |
611 assert(Root->getLinkedTo() == nullptr); | |
612 if (mightHaveStackSlot(Root, IsVarReferenced)) { | |
613 // Found a "safe" root, no need to rotate the tree. | |
614 continue; | |
615 } | |
616 Var->setLinkedTo(nullptr); | |
617 Root->setLinkedTo(Var); | |
618 } | |
619 } | |
620 | |
621 // If SimpleCoalescing is false, each variable without a register gets its | 587 // If SimpleCoalescing is false, each variable without a register gets its |
622 // own unique stack slot, which leads to large stack frames. If | 588 // own unique stack slot, which leads to large stack frames. If |
623 // SimpleCoalescing is true, then each "global" variable without a register | 589 // SimpleCoalescing is true, then each "global" variable without a register |
624 // gets its own slot, but "local" variable slots are reused across basic | 590 // gets its own slot, but "local" variable slots are reused across basic |
625 // blocks. E.g., if A and B are local to block 1 and C is local to block 2, | 591 // blocks. E.g., if A and B are local to block 1 and C is local to block 2, |
626 // then C may share a slot with A or B. | 592 // then C may share a slot with A or B. |
627 // | 593 // |
628 // We cannot coalesce stack slots if this function calls a "returns twice" | 594 // We cannot coalesce stack slots if this function calls a "returns twice" |
629 // function. In that case, basic blocks may be revisited, and variables local | 595 // function. In that case, basic blocks may be revisited, and variables local |
630 // to those basic blocks are actually live until after the called function | 596 // to those basic blocks are actually live until after the called function |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
938 case TARGET_LOWERING_CLASS_FOR(X): \ | 904 case TARGET_LOWERING_CLASS_FOR(X): \ |
939 return ::X::createTargetHeaderLowering(Ctx); | 905 return ::X::createTargetHeaderLowering(Ctx); |
940 #include "SZTargets.def" | 906 #include "SZTargets.def" |
941 #undef SUBZERO_TARGET | 907 #undef SUBZERO_TARGET |
942 } | 908 } |
943 } | 909 } |
944 | 910 |
945 TargetHeaderLowering::~TargetHeaderLowering() = default; | 911 TargetHeaderLowering::~TargetHeaderLowering() = default; |
946 | 912 |
947 } // end of namespace Ice | 913 } // end of namespace Ice |
OLD | NEW |