24#define DEBUG_TYPE "aarch64-sme-peephole-opt"
36 return "SME Peephole Optimization pass";
45 bool &HasRemovedAllSMChanges)
const;
49char SMEPeepholeOpt::ID = 0;
54 return MI->getOpcode() == AArch64::MSRpstatePseudo;
98 assert((
MI->getOpcode() == AArch64::MSRpstatesvcrImm1 ||
99 MI->getOpcode() == AArch64::MSRpstatePseudo) &&
100 "Expected MI to be a smstart/smstop instruction");
101 return MI->getOperand(0).getImm() == AArch64SVCR::SVCRSM ||
102 MI->getOperand(0).getImm() == AArch64SVCR::SVCRSMZA;
114 return AArch64::ZPRRegClass.contains(SR) ||
115 AArch64::PPRRegClass.contains(SR);
119 return TRI.getCommonSubClass(&AArch64::ZPRRegClass, RC) ||
120 TRI.getCommonSubClass(&AArch64::PPRRegClass, RC);
123bool SMEPeepholeOpt::optimizeStartStopPairs(
129 bool Changed =
false;
136 unsigned NumSMChanges = 0;
137 unsigned NumSMChangesRemoved = 0;
139 switch (
MI.getOpcode()) {
140 case AArch64::MSRpstatesvcrImm1:
141 case AArch64::MSRpstatePseudo: {
151 MI.eraseFromParent();
154 NumSMChangesRemoved += 2;
169 switch (
MI.getOpcode()) {
173 case AArch64::COALESCER_BARRIER_FPR16:
174 case AArch64::COALESCER_BARRIER_FPR32:
175 case AArch64::COALESCER_BARRIER_FPR64:
176 case AArch64::COALESCER_BARRIER_FPR128:
187 case AArch64::ADJCALLSTACKDOWN:
188 case AArch64::ADJCALLSTACKUP:
189 case AArch64::ANDXri:
190 case AArch64::ADDXri:
193 case AArch64::MSRpstatesvcrImm1:
194 case AArch64::MSRpstatePseudo:
199 HasRemovedAllSMChanges =
200 NumSMChanges && (NumSMChanges == NumSMChangesRemoved);
220 assert(
MI.getMF()->getRegInfo().isSSA() &&
"Expected to be run on SSA form!");
223 switch (
MRI.getRegClass(
MI.getOperand(0).getReg())->getID()) {
224 case AArch64::ZPR2RegClassID:
225 case AArch64::ZPR4RegClassID:
226 case AArch64::ZPR2Mul2RegClassID:
227 case AArch64::ZPR4Mul4RegClassID:
236 if (
MI.getNumOperands() != 5 &&
MI.getNumOperands() != 9)
240 for (
unsigned I = 1;
I <
MI.getNumOperands();
I += 2) {
244 if (!Def || !
Def->getParent()->isCopy())
253 if (!CopySrcOp || !CopySrcOp->
isReg() || OpSubReg !=
SubReg ||
259 if (CopySrcClass != &AArch64::ZPR2StridedOrContiguousRegClass &&
260 CopySrcClass != &AArch64::ZPR4StridedOrContiguousRegClass)
264 unsigned Opc =
MI.getNumOperands() == 5
265 ? AArch64::FORM_TRANSPOSED_REG_TUPLE_X2_PSEUDO
266 : AArch64::FORM_TRANSPOSED_REG_TUPLE_X4_PSEUDO;
271 TII->get(
Opc),
MI.getOperand(0).getReg());
272 for (
unsigned I = 1;
I <
MI.getNumOperands();
I += 2)
275 MI.eraseFromParent();
280 "SME Peephole Optimization",
false,
false)
283 if (skipFunction(MF.getFunction()))
289 assert(MF.getRegInfo().isSSA() &&
"Expected to be run on SSA form!");
291 bool Changed =
false;
292 bool FunctionHasAllSMChangesRemoved =
false;
298 bool BlockHasAllSMChangesRemoved;
299 Changed |= optimizeStartStopPairs(
MBB, BlockHasAllSMChangesRemoved);
300 FunctionHasAllSMChangesRemoved |= BlockHasAllSMChangesRemoved;
304 if (
MI.getOpcode() == AArch64::REG_SEQUENCE)
305 Changed |= visitRegSequence(
MI);
310 if (FunctionHasAllSMChangesRemoved)
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
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)
bool isStreaming() const
Returns true if the function has a streaming body.
Represent the analysis usage information of a pass.
LLVM_ABI 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.
Wrapper class representing physical registers. Should be passed by value.
static constexpr unsigned NoRegister
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.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
LLVM_ABI 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.
unsigned getSubReg() const
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,...
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.
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
#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.
NodeAddr< DefNode * > Def
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.
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.