25#define DEBUG_TYPE "si-form-memory-clauses"
31 cl::desc(
"Maximum length of a memory clause, instructions"));
35class SIFormMemoryClausesImpl {
39 const RegUse &
Uses)
const;
51 unsigned LastRecordedOccupancy;
71 return "SI Form memory clauses";
88 "SI Form memory clauses",
false,
false)
93char SIFormMemoryClausesLegacy::
ID = 0;
98 return new SIFormMemoryClausesLegacy();
112 assert(!
MI.isDebugInstr() &&
"debug instructions should not reach here");
115 if (!
MI.mayLoad() ||
MI.mayStore())
127 if (MO.getReg() == ResReg)
156 const RegUse &
Uses)
const {
173 const RegUse &
Map = MO.isDef() ?
Uses : Defs;
174 auto Conflict =
Map.find(Reg);
175 if (Conflict ==
Map.end())
178 if (
Reg.isPhysical())
182 if ((Conflict->second.second & Mask).any())
192bool SIFormMemoryClausesImpl::checkPressure(
const MachineInstr &
MI,
213 if (Occupancy >= MFI->getMinAllowedOccupancy() &&
214 MaxPressure.
getVGPRNum(
ST->hasGFX90AInsts()) <= MaxVGPRs / 2 &&
216 LastRecordedOccupancy = Occupancy;
223void SIFormMemoryClausesImpl::collectRegUses(
const MachineInstr &
MI,
224 RegUse &Defs, RegUse &
Uses)
const {
233 ?
TRI->getSubRegIndexLaneMask(MO.getSubReg())
235 RegUse &
Map = MO.isDef() ? Defs :
Uses;
238 auto [Loc,
Inserted] =
Map.try_emplace(Reg, State, Mask);
240 Loc->second.first |= State;
241 Loc->second.second |=
Mask;
249bool SIFormMemoryClausesImpl::processRegUses(
const MachineInstr &
MI,
250 RegUse &Defs, RegUse &
Uses,
252 if (!canBundle(
MI, Defs,
Uses))
255 if (!checkPressure(
MI, RPT))
258 collectRegUses(
MI, Defs,
Uses);
264 if (!
ST->isXNACKEnabled())
268 TRI =
ST->getRegisterInfo();
272 bool Changed =
false;
274 MaxVGPRs =
TRI->getAllocatableSet(MF, &AMDGPU::VGPR_32RegClass).count();
275 MaxSGPRs =
TRI->getAllocatableSet(MF, &AMDGPU::SGPR_32RegClass).count();
286 if (
MI.isMetaInstruction())
303 if (!processRegUses(
MI, Defs,
Uses, RPT)) {
310 for ( ; Next != E &&
Length < FuncMaxClause; ++Next) {
312 if (Next->isMetaInstruction())
321 if (!processRegUses(*Next, Defs,
Uses, RPT))
324 LastClauseInst = Next;
333 MFI->limitOccupancy(LastRecordedOccupancy);
335 assert(!LastClauseInst->isMetaInstruction());
337 SlotIndex ClauseLiveInIdx = LIS->getInstructionIndex(
MI);
339 LIS->getInstructionIndex(*LastClauseInst).
getNextIndex();
346 for (
auto &&R :
Uses) {
348 if (
Reg.isPhysical())
356 if (!LI.
liveAt(ClauseLiveOutIdx)) {
358 AMDGPU::NoSubRegister);
363 if (SR.liveAt(ClauseLiveInIdx) && !SR.liveAt(ClauseLiveOutIdx))
364 KilledMask |= SR.LaneMask;
367 if (KilledMask.
none())
372 MRI->getRegClass(Reg), KilledMask, KilledIndexes);
374 assert(
Success &&
"Failed to find subregister mask to cover lanes");
375 for (
unsigned SubReg : KilledIndexes) {
390 for (
auto &
Op : KillOps)
391 Kill.addUse(Reg, std::get<0>(
Op), std::get<1>(
Op));
392 Ind->insertMachineInstrInMaps(*Kill);
401 for (
auto &&R : Defs) {
404 if (
Reg.isPhysical())
406 LIS->removeInterval(Reg);
407 LIS->createAndComputeVirtRegInterval(Reg);
410 for (
auto &&R :
Uses) {
412 if (
Reg.isPhysical())
414 LIS->removeInterval(Reg);
415 LIS->createAndComputeVirtRegInterval(Reg);
423bool SIFormMemoryClausesLegacy::runOnMachineFunction(
MachineFunction &MF) {
427 LiveIntervals *LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
428 return SIFormMemoryClausesImpl(LIS).run(MF);
435 SIFormMemoryClausesImpl(&LIS).
run(MF);
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the GCNRegPressure class, which tracks registry pressure by bookkeeping number of S...
const HexagonInstrInfo * TII
Register 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
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
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()
LLVM_ABI Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
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.
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.
LLVM_ABI 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 LLVM_ABI 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.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
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)
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
unsigned getDynamicVGPRBlockSize() const
SlotIndex - An opaque wrapper around machine indexes.
SlotIndex getNextIndex() const
Returns the next index.
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)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
FunctionPass * createSIFormMemoryClausesLegacyPass()
char & SIFormMemoryClausesID
void initializeSIFormMemoryClausesLegacyPass(PassRegistry &)
unsigned getVGPRNum(bool UnifiedVGPRFile) const
unsigned getOccupancy(const GCNSubtarget &ST, unsigned DynamicVGPRBlockSize) const
unsigned getSGPRNum() const
static constexpr LaneBitmask getAll()
constexpr bool none() const