30 #define DEBUG_TYPE "si-form-memory-clauses" 36 cl::desc(
"Maximum length of a memory clause, instructions"));
54 return "SI Form memory clauses";
64 template <
typename Callable>
65 void forAllLanes(
unsigned Reg,
LaneBitmask LaneMask, Callable Func)
const;
67 bool canBundle(
const MachineInstr &
MI, RegUse &Defs, RegUse &Uses)
const;
69 void collectRegUses(
const MachineInstr &
MI, RegUse &Defs, RegUse &Uses)
const;
70 bool processRegUses(
const MachineInstr &
MI, RegUse &Defs, RegUse &Uses,
78 unsigned LastRecordedOccupancy;
86 "SI Form memory clauses",
false,
false)
92 char SIFormMemoryClauses::ID = 0;
97 return new SIFormMemoryClauses();
142 template <
typename Callable>
143 void SIFormMemoryClauses::forAllLanes(
unsigned Reg,
LaneBitmask LaneMask,
144 Callable Func)
const {
146 LaneMask ==
MRI->getMaxLaneMaskForVReg(Reg)) {
152 unsigned E =
TRI->getNumSubRegIndices();
154 for (
unsigned Idx = 1; Idx <
E; ++Idx) {
156 if (
TRI->getSubClassWithSubReg(RC, Idx) != RC)
160 if (SubRegMask == LaneMask) {
165 if ((SubRegMask & ~LaneMask).any() || (SubRegMask & LaneMask).none())
171 llvm::sort(CoveringSubregs, [
this](
unsigned A,
unsigned B) {
181 for (
unsigned Idx : CoveringSubregs) {
183 if ((SubRegMask & ~LaneMask).any() || (SubRegMask & LaneMask).none())
187 LaneMask &= ~SubRegMask;
198 RegUse &Defs, RegUse &Uses)
const {
209 unsigned Reg = MO.getReg();
215 RegUse &Map = MO.isDef() ? Uses : Defs;
216 auto Conflict = Map.find(Reg);
217 if (Conflict == Map.end())
224 if ((Conflict->second.second & Mask).any())
234 bool SIFormMemoryClauses::checkPressure(
const MachineInstr &MI,
243 if (Occupancy >= MFI->getMinAllowedOccupancy() &&
246 LastRecordedOccupancy = Occupancy;
253 void SIFormMemoryClauses::collectRegUses(
const MachineInstr &MI,
254 RegUse &Defs, RegUse &Uses)
const {
258 unsigned Reg = MO.getReg();
263 TRI->getSubRegIndexLaneMask(MO.getSubReg()) :
265 RegUse &Map = MO.isDef() ? Defs : Uses;
267 auto Loc = Map.find(Reg);
269 if (Loc == Map.end()) {
270 Map[
Reg] = std::make_pair(State, Mask);
272 Loc->second.first |= State;
273 Loc->second.second |=
Mask;
281 bool SIFormMemoryClauses::processRegUses(
const MachineInstr &MI,
282 RegUse &Defs, RegUse &Uses,
284 if (!canBundle(MI, Defs, Uses))
287 if (!checkPressure(MI, RPT))
290 collectRegUses(MI, Defs, Uses);
299 if (!
ST->isXNACKEnabled())
303 TRI =
ST->getRegisterInfo();
308 bool Changed =
false;
310 MaxVGPRs =
TRI->getAllocatableSet(MF, &AMDGPU::VGPR_32RegClass).count();
311 MaxSGPRs =
TRI->getAllocatableSet(MF, &AMDGPU::SGPR_32RegClass).count();
315 for (
auto I = MBB.instr_begin(),
E = MBB.instr_end();
I !=
E;
I = Next) {
328 if (!processRegUses(MI, Defs, Uses, RPT))
332 for ( ; Next !=
E && Length <
MaxClause; ++Next) {
339 if (!processRegUses(*Next, Defs, Uses, RPT))
348 MFI->limitOccupancy(LastRecordedOccupancy);
351 Ind->insertMachineInstrInMaps(*
B);
353 for (
auto BI =
I; BI != Next; ++BI) {
355 Ind->removeSingleMachineInstrFromMaps(*BI);
359 MO.setIsInternalRead(
true);
362 for (
auto &&R : Defs) {
363 forAllLanes(R.first, R.second.second, [&R, &
B](
unsigned SubReg) {
364 unsigned S = R.second.first | RegState::EarlyClobber;
366 S &= ~(RegState::Undef | RegState::Dead);
367 B.addDef(R.first, S, SubReg);
371 for (
auto &&R : Uses) {
372 forAllLanes(R.first, R.second.second, [&R, &
B](
unsigned SubReg) {
373 B.addUse(R.first, R.second.first & ~RegState::Kill, SubReg);
377 for (
auto &&R : Defs) {
378 unsigned Reg = R.first;
382 LIS->removeInterval(Reg);
383 LIS->createAndComputeVirtRegInterval(Reg);
386 for (
auto &&R : Uses) {
387 unsigned Reg = R.first;
390 LIS->removeInterval(Reg);
391 LIS->createAndComputeVirtRegInterval(Reg);
char & SIFormMemoryClausesID
unsigned getNumLanes() const
void bundleWithPred()
Bundle this instruction with its predecessor.
Interface definition for SIRegisterInfo.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
AMDGPU specific subclass of TargetSubtarget.
This class represents lattice values for constants.
FunctionPass * createSIFormMemoryClausesPass()
void initializeSIFormMemoryClausesPass(PassRegistry &)
decltype(MaxPressure) moveMaxPressure()
void push_back(const T &Elt)
bool reset(const MachineInstr &MI, const LiveRegSet *LiveRegs=nullptr)
unsigned getReg() const
getReg - Returns the register number.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
unsigned getHighestLane() const
unsigned const TargetRegisterInfo * TRI
LLVM_READONLY int getAtomicNoRetOp(uint16_t Opcode)
iterator_range< mop_iterator > operands()
static bool isSMRD(const MachineInstr &MI)
bool isEarlyClobber() const
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
LLVM_READONLY int getAtomicRetOp(uint16_t Opcode)
static bool isFLAT(const MachineInstr &MI)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
static constexpr LaneBitmask getAll()
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
unsigned getOccupancy(const GCNSubtarget &ST) const
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
initializer< Ty > init(const Ty &Val)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
bool isBundled() const
Return true if this instruction part of a bundle.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
unsigned getSGPRNum() const
Represent the analysis usage information of a pass.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
FunctionPass class - This class is used to implement most global optimizations.
constexpr bool all() const
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void sort(IteratorTy Start, IteratorTy End)
Iterator for intrusive lists based on ilist_node.
bool isDebugValue() const
MachineOperand class - Representation of each machine instruction operand.
unsigned getVGPRNum() const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
const Function & getFunction() const
Return the LLVM function that this machine code represents.
void setPreservesAll()
Set by analyses that do not transform their input at all.
bool isRenamable() const
isRenamable - Returns true if this register may be renamed, i.e.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Provides AMDGPU specific target descriptions.
Representation of each machine instruction.
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
Interface definition for SIInstrInfo.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
static bool isVMEM(const MachineInstr &MI)
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
StringRef - Represent a constant reference to a string, i.e.