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) {
68 bool runOnMachineFunction(MachineFunction &MF)
override;
70 StringRef getPassName()
const override {
71 return "SI Form memory clauses";
74 void getAnalysisUsage(AnalysisUsage &AU)
const override {
80 MachineFunctionProperties getClearedProperties()
const override {
81 return MachineFunctionProperties().setIsSSA();
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 {
158 for (
const MachineOperand &MO :
MI.operands()) {
173 const RegUse &
Map = MO.isDef() ?
Uses : Defs;
174 auto Conflict =
Map.find(
Reg);
175 if (Conflict ==
Map.end())
181 LaneBitmask
Mask =
TRI->getSubRegIndexLaneMask(MO.getSubReg());
182 if ((Conflict->second.second & Mask).any())
192bool SIFormMemoryClausesImpl::checkPressure(
const MachineInstr &
MI,
193 GCNDownwardRPTracker &RPT) {
202 MI.getMF()->getInfo<SIMachineFunctionInfo>()->getDynamicVGPRBlockSize());
216 LastRecordedOccupancy = Occupancy;
223void SIFormMemoryClausesImpl::collectRegUses(
const MachineInstr &
MI,
224 RegUse &Defs, RegUse &
Uses)
const {
225 for (
const MachineOperand &MO :
MI.operands()) {
233 ?
TRI->getSubRegIndexLaneMask(MO.getSubReg())
235 RegUse &
Map = MO.isDef() ? Defs :
Uses;
240 Loc->second.first |= State;
241 Loc->second.second |=
Mask;
249bool SIFormMemoryClausesImpl::processRegUses(
const MachineInstr &
MI,
250 RegUse &Defs, RegUse &
Uses,
251 GCNDownwardRPTracker &RPT) {
252 if (!canBundle(
MI, Defs,
Uses))
255 if (!checkPressure(
MI, RPT))
258 collectRegUses(
MI, Defs,
Uses);
262bool SIFormMemoryClausesImpl::run(MachineFunction &MF) {
270 MFI = MF.
getInfo<SIMachineFunctionInfo>();
274 MaxVGPRs =
TRI->getAllocatableSet(MF, &AMDGPU::VGPR_32RegClass).count();
275 MaxSGPRs =
TRI->getAllocatableSet(MF, &AMDGPU::SGPR_32RegClass).count();
279 for (MachineBasicBlock &
MBB : MF) {
280 GCNDownwardRPTracker RPT(*LIS);
283 MachineInstr &
MI = *
I;
286 if (
MI.isMetaInstruction())
303 if (!processRegUses(
MI, Defs,
Uses, RPT)) {
312 if (
Next->isMetaInstruction())
321 if (!processRegUses(*
Next, Defs,
Uses, RPT))
324 LastClauseInst =
Next;
335 assert(!LastClauseInst->isMetaInstruction());
338 SlotIndex ClauseLiveOutIdx =
342 MachineInstrBuilder
Kill;
346 for (
auto &&R :
Uses) {
356 if (!LI.
liveAt(ClauseLiveOutIdx)) {
358 AMDGPU::NoSubRegister);
361 LaneBitmask KilledMask;
362 for (
const LiveInterval::SubRange &SR : LI.
subranges()) {
363 if (SR.liveAt(ClauseLiveInIdx) && !SR.liveAt(ClauseLiveOutIdx))
364 KilledMask |= SR.LaneMask;
367 if (KilledMask.
none())
370 SmallVector<unsigned> KilledIndexes;
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) {
410 for (
auto &&R :
Uses) {
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!")
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
bool hasGFX90AInsts() const
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 LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
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.
@ 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.
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()
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
char & SIFormMemoryClausesID
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
void initializeSIFormMemoryClausesLegacyPass(PassRegistry &)
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