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"
12904cd3e0SReid Kleckner #include "llvm/Support/Debug.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>
regIndices(unsigned Reg) const193d8efa4fSMarina 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
alloc(int domain)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
release(DomainValue * DV)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
resolve(DomainValue * & DVRef)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
setLiveReg(int rx,DomainValue * dv)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
kill(int rx)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
force(int rx,unsigned domain)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
collapse(DomainValue * dv,unsigned domain)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
merge(DomainValue * A,DomainValue * B)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
enterBasicBlock(const LoopTraversal::TraversedMBBInfo & TraversedMBB)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()) {
164d34e60caSNicola Zaghen LLVM_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 }
203d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << printMBBReference(*MBB)
2043d8efa4fSMarina Yatsina << (!TraversedMBB.IsDone ? ": incomplete\n"
2053d8efa4fSMarina Yatsina : ": all preds known\n"));
2063d8efa4fSMarina Yatsina }
2073d8efa4fSMarina Yatsina
leaveBasicBlock(const LoopTraversal::TraversedMBBInfo & TraversedMBB)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
visitInstr(MachineInstr * MI)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
processDefs(MachineInstr * MI,bool Kill)2353d8efa4fSMarina Yatsina void ExecutionDomainFix::processDefs(MachineInstr *MI, bool Kill) {
236801bf7ebSShiva 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.
248d34e60caSNicola Zaghen LLVM_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
visitHardInstr(MachineInstr * mi,unsigned domain)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
visitSoftInstr(MachineInstr * mi,unsigned mask)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.
340d3b26823SFangrui Song const int Def = RDA->getReachingDef(mi, RC->getRegister(rx));
34178ee2fbfSFangrui Song auto I = partition_point(Regs, [&](int I) {
34278ee2fbfSFangrui Song return RDA->getReachingDef(mi, RC->getRegister(I)) <= Def;
3433d8efa4fSMarina Yatsina });
3443d8efa4fSMarina Yatsina Regs.insert(I, rx);
3453d8efa4fSMarina Yatsina }
3463d8efa4fSMarina Yatsina
3473d8efa4fSMarina Yatsina // doms are now sorted in order of appearance. Try to merge them all, giving
3483d8efa4fSMarina Yatsina // priority to the latest ones.
3493d8efa4fSMarina Yatsina DomainValue *dv = nullptr;
3503d8efa4fSMarina Yatsina while (!Regs.empty()) {
3513d8efa4fSMarina Yatsina if (!dv) {
3523d8efa4fSMarina Yatsina dv = LiveRegs[Regs.pop_back_val()];
3533d8efa4fSMarina Yatsina // Force the first dv to match the current instruction.
3543d8efa4fSMarina Yatsina dv->AvailableDomains = dv->getCommonDomains(available);
3553d8efa4fSMarina Yatsina assert(dv->AvailableDomains && "Domain should have been filtered");
3563d8efa4fSMarina Yatsina continue;
3573d8efa4fSMarina Yatsina }
3583d8efa4fSMarina Yatsina
3593d8efa4fSMarina Yatsina DomainValue *Latest = LiveRegs[Regs.pop_back_val()];
3603d8efa4fSMarina Yatsina // Skip already merged values.
3613d8efa4fSMarina Yatsina if (Latest == dv || Latest->Next)
3623d8efa4fSMarina Yatsina continue;
3633d8efa4fSMarina Yatsina if (merge(dv, Latest))
3643d8efa4fSMarina Yatsina continue;
3653d8efa4fSMarina Yatsina
3663d8efa4fSMarina Yatsina // If latest didn't merge, it is useless now. Kill all registers using it.
3673d8efa4fSMarina Yatsina for (int i : used) {
3683d8efa4fSMarina Yatsina assert(!LiveRegs.empty() && "no space allocated for live registers");
3693d8efa4fSMarina Yatsina if (LiveRegs[i] == Latest)
3703d8efa4fSMarina Yatsina kill(i);
3713d8efa4fSMarina Yatsina }
3723d8efa4fSMarina Yatsina }
3733d8efa4fSMarina Yatsina
3743d8efa4fSMarina Yatsina // dv is the DomainValue we are going to use for this instruction.
3753d8efa4fSMarina Yatsina if (!dv) {
3763d8efa4fSMarina Yatsina dv = alloc();
3773d8efa4fSMarina Yatsina dv->AvailableDomains = available;
3783d8efa4fSMarina Yatsina }
3793d8efa4fSMarina Yatsina dv->Instrs.push_back(mi);
3803d8efa4fSMarina Yatsina
3813d8efa4fSMarina Yatsina // Finally set all defs and non-collapsed uses to dv. We must iterate through
3823d8efa4fSMarina Yatsina // all the operators, including imp-def ones.
383*5ded5ab7SSimon Pilgrim for (const MachineOperand &mo : mi->operands()) {
3843d8efa4fSMarina Yatsina if (!mo.isReg())
3853d8efa4fSMarina Yatsina continue;
3863d8efa4fSMarina Yatsina for (int rx : regIndices(mo.getReg())) {
3873d8efa4fSMarina Yatsina if (!LiveRegs[rx] || (mo.isDef() && LiveRegs[rx] != dv)) {
3883d8efa4fSMarina Yatsina kill(rx);
3893d8efa4fSMarina Yatsina setLiveReg(rx, dv);
3903d8efa4fSMarina Yatsina }
3913d8efa4fSMarina Yatsina }
3923d8efa4fSMarina Yatsina }
3933d8efa4fSMarina Yatsina }
3943d8efa4fSMarina Yatsina
processBasicBlock(const LoopTraversal::TraversedMBBInfo & TraversedMBB)3953d8efa4fSMarina Yatsina void ExecutionDomainFix::processBasicBlock(
3963d8efa4fSMarina Yatsina const LoopTraversal::TraversedMBBInfo &TraversedMBB) {
3973d8efa4fSMarina Yatsina enterBasicBlock(TraversedMBB);
3983d8efa4fSMarina Yatsina // If this block is not done, it makes little sense to make any decisions
3993d8efa4fSMarina Yatsina // based on clearance information. We need to make a second pass anyway,
4003d8efa4fSMarina Yatsina // and by then we'll have better information, so we can avoid doing the work
4013d8efa4fSMarina Yatsina // to try and break dependencies now.
4023d8efa4fSMarina Yatsina for (MachineInstr &MI : *TraversedMBB.MBB) {
403801bf7ebSShiva Chen if (!MI.isDebugInstr()) {
4043d8efa4fSMarina Yatsina bool Kill = false;
4053d8efa4fSMarina Yatsina if (TraversedMBB.PrimaryPass)
4063d8efa4fSMarina Yatsina Kill = visitInstr(&MI);
4073d8efa4fSMarina Yatsina processDefs(&MI, Kill);
4083d8efa4fSMarina Yatsina }
4093d8efa4fSMarina Yatsina }
4103d8efa4fSMarina Yatsina leaveBasicBlock(TraversedMBB);
4113d8efa4fSMarina Yatsina }
4123d8efa4fSMarina Yatsina
runOnMachineFunction(MachineFunction & mf)4133d8efa4fSMarina Yatsina bool ExecutionDomainFix::runOnMachineFunction(MachineFunction &mf) {
4143d8efa4fSMarina Yatsina if (skipFunction(mf.getFunction()))
4153d8efa4fSMarina Yatsina return false;
4163d8efa4fSMarina Yatsina MF = &mf;
4173d8efa4fSMarina Yatsina TII = MF->getSubtarget().getInstrInfo();
4183d8efa4fSMarina Yatsina TRI = MF->getSubtarget().getRegisterInfo();
4193d8efa4fSMarina Yatsina LiveRegs.clear();
4203d8efa4fSMarina Yatsina assert(NumRegs == RC->getNumRegs() && "Bad regclass");
4213d8efa4fSMarina Yatsina
422d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "********** FIX EXECUTION DOMAIN: "
4233d8efa4fSMarina Yatsina << TRI->getRegClassName(RC) << " **********\n");
4243d8efa4fSMarina Yatsina
4253d8efa4fSMarina Yatsina // If no relevant registers are used in the function, we can skip it
4263d8efa4fSMarina Yatsina // completely.
4273d8efa4fSMarina Yatsina bool anyregs = false;
4283d8efa4fSMarina Yatsina const MachineRegisterInfo &MRI = mf.getRegInfo();
4293d8efa4fSMarina Yatsina for (unsigned Reg : *RC) {
4303d8efa4fSMarina Yatsina if (MRI.isPhysRegUsed(Reg)) {
4313d8efa4fSMarina Yatsina anyregs = true;
4323d8efa4fSMarina Yatsina break;
4333d8efa4fSMarina Yatsina }
4343d8efa4fSMarina Yatsina }
4353d8efa4fSMarina Yatsina if (!anyregs)
4363d8efa4fSMarina Yatsina return false;
4373d8efa4fSMarina Yatsina
4383d8efa4fSMarina Yatsina RDA = &getAnalysis<ReachingDefAnalysis>();
4393d8efa4fSMarina Yatsina
4403d8efa4fSMarina Yatsina // Initialize the AliasMap on the first use.
4413d8efa4fSMarina Yatsina if (AliasMap.empty()) {
4423d8efa4fSMarina Yatsina // Given a PhysReg, AliasMap[PhysReg] returns a list of indices into RC and
4433d8efa4fSMarina Yatsina // therefore the LiveRegs array.
4443d8efa4fSMarina Yatsina AliasMap.resize(TRI->getNumRegs());
4453d8efa4fSMarina Yatsina for (unsigned i = 0, e = RC->getNumRegs(); i != e; ++i)
4463d8efa4fSMarina Yatsina for (MCRegAliasIterator AI(RC->getRegister(i), TRI, true); AI.isValid();
4473d8efa4fSMarina Yatsina ++AI)
4483d8efa4fSMarina Yatsina AliasMap[*AI].push_back(i);
4493d8efa4fSMarina Yatsina }
4503d8efa4fSMarina Yatsina
4513d8efa4fSMarina Yatsina // Initialize the MBBOutRegsInfos
4523d8efa4fSMarina Yatsina MBBOutRegsInfos.resize(mf.getNumBlockIDs());
4533d8efa4fSMarina Yatsina
4543d8efa4fSMarina Yatsina // Traverse the basic blocks.
4553d8efa4fSMarina Yatsina LoopTraversal Traversal;
4563d8efa4fSMarina Yatsina LoopTraversal::TraversalOrder TraversedMBBOrder = Traversal.traverse(mf);
457*5ded5ab7SSimon Pilgrim for (const LoopTraversal::TraversedMBBInfo &TraversedMBB : TraversedMBBOrder)
4583d8efa4fSMarina Yatsina processBasicBlock(TraversedMBB);
4593d8efa4fSMarina Yatsina
460*5ded5ab7SSimon Pilgrim for (const LiveRegsDVInfo &OutLiveRegs : MBBOutRegsInfos)
461*5ded5ab7SSimon Pilgrim for (DomainValue *OutLiveReg : OutLiveRegs)
4623d8efa4fSMarina Yatsina if (OutLiveReg)
4633d8efa4fSMarina Yatsina release(OutLiveReg);
464*5ded5ab7SSimon Pilgrim
4653d8efa4fSMarina Yatsina MBBOutRegsInfos.clear();
4663d8efa4fSMarina Yatsina Avail.clear();
4673d8efa4fSMarina Yatsina Allocator.DestroyAll();
4683d8efa4fSMarina Yatsina
4693d8efa4fSMarina Yatsina return false;
4703d8efa4fSMarina Yatsina }
471