15 #define DEBUG_TYPE "execution-deps-fix" 18 ExecutionDomainFix::regIndices(
unsigned Reg)
const {
19 assert(Reg < AliasMap.size() &&
"Invalid register");
20 const auto &Entry = AliasMap[
Reg];
24 DomainValue *ExecutionDomainFix::alloc(
int domain) {
26 : Avail.pop_back_val();
29 assert(dv->
Refs == 0 &&
"Reference count wasn't cleared");
30 assert(!dv->
Next &&
"Chained DomainValue shouldn't have been recycled");
69 void ExecutionDomainFix::setLiveReg(
int rx,
DomainValue *dv) {
70 assert(
unsigned(rx) < NumRegs &&
"Invalid index");
71 assert(!LiveRegs.empty() &&
"Must enter basic block first.");
73 if (LiveRegs[rx] == dv)
76 release(LiveRegs[rx]);
77 LiveRegs[rx] = retain(dv);
80 void ExecutionDomainFix::kill(
int rx) {
81 assert(
unsigned(rx) < NumRegs &&
"Invalid index");
82 assert(!LiveRegs.empty() &&
"Must enter basic block first.");
86 release(LiveRegs[rx]);
87 LiveRegs[rx] =
nullptr;
90 void ExecutionDomainFix::force(
int rx,
unsigned domain) {
91 assert(
unsigned(rx) < NumRegs &&
"Invalid index");
92 assert(!LiveRegs.empty() &&
"Must enter basic block first.");
102 assert(LiveRegs[rx] &&
"Not live after collapse?");
103 LiveRegs[rx]->addDomain(domain);
107 setLiveReg(rx, alloc(domain));
111 void ExecutionDomainFix::collapse(
DomainValue *dv,
unsigned domain) {
115 while (!dv->
Instrs.empty())
120 if (!LiveRegs.empty() && dv->
Refs > 1)
121 for (
unsigned rx = 0; rx != NumRegs; ++rx)
122 if (LiveRegs[rx] == dv)
123 setLiveReg(rx, alloc(domain));
143 for (
unsigned rx = 0; rx != NumRegs; ++rx) {
144 assert(!LiveRegs.empty() &&
"no space allocated for live registers");
145 if (LiveRegs[rx] == B)
151 void ExecutionDomainFix::enterBasicBlock(
158 if (LiveRegs.empty())
159 LiveRegs.assign(NumRegs,
nullptr);
170 "Should have pre-allocated MBBInfos for all MBBs");
171 LiveRegsDVInfo &Incoming = MBBOutRegsInfos[
pred->getNumber()];
174 if (Incoming.empty())
177 for (
unsigned rx = 0; rx != NumRegs; ++rx) {
187 if (LiveRegs[rx]->isCollapsed()) {
189 unsigned Domain = LiveRegs[rx]->getFirstDomain();
191 collapse(pdv, Domain);
197 merge(LiveRegs[rx], pdv);
203 << (!TraversedMBB.
IsDone ?
": incomplete\n" 204 :
": all preds known\n"));
207 void ExecutionDomainFix::leaveBasicBlock(
209 assert(!LiveRegs.empty() &&
"Must enter basic block first.");
212 "Unexpected basic block number.");
214 for (
DomainValue *OldLiveReg : MBBOutRegsInfos[MBBNumber]) {
217 MBBOutRegsInfos[MBBNumber] = LiveRegs;
226 visitSoftInstr(MI, DomP.second);
228 visitHardInstr(MI, DomP.first);
245 for (
int rx : regIndices(MO.
getReg())) {
256 void ExecutionDomainFix::visitHardInstr(
MachineInstr *mi,
unsigned domain) {
264 for (
int rx : regIndices(mo.
getReg())) {
274 for (
int rx : regIndices(mo.
getReg())) {
281 void ExecutionDomainFix::visitSoftInstr(
MachineInstr *mi,
unsigned mask) {
288 if (!LiveRegs.empty())
295 for (
int rx : regIndices(mo.
getReg())) {
322 visitHardInstr(mi, domain);
329 for (
int rx : used) {
330 assert(!LiveRegs.empty() &&
"no space allocated for live registers");
333 if (!LR->getCommonDomains(available)) {
340 Regs.
begin(), Regs.
end(), rx, [&](
int LHS,
const int RHS) {
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)) {
395 void ExecutionDomainFix::processBasicBlock(
397 enterBasicBlock(TraversedMBB);
406 Kill = visitInstr(&MI);
407 processDefs(&MI, Kill);
410 leaveBasicBlock(TraversedMBB);
427 bool anyregs =
false;
429 for (
unsigned Reg : *RC) {
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);
461 for (LiveRegsDVInfo OutLiveRegs : MBBOutRegsInfos) {
467 MBBOutRegsInfos.clear();
469 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.
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.
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