24#define DEBUG_TYPE "si-form-memory-clauses"
30 cl::desc(
"Maximum length of a memory clause, instructions"));
48 return "SI Form memory clauses";
59 MachineFunctionProperties::Property::IsSSA);
64 const RegUse &
Uses)
const;
75 unsigned LastRecordedOccupancy;
83 "SI Form memory clauses",
false,
false)
89char SIFormMemoryClauses::
ID = 0;
94 return new SIFormMemoryClauses();
108 assert(!
MI.isDebugInstr() &&
"debug instructions should not reach here");
111 if (!
MI.mayLoad() ||
MI.mayStore())
123 if (MO.getReg() == ResReg)
150bool SIFormMemoryClauses::canBundle(
const MachineInstr &
MI,
const RegUse &Defs,
151 const RegUse &
Uses)
const {
168 const RegUse &
Map = MO.isDef() ?
Uses : Defs;
169 auto Conflict =
Map.find(Reg);
170 if (Conflict ==
Map.end())
173 if (
Reg.isPhysical())
177 if ((Conflict->second.second & Mask).any())
206 if (Occupancy >= MFI->getMinAllowedOccupancy() &&
207 MaxPressure.
getVGPRNum(
ST->hasGFX90AInsts()) <= MaxVGPRs / 2 &&
209 LastRecordedOccupancy = Occupancy;
217 RegUse &Defs, RegUse &
Uses)
const {
226 ?
TRI->getSubRegIndexLaneMask(MO.getSubReg())
228 RegUse &
Map = MO.isDef() ? Defs :
Uses;
231 auto [Loc,
Inserted] =
Map.try_emplace(Reg, State, Mask);
233 Loc->second.first |= State;
234 Loc->second.second |=
Mask;
243 RegUse &Defs, RegUse &
Uses,
245 if (!canBundle(
MI, Defs,
Uses))
248 if (!checkPressure(
MI, RPT))
251 collectRegUses(
MI, Defs,
Uses);
260 if (!
ST->isXNACKEnabled())
264 TRI =
ST->getRegisterInfo();
267 LiveIntervals *LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
269 bool Changed =
false;
271 MaxVGPRs =
TRI->getAllocatableSet(MF, &AMDGPU::VGPR_32RegClass).count();
272 MaxSGPRs =
TRI->getAllocatableSet(MF, &AMDGPU::SGPR_32RegClass).count();
283 if (
MI.isMetaInstruction())
300 if (!processRegUses(
MI, Defs,
Uses, RPT)) {
307 for ( ; Next != E &&
Length < FuncMaxClause; ++Next) {
309 if (Next->isMetaInstruction())
318 if (!processRegUses(*Next, Defs,
Uses, RPT))
321 LastClauseInst = Next;
330 MFI->limitOccupancy(LastRecordedOccupancy);
332 assert(!LastClauseInst->isMetaInstruction());
334 SlotIndex ClauseLiveInIdx = LIS->getInstructionIndex(
MI);
336 LIS->getInstructionIndex(*LastClauseInst).
getNextIndex();
343 for (
auto &&R :
Uses) {
345 if (
Reg.isPhysical())
353 if (!LI.
liveAt(ClauseLiveOutIdx)) {
355 AMDGPU::NoSubRegister);
360 if (SR.liveAt(ClauseLiveInIdx) && !SR.liveAt(ClauseLiveOutIdx))
361 KilledMask |= SR.LaneMask;
364 if (KilledMask.
none())
369 *
MRI,
MRI->getRegClass(Reg), KilledMask, KilledIndexes);
371 assert(
Success &&
"Failed to find subregister mask to cover lanes");
372 for (
unsigned SubReg : KilledIndexes) {
387 for (
auto &
Op : KillOps)
388 Kill.addUse(Reg, std::get<0>(
Op), std::get<1>(
Op));
398 for (
auto &&R : Defs) {
401 if (
Reg.isPhysical())
403 LIS->removeInterval(Reg);
404 LIS->createAndComputeVirtRegInterval(Reg);
407 for (
auto &&R :
Uses) {
409 if (
Reg.isPhysical())
411 LIS->removeInterval(Reg);
412 LIS->createAndComputeVirtRegInterval(Reg);
unsigned const MachineRegisterInfo * MRI
This file defines the GCNRegPressure class, which tracks registry pressure by bookkeeping number of S...
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Remove Loads Into Fake Uses
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
GCNRegPressure moveMaxPressure()
return MaxPressure and clear it.
bool advanceBeforeNext(MachineInstr *MI=nullptr, bool UseInternalIterator=true)
Move to the state right before the next MI or after the end of MBB.
bool advance(MachineInstr *MI=nullptr, bool UseInternalIterator=true)
Move to the state at the next MI.
MachineBasicBlock::const_iterator getNext() const
bool reset(const MachineInstr &MI, const LiveRegSet *LiveRegs=nullptr)
Reset tracker to the point before the MI filling LiveRegs upon this point using LIS.
void advanceToNext(MachineInstr *MI=nullptr, bool UseInternalIterator=true)
Move to the state at the MI, advanceBeforeNext has to be called first.
const decltype(LiveRegs) & getLiveRegs() const
A live range for subregisters.
LiveInterval - This class represents the liveness of a register, or stack slot.
bool hasSubRanges() const
Returns true if subregister liveness information is available.
iterator_range< subrange_iterator > subranges()
bool liveAt(SlotIndex index) const
instr_iterator instr_begin()
Instructions::iterator instr_iterator
instr_iterator instr_end()
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual MachineFunctionProperties getClearedProperties() const
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
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.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
bool isValid() const
Check for null.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
bool isRenamable() const
isRenamable - Returns true if this register may be renamed, i.e.
bool isEarlyClobber() const
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
static bool isVMEM(const MachineInstr &MI)
static bool isSMRD(const MachineInstr &MI)
static bool isAtomic(const MachineInstr &MI)
static bool isFLAT(const MachineInstr &MI)
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
SlotIndex - An opaque wrapper around machine indexes.
SlotIndex getNextIndex() const
Returns the next index.
SlotIndex insertMachineInstrInMaps(MachineInstr &MI, bool Late=false)
Insert the given machine instruction into the mapping.
reference emplace_back(ArgTypes &&... Args)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Renamable
Register that may be renamed.
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
@ EarlyClobber
Register definition happens before uses.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
void initializeSIFormMemoryClausesPass(PassRegistry &)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
char & SIFormMemoryClausesID
FunctionPass * createSIFormMemoryClausesPass()
unsigned getOccupancy(const GCNSubtarget &ST) const
unsigned getVGPRNum(bool UnifiedVGPRFile) const
unsigned getSGPRNum() const
static constexpr LaneBitmask getAll()
constexpr bool none() const