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