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;
57 bool run(MachineFunction &MF);
64 SIFormMemoryClausesLegacy() : MachineFunctionPass(ID) {}
66 bool runOnMachineFunction(MachineFunction &MF)
override;
68 StringRef getPassName()
const override {
69 return "SI Form memory clauses";
72 void getAnalysisUsage(AnalysisUsage &AU)
const override {
78 MachineFunctionProperties getClearedProperties()
const override {
79 return MachineFunctionProperties().setIsSSA();
86 "SI Form memory clauses",
false,
false)
91char SIFormMemoryClausesLegacy::
ID = 0;
96 return new SIFormMemoryClausesLegacy();
110 assert(!
MI.isDebugInstr() &&
"debug instructions should not reach here");
113 if (!
MI.mayLoad() ||
MI.mayStore())
125 if (MO.getReg() == ResReg)
154 const RegUse &
Uses)
const {
156 for (
const MachineOperand &MO :
MI.operands()) {
171 const RegUse &
Map = MO.isDef() ?
Uses : Defs;
172 auto Conflict =
Map.find(
Reg);
173 if (Conflict ==
Map.end())
179 LaneBitmask
Mask =
TRI->getSubRegIndexLaneMask(MO.getSubReg());
180 if ((Conflict->second.second & Mask).any())
190bool SIFormMemoryClausesImpl::checkPressure(
const MachineInstr &
MI,
191 GCNDownwardRPTracker &RPT) {
200 MI.getMF()->getInfo<SIMachineFunctionInfo>()->getDynamicVGPRBlockSize());
212 MaxPressure.
getVGPRNum(ST->hasGFX90AInsts()) <= MaxVGPRs / 2 &&
214 LastRecordedOccupancy = Occupancy;
221void SIFormMemoryClausesImpl::collectRegUses(
const MachineInstr &
MI,
222 RegUse &Defs, RegUse &
Uses)
const {
223 for (
const MachineOperand &MO :
MI.operands()) {
231 ?
TRI->getSubRegIndexLaneMask(MO.getSubReg())
233 RegUse &
Map = MO.isDef() ? Defs :
Uses;
238 Loc->second.first |= State;
239 Loc->second.second |=
Mask;
247bool SIFormMemoryClausesImpl::processRegUses(
const MachineInstr &
MI,
248 RegUse &Defs, RegUse &
Uses,
249 GCNDownwardRPTracker &RPT) {
250 if (!canBundle(
MI, Defs,
Uses))
253 if (!checkPressure(
MI, RPT))
256 collectRegUses(
MI, Defs,
Uses);
260bool SIFormMemoryClausesImpl::run(MachineFunction &MF) {
268 MFI = MF.
getInfo<SIMachineFunctionInfo>();
272 MaxVGPRs =
TRI->getAllocatableSet(MF, &AMDGPU::VGPR_32RegClass).count();
273 MaxSGPRs =
TRI->getAllocatableSet(MF, &AMDGPU::SGPR_32RegClass).count();
277 for (MachineBasicBlock &
MBB : MF) {
278 GCNDownwardRPTracker RPT(*LIS);
281 MachineInstr &
MI = *
I;
284 if (
MI.isMetaInstruction())
301 if (!processRegUses(
MI, Defs,
Uses, RPT)) {
310 if (
Next->isMetaInstruction())
319 if (!processRegUses(*
Next, Defs,
Uses, RPT))
322 LastClauseInst =
Next;
333 assert(!LastClauseInst->isMetaInstruction());
336 SlotIndex ClauseLiveOutIdx =
340 MachineInstrBuilder
Kill;
344 for (
auto &&R :
Uses) {
354 if (!LI.
liveAt(ClauseLiveOutIdx)) {
356 AMDGPU::NoSubRegister);
359 LaneBitmask KilledMask;
360 for (
const LiveInterval::SubRange &SR : LI.
subranges()) {
361 if (SR.liveAt(ClauseLiveInIdx) && !SR.liveAt(ClauseLiveOutIdx))
362 KilledMask |= SR.LaneMask;
365 if (KilledMask.
none())
368 SmallVector<unsigned> KilledIndexes;
370 MRI->getRegClass(
Reg), KilledMask, KilledIndexes);
372 assert(
Success &&
"Failed to find subregister mask to cover lanes");
373 for (
unsigned SubReg : KilledIndexes) {
388 for (
auto &
Op : KillOps)
389 Kill.addUse(
Reg, std::get<0>(
Op), std::get<1>(
Op));
390 Ind->insertMachineInstrInMaps(*
Kill);
399 for (
auto &&R : Defs) {
408 for (
auto &&R :
Uses) {
421bool SIFormMemoryClausesLegacy::runOnMachineFunction(MachineFunction &MF) {
425 LiveIntervals *LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
426 return SIFormMemoryClausesImpl(LIS).run(MF);
433 SIFormMemoryClausesImpl(&LIS).
run(MF);
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the GCNRegPressure class, which tracks registry pressure by bookkeeping number of S...
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#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
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
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
DenseMap< unsigned, LaneBitmask > LiveRegSet
const SIInstrInfo * getInstrInfo() const override
const SIRegisterInfo * getRegisterInfo() const override
bool isXNACKEnabled() const
bool hasSubRanges() const
Returns true if subregister liveness information is available.
iterator_range< subrange_iterator > subranges()
LLVM_ABI Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
SlotIndexes * getSlotIndexes() const
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
LiveInterval & getInterval(Register Reg)
void removeInterval(Register Reg)
Interval removal.
LiveInterval & createAndComputeVirtRegInterval(Register Reg)
bool liveAt(SlotIndex index) const
instr_iterator instr_begin()
MachineInstrBundleIterator< const MachineInstr > const_iterator
Instructions::iterator instr_iterator
instr_iterator instr_end()
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
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 PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
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 getMinAllowedOccupancy() const
void limitOccupancy(const MachineFunction &MF)
SlotIndex getNextIndex() const
Returns the next index.
reference emplace_back(ArgTypes &&... Args)
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.
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()
RegState
Flags to represent properties of register accesses.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
@ EarlyClobber
Register definition happens before uses.
@ Renamable
Register that may be renamed.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
char & SIFormMemoryClausesID
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
FunctionAddr VTableAddr Next
DWARFExpression::Operation Op
unsigned getVGPRNum(bool UnifiedVGPRFile) const
unsigned getOccupancy(const GCNSubtarget &ST, unsigned DynamicVGPRBlockSize) const
unsigned getSGPRNum() const
static constexpr LaneBitmask getAll()
constexpr bool none() const