10bf841acSMarina Yatsina //===- ExecutionDomainFix.cpp - Fix execution domain issues ----*- C++ -*--===//
23d8efa4fSMarina Yatsina //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63d8efa4fSMarina Yatsina //
73d8efa4fSMarina Yatsina //===----------------------------------------------------------------------===//
83d8efa4fSMarina Yatsina 
93d8efa4fSMarina Yatsina #include "llvm/CodeGen/ExecutionDomainFix.h"
103d8efa4fSMarina Yatsina #include "llvm/CodeGen/MachineRegisterInfo.h"
113d8efa4fSMarina Yatsina #include "llvm/CodeGen/TargetInstrInfo.h"
123d8efa4fSMarina Yatsina 
133d8efa4fSMarina Yatsina using namespace llvm;
143d8efa4fSMarina Yatsina 
153d8efa4fSMarina Yatsina #define DEBUG_TYPE "execution-deps-fix"
163d8efa4fSMarina Yatsina 
173d8efa4fSMarina Yatsina iterator_range<SmallVectorImpl<int>::const_iterator>
183d8efa4fSMarina Yatsina ExecutionDomainFix::regIndices(unsigned Reg) const {
193d8efa4fSMarina Yatsina   assert(Reg < AliasMap.size() && "Invalid register");
203d8efa4fSMarina Yatsina   const auto &Entry = AliasMap[Reg];
213d8efa4fSMarina Yatsina   return make_range(Entry.begin(), Entry.end());
223d8efa4fSMarina Yatsina }
233d8efa4fSMarina Yatsina 
243d8efa4fSMarina Yatsina DomainValue *ExecutionDomainFix::alloc(int domain) {
253d8efa4fSMarina Yatsina   DomainValue *dv = Avail.empty() ? new (Allocator.Allocate()) DomainValue
263d8efa4fSMarina Yatsina                                   : Avail.pop_back_val();
273d8efa4fSMarina Yatsina   if (domain >= 0)
283d8efa4fSMarina Yatsina     dv->addDomain(domain);
293d8efa4fSMarina Yatsina   assert(dv->Refs == 0 && "Reference count wasn't cleared");
303d8efa4fSMarina Yatsina   assert(!dv->Next && "Chained DomainValue shouldn't have been recycled");
313d8efa4fSMarina Yatsina   return dv;
323d8efa4fSMarina Yatsina }
333d8efa4fSMarina Yatsina 
343d8efa4fSMarina Yatsina void ExecutionDomainFix::release(DomainValue *DV) {
353d8efa4fSMarina Yatsina   while (DV) {
363d8efa4fSMarina Yatsina     assert(DV->Refs && "Bad DomainValue");
373d8efa4fSMarina Yatsina     if (--DV->Refs)
383d8efa4fSMarina Yatsina       return;
393d8efa4fSMarina Yatsina 
403d8efa4fSMarina Yatsina     // There are no more DV references. Collapse any contained instructions.
413d8efa4fSMarina Yatsina     if (DV->AvailableDomains && !DV->isCollapsed())
423d8efa4fSMarina Yatsina       collapse(DV, DV->getFirstDomain());
433d8efa4fSMarina Yatsina 
443d8efa4fSMarina Yatsina     DomainValue *Next = DV->Next;
453d8efa4fSMarina Yatsina     DV->clear();
463d8efa4fSMarina Yatsina     Avail.push_back(DV);
473d8efa4fSMarina Yatsina     // Also release the next DomainValue in the chain.
483d8efa4fSMarina Yatsina     DV = Next;
493d8efa4fSMarina Yatsina   }
503d8efa4fSMarina Yatsina }
513d8efa4fSMarina Yatsina 
523d8efa4fSMarina Yatsina DomainValue *ExecutionDomainFix::resolve(DomainValue *&DVRef) {
533d8efa4fSMarina Yatsina   DomainValue *DV = DVRef;
543d8efa4fSMarina Yatsina   if (!DV || !DV->Next)
553d8efa4fSMarina Yatsina     return DV;
563d8efa4fSMarina Yatsina 
573d8efa4fSMarina Yatsina   // DV has a chain. Find the end.
583d8efa4fSMarina Yatsina   do
593d8efa4fSMarina Yatsina     DV = DV->Next;
603d8efa4fSMarina Yatsina   while (DV->Next);
613d8efa4fSMarina Yatsina 
623d8efa4fSMarina Yatsina   // Update DVRef to point to DV.
633d8efa4fSMarina Yatsina   retain(DV);
643d8efa4fSMarina Yatsina   release(DVRef);
653d8efa4fSMarina Yatsina   DVRef = DV;
663d8efa4fSMarina Yatsina   return DV;
673d8efa4fSMarina Yatsina }
683d8efa4fSMarina Yatsina 
693d8efa4fSMarina Yatsina void ExecutionDomainFix::setLiveReg(int rx, DomainValue *dv) {
703d8efa4fSMarina Yatsina   assert(unsigned(rx) < NumRegs && "Invalid index");
713d8efa4fSMarina Yatsina   assert(!LiveRegs.empty() && "Must enter basic block first.");
723d8efa4fSMarina Yatsina 
733d8efa4fSMarina Yatsina   if (LiveRegs[rx] == dv)
743d8efa4fSMarina Yatsina     return;
753d8efa4fSMarina Yatsina   if (LiveRegs[rx])
763d8efa4fSMarina Yatsina     release(LiveRegs[rx]);
773d8efa4fSMarina Yatsina   LiveRegs[rx] = retain(dv);
783d8efa4fSMarina Yatsina }
793d8efa4fSMarina Yatsina 
803d8efa4fSMarina Yatsina void ExecutionDomainFix::kill(int rx) {
813d8efa4fSMarina Yatsina   assert(unsigned(rx) < NumRegs && "Invalid index");
823d8efa4fSMarina Yatsina   assert(!LiveRegs.empty() && "Must enter basic block first.");
833d8efa4fSMarina Yatsina   if (!LiveRegs[rx])
843d8efa4fSMarina Yatsina     return;
853d8efa4fSMarina Yatsina 
863d8efa4fSMarina Yatsina   release(LiveRegs[rx]);
873d8efa4fSMarina Yatsina   LiveRegs[rx] = nullptr;
883d8efa4fSMarina Yatsina }
893d8efa4fSMarina Yatsina 
903d8efa4fSMarina Yatsina void ExecutionDomainFix::force(int rx, unsigned domain) {
913d8efa4fSMarina Yatsina   assert(unsigned(rx) < NumRegs && "Invalid index");
923d8efa4fSMarina Yatsina   assert(!LiveRegs.empty() && "Must enter basic block first.");
933d8efa4fSMarina Yatsina   if (DomainValue *dv = LiveRegs[rx]) {
943d8efa4fSMarina Yatsina     if (dv->isCollapsed())
953d8efa4fSMarina Yatsina       dv->addDomain(domain);
963d8efa4fSMarina Yatsina     else if (dv->hasDomain(domain))
973d8efa4fSMarina Yatsina       collapse(dv, domain);
983d8efa4fSMarina Yatsina     else {
993d8efa4fSMarina Yatsina       // This is an incompatible open DomainValue. Collapse it to whatever and
1003d8efa4fSMarina Yatsina       // force the new value into domain. This costs a domain crossing.
1013d8efa4fSMarina Yatsina       collapse(dv, dv->getFirstDomain());
1023d8efa4fSMarina Yatsina       assert(LiveRegs[rx] && "Not live after collapse?");
1033d8efa4fSMarina Yatsina       LiveRegs[rx]->addDomain(domain);
1043d8efa4fSMarina Yatsina     }
1053d8efa4fSMarina Yatsina   } else {
1063d8efa4fSMarina Yatsina     // Set up basic collapsed DomainValue.
1073d8efa4fSMarina Yatsina     setLiveReg(rx, alloc(domain));
1083d8efa4fSMarina Yatsina   }
1093d8efa4fSMarina Yatsina }
1103d8efa4fSMarina Yatsina 
1113d8efa4fSMarina Yatsina void ExecutionDomainFix::collapse(DomainValue *dv, unsigned domain) {
1123d8efa4fSMarina Yatsina   assert(dv->hasDomain(domain) && "Cannot collapse");
1133d8efa4fSMarina Yatsina 
1143d8efa4fSMarina Yatsina   // Collapse all the instructions.
1153d8efa4fSMarina Yatsina   while (!dv->Instrs.empty())
1163d8efa4fSMarina Yatsina     TII->setExecutionDomain(*dv->Instrs.pop_back_val(), domain);
1173d8efa4fSMarina Yatsina   dv->setSingleDomain(domain);
1183d8efa4fSMarina Yatsina 
1193d8efa4fSMarina Yatsina   // If there are multiple users, give them new, unique DomainValues.
1203d8efa4fSMarina Yatsina   if (!LiveRegs.empty() && dv->Refs > 1)
1213d8efa4fSMarina Yatsina     for (unsigned rx = 0; rx != NumRegs; ++rx)
1223d8efa4fSMarina Yatsina       if (LiveRegs[rx] == dv)
1233d8efa4fSMarina Yatsina         setLiveReg(rx, alloc(domain));
1243d8efa4fSMarina Yatsina }
1253d8efa4fSMarina Yatsina 
1263d8efa4fSMarina Yatsina bool ExecutionDomainFix::merge(DomainValue *A, DomainValue *B) {
1273d8efa4fSMarina Yatsina   assert(!A->isCollapsed() && "Cannot merge into collapsed");
1283d8efa4fSMarina Yatsina   assert(!B->isCollapsed() && "Cannot merge from collapsed");
1293d8efa4fSMarina Yatsina   if (A == B)
1303d8efa4fSMarina Yatsina     return true;
1313d8efa4fSMarina Yatsina   // Restrict to the domains that A and B have in common.
1323d8efa4fSMarina Yatsina   unsigned common = A->getCommonDomains(B->AvailableDomains);
1333d8efa4fSMarina Yatsina   if (!common)
1343d8efa4fSMarina Yatsina     return false;
1353d8efa4fSMarina Yatsina   A->AvailableDomains = common;
1363d8efa4fSMarina Yatsina   A->Instrs.append(B->Instrs.begin(), B->Instrs.end());
1373d8efa4fSMarina Yatsina 
1383d8efa4fSMarina Yatsina   // Clear the old DomainValue so we won't try to swizzle instructions twice.
1393d8efa4fSMarina Yatsina   B->clear();
1403d8efa4fSMarina Yatsina   // All uses of B are referred to A.
1413d8efa4fSMarina Yatsina   B->Next = retain(A);
1423d8efa4fSMarina Yatsina 
1433d8efa4fSMarina Yatsina   for (unsigned rx = 0; rx != NumRegs; ++rx) {
1443d8efa4fSMarina Yatsina     assert(!LiveRegs.empty() && "no space allocated for live registers");
1453d8efa4fSMarina Yatsina     if (LiveRegs[rx] == B)
1463d8efa4fSMarina Yatsina       setLiveReg(rx, A);
1473d8efa4fSMarina Yatsina   }
1483d8efa4fSMarina Yatsina   return true;
1493d8efa4fSMarina Yatsina }
1503d8efa4fSMarina Yatsina 
1513d8efa4fSMarina Yatsina void ExecutionDomainFix::enterBasicBlock(
1523d8efa4fSMarina Yatsina     const LoopTraversal::TraversedMBBInfo &TraversedMBB) {
1533d8efa4fSMarina Yatsina 
1543d8efa4fSMarina Yatsina   MachineBasicBlock *MBB = TraversedMBB.MBB;
1553d8efa4fSMarina Yatsina 
1563d8efa4fSMarina Yatsina   // Set up LiveRegs to represent registers entering MBB.
1573d8efa4fSMarina Yatsina   // Set default domain values to 'no domain' (nullptr)
1583d8efa4fSMarina Yatsina   if (LiveRegs.empty())
1593d8efa4fSMarina Yatsina     LiveRegs.assign(NumRegs, nullptr);
1603d8efa4fSMarina Yatsina 
1613d8efa4fSMarina Yatsina   // This is the entry block.
1623d8efa4fSMarina Yatsina   if (MBB->pred_empty()) {
163d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << printMBBReference(*MBB) << ": entry\n");
1643d8efa4fSMarina Yatsina     return;
1653d8efa4fSMarina Yatsina   }
1663d8efa4fSMarina Yatsina 
1673d8efa4fSMarina Yatsina   // Try to coalesce live-out registers from predecessors.
1683d8efa4fSMarina Yatsina   for (MachineBasicBlock *pred : MBB->predecessors()) {
169e4d63a49SMarina Yatsina     assert(unsigned(pred->getNumber()) < MBBOutRegsInfos.size() &&
1703d8efa4fSMarina Yatsina            "Should have pre-allocated MBBInfos for all MBBs");
1713d8efa4fSMarina Yatsina     LiveRegsDVInfo &Incoming = MBBOutRegsInfos[pred->getNumber()];
1723d8efa4fSMarina Yatsina     // Incoming is null if this is a backedge from a BB
1733d8efa4fSMarina Yatsina     // we haven't processed yet
1743d8efa4fSMarina Yatsina     if (Incoming.empty())
1753d8efa4fSMarina Yatsina       continue;
1763d8efa4fSMarina Yatsina 
1773d8efa4fSMarina Yatsina     for (unsigned rx = 0; rx != NumRegs; ++rx) {
1783d8efa4fSMarina Yatsina       DomainValue *pdv = resolve(Incoming[rx]);
1793d8efa4fSMarina Yatsina       if (!pdv)
1803d8efa4fSMarina Yatsina         continue;
1813d8efa4fSMarina Yatsina       if (!LiveRegs[rx]) {
1823d8efa4fSMarina Yatsina         setLiveReg(rx, pdv);
1833d8efa4fSMarina Yatsina         continue;
1843d8efa4fSMarina Yatsina       }
1853d8efa4fSMarina Yatsina 
1863d8efa4fSMarina Yatsina       // We have a live DomainValue from more than one predecessor.
1873d8efa4fSMarina Yatsina       if (LiveRegs[rx]->isCollapsed()) {
1883d8efa4fSMarina Yatsina         // We are already collapsed, but predecessor is not. Force it.
1893d8efa4fSMarina Yatsina         unsigned Domain = LiveRegs[rx]->getFirstDomain();
1903d8efa4fSMarina Yatsina         if (!pdv->isCollapsed() && pdv->hasDomain(Domain))
1913d8efa4fSMarina Yatsina           collapse(pdv, Domain);
1923d8efa4fSMarina Yatsina         continue;
1933d8efa4fSMarina Yatsina       }
1943d8efa4fSMarina Yatsina 
1953d8efa4fSMarina Yatsina       // Currently open, merge in predecessor.
1963d8efa4fSMarina Yatsina       if (!pdv->isCollapsed())
1973d8efa4fSMarina Yatsina         merge(LiveRegs[rx], pdv);
1983d8efa4fSMarina Yatsina       else
1993d8efa4fSMarina Yatsina         force(rx, pdv->getFirstDomain());
2003d8efa4fSMarina Yatsina     }
2013d8efa4fSMarina Yatsina   }
202d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << printMBBReference(*MBB)
2033d8efa4fSMarina Yatsina                     << (!TraversedMBB.IsDone ? ": incomplete\n"
2043d8efa4fSMarina Yatsina                                              : ": all preds known\n"));
2053d8efa4fSMarina Yatsina }
2063d8efa4fSMarina Yatsina 
2073d8efa4fSMarina Yatsina void ExecutionDomainFix::leaveBasicBlock(
2083d8efa4fSMarina Yatsina     const LoopTraversal::TraversedMBBInfo &TraversedMBB) {
2093d8efa4fSMarina Yatsina   assert(!LiveRegs.empty() && "Must enter basic block first.");
210e4d63a49SMarina Yatsina   unsigned MBBNumber = TraversedMBB.MBB->getNumber();
2113d8efa4fSMarina Yatsina   assert(MBBNumber < MBBOutRegsInfos.size() &&
2123d8efa4fSMarina Yatsina          "Unexpected basic block number.");
2133d8efa4fSMarina Yatsina   // Save register clearances at end of MBB - used by enterBasicBlock().
2143d8efa4fSMarina Yatsina   for (DomainValue *OldLiveReg : MBBOutRegsInfos[MBBNumber]) {
2153d8efa4fSMarina Yatsina     release(OldLiveReg);
2163d8efa4fSMarina Yatsina   }
2173d8efa4fSMarina Yatsina   MBBOutRegsInfos[MBBNumber] = LiveRegs;
2183d8efa4fSMarina Yatsina   LiveRegs.clear();
2193d8efa4fSMarina Yatsina }
2203d8efa4fSMarina Yatsina 
2213d8efa4fSMarina Yatsina bool ExecutionDomainFix::visitInstr(MachineInstr *MI) {
2223d8efa4fSMarina Yatsina   // Update instructions with explicit execution domains.
2233d8efa4fSMarina Yatsina   std::pair<uint16_t, uint16_t> DomP = TII->getExecutionDomain(*MI);
2243d8efa4fSMarina Yatsina   if (DomP.first) {
2253d8efa4fSMarina Yatsina     if (DomP.second)
2263d8efa4fSMarina Yatsina       visitSoftInstr(MI, DomP.second);
2273d8efa4fSMarina Yatsina     else
2283d8efa4fSMarina Yatsina       visitHardInstr(MI, DomP.first);
2293d8efa4fSMarina Yatsina   }
2303d8efa4fSMarina Yatsina 
2313d8efa4fSMarina Yatsina   return !DomP.first;
2323d8efa4fSMarina Yatsina }
2333d8efa4fSMarina Yatsina 
2343d8efa4fSMarina Yatsina void ExecutionDomainFix::processDefs(MachineInstr *MI, bool Kill) {
235801bf7ebSShiva Chen   assert(!MI->isDebugInstr() && "Won't process debug values");
2363d8efa4fSMarina Yatsina   const MCInstrDesc &MCID = MI->getDesc();
2373d8efa4fSMarina Yatsina   for (unsigned i = 0,
2383d8efa4fSMarina Yatsina                 e = MI->isVariadic() ? MI->getNumOperands() : MCID.getNumDefs();
2393d8efa4fSMarina Yatsina        i != e; ++i) {
2403d8efa4fSMarina Yatsina     MachineOperand &MO = MI->getOperand(i);
2413d8efa4fSMarina Yatsina     if (!MO.isReg())
2423d8efa4fSMarina Yatsina       continue;
2433d8efa4fSMarina Yatsina     if (MO.isUse())
2443d8efa4fSMarina Yatsina       continue;
2453d8efa4fSMarina Yatsina     for (int rx : regIndices(MO.getReg())) {
2463d8efa4fSMarina Yatsina       // This instruction explicitly defines rx.
247d34e60caSNicola Zaghen       LLVM_DEBUG(dbgs() << printReg(RC->getRegister(rx), TRI) << ":\t" << *MI);
2483d8efa4fSMarina Yatsina 
2493d8efa4fSMarina Yatsina       // Kill off domains redefined by generic instructions.
2503d8efa4fSMarina Yatsina       if (Kill)
2513d8efa4fSMarina Yatsina         kill(rx);
2523d8efa4fSMarina Yatsina     }
2533d8efa4fSMarina Yatsina   }
2543d8efa4fSMarina Yatsina }
2553d8efa4fSMarina Yatsina 
2563d8efa4fSMarina Yatsina void ExecutionDomainFix::visitHardInstr(MachineInstr *mi, unsigned domain) {
2573d8efa4fSMarina Yatsina   // Collapse all uses.
2583d8efa4fSMarina Yatsina   for (unsigned i = mi->getDesc().getNumDefs(),
2593d8efa4fSMarina Yatsina                 e = mi->getDesc().getNumOperands();
2603d8efa4fSMarina Yatsina        i != e; ++i) {
2613d8efa4fSMarina Yatsina     MachineOperand &mo = mi->getOperand(i);
2623d8efa4fSMarina Yatsina     if (!mo.isReg())
2633d8efa4fSMarina Yatsina       continue;
2643d8efa4fSMarina Yatsina     for (int rx : regIndices(mo.getReg())) {
2653d8efa4fSMarina Yatsina       force(rx, domain);
2663d8efa4fSMarina Yatsina     }
2673d8efa4fSMarina Yatsina   }
2683d8efa4fSMarina Yatsina 
2693d8efa4fSMarina Yatsina   // Kill all defs and force them.
2703d8efa4fSMarina Yatsina   for (unsigned i = 0, e = mi->getDesc().getNumDefs(); i != e; ++i) {
2713d8efa4fSMarina Yatsina     MachineOperand &mo = mi->getOperand(i);
2723d8efa4fSMarina Yatsina     if (!mo.isReg())
2733d8efa4fSMarina Yatsina       continue;
2743d8efa4fSMarina Yatsina     for (int rx : regIndices(mo.getReg())) {
2753d8efa4fSMarina Yatsina       kill(rx);
2763d8efa4fSMarina Yatsina       force(rx, domain);
2773d8efa4fSMarina Yatsina     }
2783d8efa4fSMarina Yatsina   }
2793d8efa4fSMarina Yatsina }
2803d8efa4fSMarina Yatsina 
2813d8efa4fSMarina Yatsina void ExecutionDomainFix::visitSoftInstr(MachineInstr *mi, unsigned mask) {
2823d8efa4fSMarina Yatsina   // Bitmask of available domains for this instruction after taking collapsed
2833d8efa4fSMarina Yatsina   // operands into account.
2843d8efa4fSMarina Yatsina   unsigned available = mask;
2853d8efa4fSMarina Yatsina 
2863d8efa4fSMarina Yatsina   // Scan the explicit use operands for incoming domains.
2873d8efa4fSMarina Yatsina   SmallVector<int, 4> used;
2883d8efa4fSMarina Yatsina   if (!LiveRegs.empty())
2893d8efa4fSMarina Yatsina     for (unsigned i = mi->getDesc().getNumDefs(),
2903d8efa4fSMarina Yatsina                   e = mi->getDesc().getNumOperands();
2913d8efa4fSMarina Yatsina          i != e; ++i) {
2923d8efa4fSMarina Yatsina       MachineOperand &mo = mi->getOperand(i);
2933d8efa4fSMarina Yatsina       if (!mo.isReg())
2943d8efa4fSMarina Yatsina         continue;
2953d8efa4fSMarina Yatsina       for (int rx : regIndices(mo.getReg())) {
2963d8efa4fSMarina Yatsina         DomainValue *dv = LiveRegs[rx];
2973d8efa4fSMarina Yatsina         if (dv == nullptr)
2983d8efa4fSMarina Yatsina           continue;
2993d8efa4fSMarina Yatsina         // Bitmask of domains that dv and available have in common.
3003d8efa4fSMarina Yatsina         unsigned common = dv->getCommonDomains(available);
3013d8efa4fSMarina Yatsina         // Is it possible to use this collapsed register for free?
3023d8efa4fSMarina Yatsina         if (dv->isCollapsed()) {
3033d8efa4fSMarina Yatsina           // Restrict available domains to the ones in common with the operand.
3043d8efa4fSMarina Yatsina           // If there are no common domains, we must pay the cross-domain
3053d8efa4fSMarina Yatsina           // penalty for this operand.
3063d8efa4fSMarina Yatsina           if (common)
3073d8efa4fSMarina Yatsina             available = common;
3083d8efa4fSMarina Yatsina         } else if (common)
3093d8efa4fSMarina Yatsina           // Open DomainValue is compatible, save it for merging.
3103d8efa4fSMarina Yatsina           used.push_back(rx);
3113d8efa4fSMarina Yatsina         else
3123d8efa4fSMarina Yatsina           // Open DomainValue is not compatible with instruction. It is useless
3133d8efa4fSMarina Yatsina           // now.
3143d8efa4fSMarina Yatsina           kill(rx);
3153d8efa4fSMarina Yatsina       }
3163d8efa4fSMarina Yatsina     }
3173d8efa4fSMarina Yatsina 
3183d8efa4fSMarina Yatsina   // If the collapsed operands force a single domain, propagate the collapse.
3193d8efa4fSMarina Yatsina   if (isPowerOf2_32(available)) {
3203d8efa4fSMarina Yatsina     unsigned domain = countTrailingZeros(available);
3213d8efa4fSMarina Yatsina     TII->setExecutionDomain(*mi, domain);
3223d8efa4fSMarina Yatsina     visitHardInstr(mi, domain);
3233d8efa4fSMarina Yatsina     return;
3243d8efa4fSMarina Yatsina   }
3253d8efa4fSMarina Yatsina 
3263d8efa4fSMarina Yatsina   // Kill off any remaining uses that don't match available, and build a list of
3273d8efa4fSMarina Yatsina   // incoming DomainValues that we want to merge.
3283d8efa4fSMarina Yatsina   SmallVector<int, 4> Regs;
3293d8efa4fSMarina Yatsina   for (int rx : used) {
3303d8efa4fSMarina Yatsina     assert(!LiveRegs.empty() && "no space allocated for live registers");
3313d8efa4fSMarina Yatsina     DomainValue *&LR = LiveRegs[rx];
3323d8efa4fSMarina Yatsina     // This useless DomainValue could have been missed above.
3333d8efa4fSMarina Yatsina     if (!LR->getCommonDomains(available)) {
3343d8efa4fSMarina Yatsina       kill(rx);
3353d8efa4fSMarina Yatsina       continue;
3363d8efa4fSMarina Yatsina     }
3373d8efa4fSMarina Yatsina     // Sorted insertion.
3383d8efa4fSMarina Yatsina     // Enables giving priority to the latest domains during merging.
339d3b26823SFangrui Song     const int Def = RDA->getReachingDef(mi, RC->getRegister(rx));
340*78ee2fbfSFangrui Song     auto I = partition_point(Regs, [&](int I) {
341*78ee2fbfSFangrui Song       return RDA->getReachingDef(mi, RC->getRegister(I)) <= Def;
3423d8efa4fSMarina Yatsina     });
3433d8efa4fSMarina Yatsina     Regs.insert(I, rx);
3443d8efa4fSMarina Yatsina   }
3453d8efa4fSMarina Yatsina 
3463d8efa4fSMarina Yatsina   // doms are now sorted in order of appearance. Try to merge them all, giving
3473d8efa4fSMarina Yatsina   // priority to the latest ones.
3483d8efa4fSMarina Yatsina   DomainValue *dv = nullptr;
3493d8efa4fSMarina Yatsina   while (!Regs.empty()) {
3503d8efa4fSMarina Yatsina     if (!dv) {
3513d8efa4fSMarina Yatsina       dv = LiveRegs[Regs.pop_back_val()];
3523d8efa4fSMarina Yatsina       // Force the first dv to match the current instruction.
3533d8efa4fSMarina Yatsina       dv->AvailableDomains = dv->getCommonDomains(available);
3543d8efa4fSMarina Yatsina       assert(dv->AvailableDomains && "Domain should have been filtered");
3553d8efa4fSMarina Yatsina       continue;
3563d8efa4fSMarina Yatsina     }
3573d8efa4fSMarina Yatsina 
3583d8efa4fSMarina Yatsina     DomainValue *Latest = LiveRegs[Regs.pop_back_val()];
3593d8efa4fSMarina Yatsina     // Skip already merged values.
3603d8efa4fSMarina Yatsina     if (Latest == dv || Latest->Next)
3613d8efa4fSMarina Yatsina       continue;
3623d8efa4fSMarina Yatsina     if (merge(dv, Latest))
3633d8efa4fSMarina Yatsina       continue;
3643d8efa4fSMarina Yatsina 
3653d8efa4fSMarina Yatsina     // If latest didn't merge, it is useless now. Kill all registers using it.
3663d8efa4fSMarina Yatsina     for (int i : used) {
3673d8efa4fSMarina Yatsina       assert(!LiveRegs.empty() && "no space allocated for live registers");
3683d8efa4fSMarina Yatsina       if (LiveRegs[i] == Latest)
3693d8efa4fSMarina Yatsina         kill(i);
3703d8efa4fSMarina Yatsina     }
3713d8efa4fSMarina Yatsina   }
3723d8efa4fSMarina Yatsina 
3733d8efa4fSMarina Yatsina   // dv is the DomainValue we are going to use for this instruction.
3743d8efa4fSMarina Yatsina   if (!dv) {
3753d8efa4fSMarina Yatsina     dv = alloc();
3763d8efa4fSMarina Yatsina     dv->AvailableDomains = available;
3773d8efa4fSMarina Yatsina   }
3783d8efa4fSMarina Yatsina   dv->Instrs.push_back(mi);
3793d8efa4fSMarina Yatsina 
3803d8efa4fSMarina Yatsina   // Finally set all defs and non-collapsed uses to dv. We must iterate through
3813d8efa4fSMarina Yatsina   // all the operators, including imp-def ones.
3823d8efa4fSMarina Yatsina   for (MachineOperand &mo : mi->operands()) {
3833d8efa4fSMarina Yatsina     if (!mo.isReg())
3843d8efa4fSMarina Yatsina       continue;
3853d8efa4fSMarina Yatsina     for (int rx : regIndices(mo.getReg())) {
3863d8efa4fSMarina Yatsina       if (!LiveRegs[rx] || (mo.isDef() && LiveRegs[rx] != dv)) {
3873d8efa4fSMarina Yatsina         kill(rx);
3883d8efa4fSMarina Yatsina         setLiveReg(rx, dv);
3893d8efa4fSMarina Yatsina       }
3903d8efa4fSMarina Yatsina     }
3913d8efa4fSMarina Yatsina   }
3923d8efa4fSMarina Yatsina }
3933d8efa4fSMarina Yatsina 
3943d8efa4fSMarina Yatsina void ExecutionDomainFix::processBasicBlock(
3953d8efa4fSMarina Yatsina     const LoopTraversal::TraversedMBBInfo &TraversedMBB) {
3963d8efa4fSMarina Yatsina   enterBasicBlock(TraversedMBB);
3973d8efa4fSMarina Yatsina   // If this block is not done, it makes little sense to make any decisions
3983d8efa4fSMarina Yatsina   // based on clearance information. We need to make a second pass anyway,
3993d8efa4fSMarina Yatsina   // and by then we'll have better information, so we can avoid doing the work
4003d8efa4fSMarina Yatsina   // to try and break dependencies now.
4013d8efa4fSMarina Yatsina   for (MachineInstr &MI : *TraversedMBB.MBB) {
402801bf7ebSShiva Chen     if (!MI.isDebugInstr()) {
4033d8efa4fSMarina Yatsina       bool Kill = false;
4043d8efa4fSMarina Yatsina       if (TraversedMBB.PrimaryPass)
4053d8efa4fSMarina Yatsina         Kill = visitInstr(&MI);
4063d8efa4fSMarina Yatsina       processDefs(&MI, Kill);
4073d8efa4fSMarina Yatsina     }
4083d8efa4fSMarina Yatsina   }
4093d8efa4fSMarina Yatsina   leaveBasicBlock(TraversedMBB);
4103d8efa4fSMarina Yatsina }
4113d8efa4fSMarina Yatsina 
4123d8efa4fSMarina Yatsina bool ExecutionDomainFix::runOnMachineFunction(MachineFunction &mf) {
4133d8efa4fSMarina Yatsina   if (skipFunction(mf.getFunction()))
4143d8efa4fSMarina Yatsina     return false;
4153d8efa4fSMarina Yatsina   MF = &mf;
4163d8efa4fSMarina Yatsina   TII = MF->getSubtarget().getInstrInfo();
4173d8efa4fSMarina Yatsina   TRI = MF->getSubtarget().getRegisterInfo();
4183d8efa4fSMarina Yatsina   LiveRegs.clear();
4193d8efa4fSMarina Yatsina   assert(NumRegs == RC->getNumRegs() && "Bad regclass");
4203d8efa4fSMarina Yatsina 
421d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "********** FIX EXECUTION DOMAIN: "
4223d8efa4fSMarina Yatsina                     << TRI->getRegClassName(RC) << " **********\n");
4233d8efa4fSMarina Yatsina 
4243d8efa4fSMarina Yatsina   // If no relevant registers are used in the function, we can skip it
4253d8efa4fSMarina Yatsina   // completely.
4263d8efa4fSMarina Yatsina   bool anyregs = false;
4273d8efa4fSMarina Yatsina   const MachineRegisterInfo &MRI = mf.getRegInfo();
4283d8efa4fSMarina Yatsina   for (unsigned Reg : *RC) {
4293d8efa4fSMarina Yatsina     if (MRI.isPhysRegUsed(Reg)) {
4303d8efa4fSMarina Yatsina       anyregs = true;
4313d8efa4fSMarina Yatsina       break;
4323d8efa4fSMarina Yatsina     }
4333d8efa4fSMarina Yatsina   }
4343d8efa4fSMarina Yatsina   if (!anyregs)
4353d8efa4fSMarina Yatsina     return false;
4363d8efa4fSMarina Yatsina 
4373d8efa4fSMarina Yatsina   RDA = &getAnalysis<ReachingDefAnalysis>();
4383d8efa4fSMarina Yatsina 
4393d8efa4fSMarina Yatsina   // Initialize the AliasMap on the first use.
4403d8efa4fSMarina Yatsina   if (AliasMap.empty()) {
4413d8efa4fSMarina Yatsina     // Given a PhysReg, AliasMap[PhysReg] returns a list of indices into RC and
4423d8efa4fSMarina Yatsina     // therefore the LiveRegs array.
4433d8efa4fSMarina Yatsina     AliasMap.resize(TRI->getNumRegs());
4443d8efa4fSMarina Yatsina     for (unsigned i = 0, e = RC->getNumRegs(); i != e; ++i)
4453d8efa4fSMarina Yatsina       for (MCRegAliasIterator AI(RC->getRegister(i), TRI, true); AI.isValid();
4463d8efa4fSMarina Yatsina            ++AI)
4473d8efa4fSMarina Yatsina         AliasMap[*AI].push_back(i);
4483d8efa4fSMarina Yatsina   }
4493d8efa4fSMarina Yatsina 
4503d8efa4fSMarina Yatsina   // Initialize the MBBOutRegsInfos
4513d8efa4fSMarina Yatsina   MBBOutRegsInfos.resize(mf.getNumBlockIDs());
4523d8efa4fSMarina Yatsina 
4533d8efa4fSMarina Yatsina   // Traverse the basic blocks.
4543d8efa4fSMarina Yatsina   LoopTraversal Traversal;
4553d8efa4fSMarina Yatsina   LoopTraversal::TraversalOrder TraversedMBBOrder = Traversal.traverse(mf);
4563d8efa4fSMarina Yatsina   for (LoopTraversal::TraversedMBBInfo TraversedMBB : TraversedMBBOrder) {
4573d8efa4fSMarina Yatsina     processBasicBlock(TraversedMBB);
4583d8efa4fSMarina Yatsina   }
4593d8efa4fSMarina Yatsina 
4603d8efa4fSMarina Yatsina   for (LiveRegsDVInfo OutLiveRegs : MBBOutRegsInfos) {
4613d8efa4fSMarina Yatsina     for (DomainValue *OutLiveReg : OutLiveRegs) {
4623d8efa4fSMarina Yatsina       if (OutLiveReg)
4633d8efa4fSMarina Yatsina         release(OutLiveReg);
4643d8efa4fSMarina Yatsina     }
4653d8efa4fSMarina Yatsina   }
4663d8efa4fSMarina Yatsina   MBBOutRegsInfos.clear();
4673d8efa4fSMarina Yatsina   Avail.clear();
4683d8efa4fSMarina Yatsina   Allocator.DestroyAll();
4693d8efa4fSMarina Yatsina 
4703d8efa4fSMarina Yatsina   return false;
4713d8efa4fSMarina Yatsina }
472