25#define DEBUG_TYPE "aarch64-sme-peephole-opt"
39 return "SME Peephole Optimization pass";
48 bool &HasRemovedAllSMChanges)
const;
51char SMEPeepholeOpt::ID = 0;
56 return MI->getOpcode() == AArch64::MSRpstatePseudo;
106 assert((
MI->getOpcode() == AArch64::MSRpstatesvcrImm1 ||
107 MI->getOpcode() == AArch64::MSRpstatePseudo) &&
108 "Expected MI to be a smstart/smstop instruction");
109 return MI->getOperand(0).getImm() == AArch64SVCR::SVCRSM ||
110 MI->getOperand(0).getImm() == AArch64SVCR::SVCRSMZA;
122 return AArch64::ZPRRegClass.contains(SR) ||
123 AArch64::PPRRegClass.contains(SR);
127 return TRI.getCommonSubClass(&AArch64::ZPRRegClass, RC) ||
128 TRI.getCommonSubClass(&AArch64::PPRRegClass, RC);
131bool SMEPeepholeOpt::optimizeStartStopPairs(
137 bool Changed =
false;
151 unsigned NumSMChanges = 0;
152 unsigned NumSMChangesRemoved = 0;
154 switch (
MI.getOpcode()) {
155 case AArch64::MSRpstatesvcrImm1:
156 case AArch64::MSRpstatePseudo: {
166 MI.eraseFromParent();
168 TBR->eraseFromParent();
172 NumSMChangesRemoved += 2;
188 switch (
MI.getOpcode()) {
192 case AArch64::COALESCER_BARRIER_FPR16:
193 case AArch64::COALESCER_BARRIER_FPR32:
194 case AArch64::COALESCER_BARRIER_FPR64:
195 case AArch64::COALESCER_BARRIER_FPR128:
206 case AArch64::ADJCALLSTACKDOWN:
207 case AArch64::ADJCALLSTACKUP:
208 case AArch64::ANDXri:
209 case AArch64::ADDXri:
212 case AArch64::VGRestorePseudo:
213 case AArch64::VGSavePseudo:
216 ToBeRemoved.push_back(&
MI);
218 case AArch64::MSRpstatesvcrImm1:
219 case AArch64::MSRpstatePseudo:
224 HasRemovedAllSMChanges =
225 NumSMChanges && (NumSMChanges == NumSMChangesRemoved);
230 "SME Peephole Optimization",
false,
false)
233 if (skipFunction(MF.getFunction()))
239 assert(MF.getRegInfo().isSSA() &&
"Expected to be run on SSA form!");
241 bool Changed =
false;
242 bool FunctionHasAllSMChangesRemoved =
false;
248 bool BlockHasAllSMChangesRemoved;
249 Changed |= optimizeStartStopPairs(
MBB, BlockHasAllSMChangesRemoved);
250 FunctionHasAllSMChangesRemoved |= BlockHasAllSMChangesRemoved;
254 if (FunctionHasAllSMChangesRemoved)
unsigned const MachineRegisterInfo * MRI
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isSVERegOp(const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, const MachineOperand &MO)
static bool isMatchingStartStopPair(const MachineInstr *MI1, const MachineInstr *MI2)
static bool isConditionalStartStop(const MachineInstr *MI)
static bool ChangesStreamingMode(const MachineInstr *MI)
This file defines the SmallVector class.
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
void setHasStreamingModeChanges(bool HasChanges)
Represent the analysis usage information of a pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
FunctionPass class - This class is used to implement most global optimizations.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
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.
Representation of each machine instruction.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
const uint32_t * getRegMask() const
getRegMask - Returns a bit mask of registers preserved by this RegMask operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static 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.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
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.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
FunctionPass * createSMEPeepholeOptPass()
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void initializeSMEPeepholeOptPass(PassRegistry &)