16 #define DEBUG_TYPE "execution-deps-fix" 19 ExecutionDomainFix::regIndices(
unsigned Reg)
const {
20 assert(Reg < AliasMap.size() &&
"Invalid register");
21 const auto &Entry = AliasMap[
Reg];
25 DomainValue *ExecutionDomainFix::alloc(
int domain) {
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");
70 void 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)
77 release(LiveRegs[rx]);
78 LiveRegs[rx] = retain(dv);
81 void ExecutionDomainFix::kill(
int rx) {
82 assert(
unsigned(rx) < NumRegs &&
"Invalid index");
83 assert(!LiveRegs.empty() &&
"Must enter basic block first.");
87 release(LiveRegs[rx]);
88 LiveRegs[rx] =
nullptr;
91 void 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));
112 void 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));
144 for (
unsigned rx = 0; rx != NumRegs; ++rx) {
145 assert(!LiveRegs.empty() &&
"no space allocated for live registers");
146 if (LiveRegs[rx] == B)
152 void 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()];
175 if (Incoming.empty())
178 for (
unsigned rx = 0; rx != NumRegs; ++rx) {
188 if (LiveRegs[rx]->isCollapsed()) {
190 unsigned Domain = LiveRegs[rx]->getFirstDomain();
192 collapse(pdv, Domain);
198 merge(LiveRegs[rx], pdv);
204 << (!TraversedMBB.
IsDone ?
": incomplete\n" 205 :
": all preds known\n"));
208 void 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);
246 for (
int rx : regIndices(MO.
getReg())) {
257 void ExecutionDomainFix::visitHardInstr(
MachineInstr *mi,
unsigned domain) {
265 for (
int rx : regIndices(mo.
getReg())) {
275 for (
int rx : regIndices(mo.
getReg())) {
282 void 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");
334 if (!LR->getCommonDomains(available)) {
341 Regs.
begin(), Regs.
end(), rx, [&](
int LHS,
const int RHS) {
351 while (!Regs.
empty()) {
362 if (Latest == dv || Latest->
Next)
364 if (merge(dv, Latest))
369 assert(!LiveRegs.empty() &&
"no space allocated for live registers");
370 if (LiveRegs[i] == Latest)
387 for (
int rx : regIndices(mo.getReg())) {
388 if (!LiveRegs[rx] || (mo.isDef() && LiveRegs[rx] != dv)) {
396 void ExecutionDomainFix::processBasicBlock(
398 enterBasicBlock(TraversedMBB);
407 Kill = visitInstr(&MI);
408 processDefs(&MI, Kill);
411 leaveBasicBlock(TraversedMBB);
428 bool anyregs =
false;
430 for (
unsigned Reg : *RC) {
439 RDA = &getAnalysis<ReachingDefAnalysis>();
442 if (AliasMap.empty()) {
446 for (
unsigned i = 0, e = RC->getNumRegs(); i != e; ++i)
449 AliasMap[*AI].push_back(i);
459 processBasicBlock(TraversedMBB);
462 for (LiveRegsDVInfo OutLiveRegs : MBBOutRegsInfos) {
468 MBBOutRegsInfos.clear();
470 Allocator.DestroyAll();
unsigned getCommonDomains(unsigned mask) const
Return bitmask of domains that are available and in mask.
void addDomain(unsigned domain)
Mark domain as available.
This class represents lattice values for constants.
unsigned getNumRegs() const
Return the number of registers in this class.
virtual void setExecutionDomain(MachineInstr &MI, unsigned Domain) const
Change the opcode of MI to execute in Domain.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
bool PrimaryPass
True if this is the first time we process the basic block.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
unsigned getRegister(unsigned i) const
Return the specified register in the class.
void push_back(const T &Elt)
Describe properties that are true of each instruction in the target description file.
unsigned getFirstDomain() const
First domain available.
unsigned getReg() const
getReg - Returns the register number.
unsigned AvailableDomains
Bitmask of available domains.
iterator_range< mop_iterator > operands()
const char * getRegClassName(const TargetRegisterClass *Class) const
Returns the name of the register class.
void clear()
Clear this DomainValue and point to next which has all its data.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
unsigned getNumOperands() const
Retuns the total number of operands.
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
DomainValue * Next
Pointer to the next DomainValue in a chain.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
virtual const TargetInstrInfo * getInstrInfo() const
return !LiveInRegUnits available(Reg)
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
bool hasDomain(unsigned domain) const
Is domain available?
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
unsigned const MachineRegisterInfo * MRI
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
MCRegAliasIterator enumerates all registers aliasing Reg.
iterator_range< pred_iterator > predecessors()
bool isDebugInstr() const
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
MachineOperand class - Representation of each machine instruction operand.
void setSingleDomain(unsigned domain)
LLVM_NODISCARD T pop_back_val()
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
bool isVariadic(QueryType Type=IgnoreBundle) const
Return true if this instruction can have a variable number of operands.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isPhysRegUsed(unsigned PhysReg) const
Return true if the specified register is modified or read in this function.
A range adaptor for a pair of iterators.
iterator insert(iterator I, T &&Elt)
A DomainValue is a bit like LiveIntervals' ValNo, but it also keeps track of execution domains...
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
LLVM_NODISCARD bool empty() const
SmallVector< MachineInstr *, 8 > Instrs
Twiddleable instructions using or defining these registers.
TraversalOrder traverse(MachineFunction &MF)
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.
This class provides the basic blocks traversal order used by passes like ReachingDefAnalysis and Exec...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
auto upper_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range))
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
int getReachingDef(MachineInstr *MI, int PhysReg)
Provides the instruction id of the closest reaching def instruction of PhysReg that reaches MI...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachineBasicBlock * MBB
The basic block.
unsigned Refs
Basic reference counting.
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
bool IsDone
True if the block that is ready for its final round of processing.
bool isCollapsed() const
A collapsed DomainValue has no instructions to twiddle - it simply keeps track of the domains where t...
const MachineOperand & getOperand(unsigned i) const