26#define DEBUG_TYPE "aarch64-post-select-optimize"
39 return "AArch64 Post Select Optimizer";
48void AArch64PostSelectOptimizeLegacy::getAnalysisUsage(
59 case AArch64::SUBSXrr:
60 return AArch64::SUBXrr;
61 case AArch64::SUBSWrr:
62 return AArch64::SUBWrr;
63 case AArch64::SUBSXrs:
64 return AArch64::SUBXrs;
65 case AArch64::SUBSWrs:
66 return AArch64::SUBWrs;
67 case AArch64::SUBSXri:
68 return AArch64::SUBXri;
69 case AArch64::SUBSWri:
70 return AArch64::SUBWri;
71 case AArch64::ADDSXrr:
72 return AArch64::ADDXrr;
73 case AArch64::ADDSWrr:
74 return AArch64::ADDWrr;
75 case AArch64::ADDSXrs:
76 return AArch64::ADDXrs;
77 case AArch64::ADDSWrs:
78 return AArch64::ADDWrs;
79 case AArch64::ADDSXri:
80 return AArch64::ADDXri;
81 case AArch64::ADDSWri:
82 return AArch64::ADDWri;
84 return AArch64::SBCXr;
86 return AArch64::SBCWr;
88 return AArch64::ADCXr;
90 return AArch64::ADCWr;
96 auto *MF =
MI.getMF();
97 auto &MRI = MF->getRegInfo();
102 if (
MI.getOperand(1).getSubReg())
108 if (Src.isPhysical() || Dst.isPhysical())
123 if (!MRI.hasOneNonDBGUse(Src))
128 if (!MRI.constrainRegClass(Src, DstRC, 25))
138 MRI.replaceRegWith(Dst, Src);
139 MI.eraseFromParent();
147 auto *MF =
MI.getMF();
148 auto &MRI = MF->getRegInfo();
149 auto *
TII = MF->getSubtarget().getInstrInfo();
156 if (!Dst.isVirtual() || !Src.isVirtual())
162 if (MRI.getRegClassOrNull(Dst) != GPRRegClass ||
163 MRI.getRegClassOrNull(Src) != FPRRegClass)
170 for (
auto &
Use : MRI.use_nodbg_instructions(Dst)) {
179 if (MRI.getRegClassOrNull(UseOp0) == FPRRegClass &&
180 MRI.getRegClassOrNull(UseOp1) == GPRRegClass)
185 if (!SrcMI || SrcMI->
getOpcode() != DUP || !MRI.hasOneNonDBGUse(Src))
195 MI.eraseFromParent();
199 return TryMatchDUP(&AArch64::GPR32RegClass, &AArch64::FPR32RegClass,
200 AArch64::DUPi32, AArch64::UMOVvi32) ||
201 TryMatchDUP(&AArch64::GPR64RegClass, &AArch64::FPR64RegClass,
202 AArch64::DUPi64, AArch64::UMOVvi64);
209 if (!CurrentIterChanged)
245 auto &MF = *
MBB.getParent();
246 auto &Subtarget = MF.getSubtarget();
247 const auto &
TII = Subtarget.getInstrInfo();
248 auto TRI = Subtarget.getRegisterInfo();
249 auto RBI = Subtarget.getRegBankInfo();
250 auto &MRI = MF.getRegInfo();
256 bool NZCVDead = LRU.
available(AArch64::NZCV);
257 if (NZCVDead &&
II.definesRegister(AArch64::NZCV,
nullptr)) {
261 II.findRegisterDefOperandIdx(AArch64::NZCV,
nullptr);
262 if (DeadNZCVIdx != -1) {
265 LLVM_DEBUG(
dbgs() <<
"Post-select optimizer: converting flag-setting "
268 II.setDesc(
TII->get(NewOpc));
269 II.removeOperand(DeadNZCVIdx);
274 II.getOperand(0), 0);
279 II.getOperand(DeadNZCVIdx).setIsDead();
294 for (
auto &BB : MF) {
301bool AArch64PostSelectOptimizeLegacy::runOnMachineFunction(
302 MachineFunction &MF) {
306char AArch64PostSelectOptimizeLegacy::ID = 0;
308 "Optimize AArch64 selected instructions",
false,
false)
314 return new AArch64PostSelectOptimizeLegacy();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
bool doPeepholeOpts(MachineBasicBlock &MBB)
bool foldCopyDup(MachineInstr &MI)
bool optimizeNZCVDefs(MachineBasicBlock &MBB)
unsigned getNonFlagSettingVariant(unsigned Opc)
bool runAArch64PostSelectOptimize(MachineFunction &MF)
bool foldSimpleCrossClassCopies(MachineInstr &MI)
Look for cross regclass copies that can be trivially eliminated.
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Represent the analysis usage information of a pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
FunctionPass class - This class is used to implement most global optimizations.
A set of register units used to track register liveness.
bool available(MCRegister Reg) const
Returns true if no part of physical register Reg is live.
LLVM_ABI void stepBackward(const MachineInstr &MI)
Updates liveness when stepping backwards over the instruction MI.
LLVM_ABI void addLiveOuts(const MachineBasicBlock &MBB)
Adds registers living out of block MBB.
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.
const MachineFunctionProperties & getProperties() const
Get the function properties.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
Register getReg() const
getReg - Returns the register number.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
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.
bool hasSubClass(const TargetRegisterClass *RC) const
Return true if the specified TargetRegisterClass is a proper sub-class of this TargetRegisterClass.
A Use represents the edge between a Value definition and its users.
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()
LLVM_ABI 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...
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...
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
LLVM_ABI 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,...
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.