Go to the documentation of this file.
24 #define DEBUG_TYPE "si-form-memory-clauses"
30 cl::desc(
"Maximum length of a memory clause, instructions"));
48 return "SI Form memory clauses";
64 const RegUse &
Uses)
const;
75 unsigned LastRecordedOccupancy;
83 "SI Form memory clauses",
false,
false)
89 char 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.isReg() || MO.isDef())
125 if (MO.getReg() == ResReg)
152 bool SIFormMemoryClauses::canBundle(
const MachineInstr &
MI,
const RegUse &Defs,
153 const RegUse &
Uses)
const {
170 const RegUse &
Map = MO.isDef() ?
Uses : Defs;
171 auto Conflict =
Map.find(
Reg);
172 if (Conflict ==
Map.end())
175 if (
Reg.isPhysical())
179 if ((Conflict->second.second &
Mask).any())
208 if (Occupancy >= MFI->getMinAllowedOccupancy() &&
209 MaxPressure.
getVGPRNum(
ST->hasGFX90AInsts()) <= MaxVGPRs / 2 &&
211 LastRecordedOccupancy = Occupancy;
219 RegUse &Defs, RegUse &
Uses)
const {
230 RegUse &
Map = MO.isDef() ? Defs :
Uses;
234 if (Loc ==
Map.end()) {
237 Loc->second.first |= State;
238 Loc->second.second |=
Mask;
247 RegUse &Defs, RegUse &
Uses,
249 if (!canBundle(
MI, Defs,
Uses))
252 if (!checkPressure(
MI, RPT))
255 collectRegUses(
MI, Defs,
Uses);
264 if (!
ST->isXNACKEnabled())
268 TRI =
ST->getRegisterInfo();
273 bool Changed =
false;
287 if (
MI.isMetaInstruction())
304 if (!processRegUses(
MI, Defs,
Uses, RPT)) {
311 for ( ; Next !=
E &&
Length < FuncMaxClause; ++Next) {
313 if (Next->isMetaInstruction())
322 if (!processRegUses(*Next, Defs,
Uses, RPT))
325 LastClauseInst = Next;
334 MFI->limitOccupancy(LastRecordedOccupancy);
336 assert(!LastClauseInst->isMetaInstruction());
338 SlotIndex ClauseLiveInIdx = LIS->getInstructionIndex(
MI);
340 LIS->getInstructionIndex(*LastClauseInst).
getNextIndex();
347 for (
auto &&R :
Uses) {
349 if (
Reg.isPhysical())
357 if (!LI.
liveAt(ClauseLiveOutIdx)) {
359 AMDGPU::NoSubRegister);
364 if (SR.liveAt(ClauseLiveInIdx) && !SR.liveAt(ClauseLiveOutIdx))
365 KilledMask |= SR.LaneMask;
368 if (KilledMask.
none())
375 assert(
Success &&
"Failed to find subregister mask to cover lanes");
376 for (
unsigned SubReg : KilledIndexes) {
391 for (
auto &
Op : KillOps)
392 Kill.addUse(
Reg, std::get<0>(
Op), std::get<1>(
Op));
402 for (
auto &&R : Defs) {
405 if (
Reg.isPhysical())
407 LIS->removeInterval(
Reg);
408 LIS->createAndComputeVirtRegInterval(
Reg);
411 for (
auto &&R :
Uses) {
413 if (
Reg.isPhysical())
415 LIS->removeInterval(
Reg);
416 LIS->createAndComputeVirtRegInterval(
Reg);
@ Undef
Value of the register doesn't matter.
This is an optimization pass for GlobalISel generic memory operations.
const decltype(LiveRegs) & getLiveRegs() const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Reg
All possible values of the reg field in the ModR/M byte.
BitVector getAllocatableSet(const MachineFunction &MF, const TargetRegisterClass *RC=nullptr) const
Returns a bitset indexed by register number indicating if a register is allocatable or not.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Properties which a MachineFunction may have at a given point in time.
unsigned const TargetRegisterInfo * TRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
SmallPtrSet< MachineInstr *, 2 > Uses
decltype(MaxPressure) moveMaxPressure()
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.
bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
bool isRenamable() const
isRenamable - Returns true if this register may be renamed, i.e.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool liveAt(SlotIndex index) const
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const
Return a bitmask representing the parts of a register that are covered by SubIdx.
unsigned getSGPRNum() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
size_type count() const
count - Returns the number of bits which are set.
unsigned getOccupancy(const GCNSubtarget &ST) const
@ Renamable
Register that may be renamed.
Represent the analysis usage information of a pass.
const HexagonInstrInfo * TII
MachineOperand class - Representation of each machine instruction operand.
MachineFunctionProperties & set(Property P)
LiveInterval - This class represents the liveness of a register, or stack slot.
SlotIndex - An opaque wrapper around machine indexes.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
SlotIndex insertMachineInstrInMaps(MachineInstr &MI, bool Late=false)
Insert the given machine instruction into the mapping.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Representation of each machine instruction.
@ EarlyClobber
Register definition happens before uses.
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
static bool isSMRD(const MachineInstr &MI)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
initializer< Ty > init(const Ty &Val)
char & SIFormMemoryClausesID
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool reset(const MachineInstr &MI, const LiveRegSet *LiveRegs=nullptr)
bool isEarlyClobber() const
static bool isAtomic(const MachineInstr &MI)
Register getReg() const
getReg - Returns the register number.
instr_iterator instr_begin()
instr_iterator instr_end()
FunctionPass * createSIFormMemoryClausesPass()
void initializeSIFormMemoryClausesPass(PassRegistry &)
StringRef - Represent a constant reference to a string, i.e.
constexpr bool none() const
bool getCoveringSubRegIndexes(const MachineRegisterInfo &MRI, const TargetRegisterClass *RC, LaneBitmask LaneMask, SmallVectorImpl< unsigned > &Indexes) const
Try to find one or more subregister indexes to cover LaneMask.
SlotIndex getNextIndex() const
Returns the next index.
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
A live range for subregisters.
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
MachineBasicBlock::const_iterator getNext() const
Function & getFunction()
Return the LLVM function that this machine code represents.
void setPreservesAll()
Set by analyses that do not transform their input at all.
unsigned getVGPRNum(bool UnifiedVGPRFile) const
Iterator for intrusive lists based on ilist_node.
static bool isVMEM(const MachineInstr &MI)
@ Kill
The last use of a register.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
bool hasSubRanges() const
Returns true if subregister liveness information is available.
FunctionPass class - This class is used to implement most global optimizations.
AnalysisUsage & addRequired()
static bool isFLAT(const MachineInstr &MI)
static constexpr LaneBitmask getAll()
reference emplace_back(ArgTypes &&... Args)
iterator_range< subrange_iterator > subranges()