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