Go to the documentation of this file.
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));
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)
152 void ExecutionDomainFix::enterBasicBlock(
159 if (LiveRegs.empty())
160 LiveRegs.assign(NumRegs,
nullptr);
170 assert(
unsigned(
pred->getNumber()) < MBBOutRegsInfos.size() &&
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();
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.");
212 assert(MBBNumber < MBBOutRegsInfos.size() &&
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);
236 assert(!
MI->isDebugInstr() &&
"Won't process debug values");
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");
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);
403 if (!
MI.isDebugInstr()) {
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);
460 for (
const LiveRegsDVInfo &OutLiveRegs : MBBOutRegsInfos)
465 MBBOutRegsInfos.clear();
467 Allocator.DestroyAll();
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
bool PrimaryPass
True if this is the first time we process the basic block.
This is an optimization pass for GlobalISel generic memory operations.
bool isPhysRegUsed(MCRegister PhysReg, bool SkipRegMaskTest=false) const
Return true if the specified register is modified or read in this function.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void addDomain(unsigned domain)
Mark domain as available.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
virtual const TargetInstrInfo * getInstrInfo() const
unsigned Refs
Basic reference counting.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
void clear()
Clear this DomainValue and point to next which has all its data.
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
Reg
All possible values of the reg field in the ModR/M byte.
unsigned getCommonDomains(unsigned mask) const
Return bitmask of domains that are available and in mask.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
This class provides the basic blocks traversal order used by passes like ReachingDefAnalysis and Exec...
LLVM_NODISCARD T pop_back_val()
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
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.
unsigned AvailableDomains
Bitmask of available domains.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
This requires reassociating to forms of expressions that are already available
const MachineOperand & getOperand(unsigned i) const
@ Kill
The last use of a register.
Describe properties that are true of each instruction in the target description file.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MachineOperand class - Representation of each machine instruction operand.
DomainValue * Next
Pointer to the next DomainValue in a chain.
bool hasDomain(unsigned domain) const
Is domain available?
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
A DomainValue is a bit like LiveIntervals' ValNo, but it also keeps track of execution domains.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Representation of each machine instruction.
int getReachingDef(MachineInstr *MI, MCRegister PhysReg) const
Provides the instruction id of the closest reaching def instruction of PhysReg that reaches MI,...
const char * getRegClassName(const TargetRegisterClass *Class) const
Returns the name of the register class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void setSingleDomain(unsigned domain)
Register getReg() const
getReg - Returns the register number.
iterator_range< pred_iterator > predecessors()
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
unsigned 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.
TraversalOrder traverse(MachineFunction &MF)
unsigned const MachineRegisterInfo * MRI
SmallVector< MachineInstr *, 8 > Instrs
Twiddleable instructions using or defining these registers.
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
unsigned getNumRegs() const
Return the number of registers in this class.
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.
Function & getFunction()
Return the LLVM function that this machine code represents.
MCRegister getRegister(unsigned i) const
Return the specified register in the class.
bool IsDone
True if the block that is ready for its final round of processing.
MachineBasicBlock * MBB
The basic block.
This might compile to this xmm1 xorps xmm0 movss xmm0 ret Now consider if the code caused xmm1 to get spilled This might produce this xmm1 movaps xmm0 movaps xmm1 movss xmm0 ret since the reload is only used by these we could fold it into the producing something like xmm1 movaps xmm0 ret saving two instructions The basic idea is that a reload from a spill if only one byte chunk is used
A range adaptor for a pair of iterators.
virtual void setExecutionDomain(MachineInstr &MI, unsigned Domain) const
Change the opcode of MI to execute in Domain.
unsigned getFirstDomain() const
First domain available.
bool isCollapsed() const
A collapsed DomainValue has no instructions to twiddle - it simply keeps track of the domains where t...
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.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
iterator_range< mop_iterator > operands()
MCRegAliasIterator enumerates all registers aliasing Reg.
iterator insert(iterator I, T &&Elt)