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