16#define DEBUG_TYPE "execution-deps-fix"
19ExecutionDomainFix::regIndices(
unsigned Reg)
const {
20 assert(Reg < AliasMap.size() &&
"Invalid register");
21 const auto &Entry = AliasMap[Reg];
27 : Avail.pop_back_val();
30 assert(dv->
Refs == 0 &&
"Reference count wasn't cleared");
31 assert(!dv->
Next &&
"Chained DomainValue shouldn't have been recycled");
70void ExecutionDomainFix::setLiveReg(
int rx,
DomainValue *dv) {
71 assert(
unsigned(rx) < NumRegs &&
"Invalid index");
72 assert(!LiveRegs.empty() &&
"Must enter basic block first.");
74 if (LiveRegs[rx] == dv)
78 LiveRegs[rx] = retain(dv);
81void ExecutionDomainFix::kill(
int rx) {
82 assert(
unsigned(rx) < NumRegs &&
"Invalid index");
83 assert(!LiveRegs.empty() &&
"Must enter basic block first.");
88 LiveRegs[rx] =
nullptr;
91void ExecutionDomainFix::force(
int rx,
unsigned domain) {
92 assert(
unsigned(rx) < NumRegs &&
"Invalid index");
93 assert(!LiveRegs.empty() &&
"Must enter basic block first.");
103 assert(LiveRegs[rx] &&
"Not live after collapse?");
104 LiveRegs[rx]->addDomain(domain);
108 setLiveReg(rx, alloc(domain));
112void ExecutionDomainFix::collapse(
DomainValue *dv,
unsigned domain) {
116 while (!dv->
Instrs.empty())
121 if (!LiveRegs.empty() && dv->
Refs > 1)
122 for (
unsigned rx = 0; rx != NumRegs; ++rx)
123 if (LiveRegs[rx] == dv)
124 setLiveReg(rx, alloc(domain));
128 assert(!
A->isCollapsed() &&
"Cannot merge into collapsed");
129 assert(!
B->isCollapsed() &&
"Cannot merge from collapsed");
133 unsigned common =
A->getCommonDomains(
B->AvailableDomains);
136 A->AvailableDomains = common;
137 A->Instrs.append(
B->Instrs.begin(),
B->Instrs.end());
144 for (
unsigned rx = 0; rx != NumRegs; ++rx) {
145 assert(!LiveRegs.empty() &&
"no space allocated for live registers");
146 if (LiveRegs[rx] ==
B)
152void ExecutionDomainFix::enterBasicBlock(
159 if (LiveRegs.empty())
160 LiveRegs.assign(NumRegs,
nullptr);
171 "Should have pre-allocated MBBInfos for all MBBs");
172 LiveRegsDVInfo &
Incoming = MBBOutRegsInfos[
pred->getNumber()];
178 for (
unsigned rx = 0; rx != NumRegs; ++rx) {
188 if (LiveRegs[rx]->isCollapsed()) {
190 unsigned Domain = LiveRegs[rx]->getFirstDomain();
198 merge(LiveRegs[rx], pdv);
204 << (!TraversedMBB.
IsDone ?
": incomplete\n"
205 :
": all preds known\n"));
208void ExecutionDomainFix::leaveBasicBlock(
210 assert(!LiveRegs.empty() &&
"Must enter basic block first.");
213 "Unexpected basic block number.");
215 for (
DomainValue *OldLiveReg : MBBOutRegsInfos[MBBNumber]) {
218 MBBOutRegsInfos[MBBNumber] = LiveRegs;
227 visitSoftInstr(
MI, DomP.second);
229 visitHardInstr(
MI, DomP.first);
235void ExecutionDomainFix::processDefs(
MachineInstr *
MI,
bool Kill) {
236 assert(!
MI->isDebugInstr() &&
"Won't process debug values");
246 for (
int rx : regIndices(MO.
getReg())) {
257void ExecutionDomainFix::visitHardInstr(
MachineInstr *mi,
unsigned domain) {
265 for (
int rx : regIndices(mo.
getReg())) {
275 for (
int rx : regIndices(mo.
getReg())) {
282void ExecutionDomainFix::visitSoftInstr(
MachineInstr *mi,
unsigned mask) {
289 if (!LiveRegs.empty())
296 for (
int rx : regIndices(mo.
getReg())) {
323 visitHardInstr(mi, domain);
330 for (
int rx : used) {
331 assert(!LiveRegs.empty() &&
"no space allocated for live registers");
350 while (!Regs.
empty()) {
361 if (Latest == dv || Latest->
Next)
363 if (merge(dv, Latest))
368 assert(!LiveRegs.empty() &&
"no space allocated for live registers");
369 if (LiveRegs[i] == Latest)
386 for (
int rx : regIndices(mo.
getReg())) {
387 if (!LiveRegs[rx] || (mo.
isDef() && LiveRegs[rx] != dv)) {
395void ExecutionDomainFix::processBasicBlock(
397 enterBasicBlock(TraversedMBB);
403 if (!
MI.isDebugInstr()) {
407 processDefs(&
MI, Kill);
410 leaveBasicBlock(TraversedMBB);
427 bool anyregs =
false;
429 for (
unsigned Reg : *RC) {
430 if (
MRI.isPhysRegUsed(Reg)) {
438 RDA = &getAnalysis<ReachingDefAnalysis>();
441 if (AliasMap.empty()) {
445 for (
unsigned i = 0, e = RC->getNumRegs(); i != e; ++i)
448 AliasMap[*AI].push_back(i);
458 processBasicBlock(TraversedMBB);
460 for (
const LiveRegsDVInfo &OutLiveRegs : MBBOutRegsInfos)
465 MBBOutRegsInfos.clear();
467 Allocator.DestroyAll();
unsigned const MachineRegisterInfo * MRI
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
return !LiveInRegUnits available(Reg)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
This class provides the basic blocks traversal order used by passes like ReachingDefAnalysis and Exec...
TraversalOrder traverse(MachineFunction &MF)
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
MCRegAliasIterator enumerates all registers aliasing Reg.
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
iterator_range< pred_iterator > predecessors()
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
Representation of each machine instruction.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
iterator_range< mop_iterator > operands()
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
int getReachingDef(MachineInstr *MI, MCRegister PhysReg) const
Provides the instruction id of the closest reaching def instruction of PhysReg that reaches MI,...
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
virtual std::pair< uint16_t, uint16_t > getExecutionDomain(const MachineInstr &MI) const
Return the current execution domain and bit mask of possible domains for instruction.
virtual void setExecutionDomain(MachineInstr &MI, unsigned Domain) const
Change the opcode of MI to execute in Domain.
unsigned getNumRegs() const
Return the number of registers in this class.
MCRegister getRegister(unsigned i) const
Return the specified register in the class.
const char * getRegClassName(const TargetRegisterClass *Class) const
Returns the name of the register class.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
A range adaptor for a pair of iterators.
@ Kill
The last use of a register.
NodeAddr< DefNode * > Def
This is an optimization pass for GlobalISel generic memory operations.
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
auto mask(ShuffFunc S, unsigned Length, OptArgs... args) -> MaskT
A DomainValue is a bit like LiveIntervals' ValNo, but it also keeps track of execution domains.
unsigned getCommonDomains(unsigned mask) const
Return bitmask of domains that are available and in mask.
void clear()
Clear this DomainValue and point to next which has all its data.
SmallVector< MachineInstr *, 8 > Instrs
Twiddleable instructions using or defining these registers.
void setSingleDomain(unsigned domain)
bool isCollapsed() const
A collapsed DomainValue has no instructions to twiddle - it simply keeps track of the domains where t...
DomainValue * Next
Pointer to the next DomainValue in a chain.
void addDomain(unsigned domain)
Mark domain as available.
unsigned AvailableDomains
Bitmask of available domains.
unsigned Refs
Basic reference counting.
unsigned getFirstDomain() const
First domain available.
bool hasDomain(unsigned domain) const
Is domain available?
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
MachineBasicBlock * MBB
The basic block.
bool IsDone
True if the block that is ready for its final round of processing.
bool PrimaryPass
True if this is the first time we process the basic block.