27#define DEBUG_TYPE "aarch64-post-select-optimize"
36 AArch64PostSelectOptimize();
39 return "AArch64 Post Select Optimizer";
54void AArch64PostSelectOptimize::getAnalysisUsage(
AnalysisUsage &AU)
const {
61AArch64PostSelectOptimize::AArch64PostSelectOptimize()
70 case AArch64::SUBSXrr:
71 return AArch64::SUBXrr;
72 case AArch64::SUBSWrr:
73 return AArch64::SUBWrr;
74 case AArch64::SUBSXrs:
75 return AArch64::SUBXrs;
76 case AArch64::SUBSXri:
77 return AArch64::SUBXri;
78 case AArch64::SUBSWri:
79 return AArch64::SUBWri;
86 Changed |= foldSimpleCrossClassCopies(
MI);
91bool AArch64PostSelectOptimize::foldSimpleCrossClassCopies(
MachineInstr &
MI) {
92 auto *MF =
MI.getMF();
93 auto &
MRI = MF->getRegInfo();
98 if (
MI.getOperand(1).getSubReg())
104 if (Src.isPhysical() || Dst.isPhysical())
119 if (!
MRI.hasOneNonDBGUse(Src))
124 if (!
MRI.constrainRegClass(Src, DstRC, 25))
134 MRI.replaceRegWith(Dst, Src);
135 MI.eraseFromParent();
158 bool Changed =
false;
161 const auto &
TII = Subtarget.getInstrInfo();
162 auto TRI = Subtarget.getRegisterInfo();
163 auto RBI = Subtarget.getRegBankInfo();
164 auto &
MRI = MF.getRegInfo();
172 if (
MI.getOpcode() == AArch64::FCMPSrr ||
173 MI.getOpcode() == AArch64::FCMPDrr) {
187 LRU.addLiveOuts(
MBB);
188 bool NZCVDead = LRU.available(AArch64::NZCV);
189 bool InsideCmpRange =
false;
191 LRU.stepBackward(II);
195 if (InsideCmpRange && &II == FirstCmp)
196 InsideCmpRange =
false;
197 else if (&II == LastCmp)
198 InsideCmpRange =
true;
202 bool NZCVDeadAtCurrInstr = LRU.available(AArch64::NZCV);
203 if (NZCVDead && NZCVDeadAtCurrInstr && II.definesRegister(AArch64::NZCV)) {
206 int DeadNZCVIdx = II.findRegisterDefOperandIdx(AArch64::NZCV);
207 if (DeadNZCVIdx != -1) {
209 if (InsideCmpRange && NewOpc) {
210 LLVM_DEBUG(
dbgs() <<
"Post-select optimizer: converting flag-setting "
213 II.setDesc(
TII->get(NewOpc));
214 II.removeOperand(DeadNZCVIdx);
219 II.getOperand(0), 0);
224 II.getOperand(DeadNZCVIdx).setIsDead();
229 NZCVDead = NZCVDeadAtCurrInstr;
234bool AArch64PostSelectOptimize::runOnMachineFunction(
MachineFunction &MF) {
236 MachineFunctionProperties::Property::FailedISel))
239 MachineFunctionProperties::Property::Selected) &&
240 "Expected a selected MF");
242 bool Changed =
false;
243 for (
auto &BB : MF) {
244 Changed |= optimizeNZCVDefs(BB);
245 Changed |= doPeepholeOpts(BB);
250char AArch64PostSelectOptimize::ID = 0;
252 "Optimize AArch64 selected instructions",
260 return new AArch64PostSelectOptimize();
unsigned const MachineRegisterInfo * MRI
unsigned getNonFlagSettingVariant(unsigned Opc)
Optimize AArch64 selected instructions
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Target-Independent Code Generator Pass Configuration Options pass.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
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.
A set of register units used to track register liveness.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
reverse_iterator rbegin()
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...
bool hasProperty(Property P) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const MachineFunctionProperties & getProperties() const
Get the function properties.
Representation of each machine instruction.
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.
StringRef - Represent a constant reference to a string, i.e.
Target-Independent Code Generator Pass Configuration Options.
bool hasSubClass(const TargetRegisterClass *RC) const
Return true if the specified TargetRegisterClass is a proper sub-class of this TargetRegisterClass.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createAArch64PostSelectOptimize()
Register constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, MachineOperand &RegMO)
Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
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...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
auto instructionsWithoutDebug(IterT It, IterT End, bool SkipPseudoOp=true)
Construct a range iterator which begins at It and moves forwards until End is reached,...
void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
void initializeAArch64PostSelectOptimizePass(PassRegistry &)