65#define DEBUG_TYPE "hexagon-peephole"
69 cl::desc(
"Disable Peephole Optimization"));
72 cl::desc(
"Disable Optimization of PNotP"));
76 cl::desc(
"Disable Optimization of Sign/Zero Extends"));
81 cl::desc(
"Disable Optimization of extensions to i64."));
86 cl::desc(
"Fuse A2_vminub/C2_cmpgtup into "
101 StringRef getPassName()
const override {
102 return "Hexagon optimize redundant zero and size extends";
105 void getAnalysisUsage(AnalysisUsage &AU)
const override {
111char HexagonPeephole::ID = 0;
117 if (skipFunction(MF.getFunction()))
122 QII =
static_cast<const HexagonInstrInfo *
>(MF.getSubtarget().getInstrInfo());
123 MRI = &MF.getRegInfo();
126 DenseMap<
unsigned, std::pair<unsigned, unsigned> > PeepholeDoubleRegsMap;
133 PeepholeDoubleRegsMap.clear();
150 PeepholeMap[DstReg] = SrcReg;
161 if (Src1.getImm() != 0)
165 PeepholeMap[DstReg] = SrcReg;
173 if (
MI.getOpcode() == Hexagon::S2_lsr_i_p) {
178 if (Src2.getImm() != 32)
182 PeepholeDoubleRegsMap[DstReg] =
183 std::make_pair(*&SrcReg, Hexagon::isub_hi);
198 PeepholeMap[DstReg] = SrcReg;
210 if (Src.getSubReg() != Hexagon::isub_lo)
217 if (
unsigned PeepholeSrc = PeepholeMap.lookup(SrcReg)) {
224 PeepholeDoubleRegsMap.find(SrcReg);
225 if (DI != PeepholeDoubleRegsMap.
end()) {
226 std::pair<unsigned,unsigned> PeepholeSrc = DI->second;
229 PeepholeSrc.first,
false ,
false ,
230 false ,
false ,
false ,
231 false , PeepholeSrc.second));
241 if (QII->isPredicated(
MI)) {
245 if (RC0->
getID() == Hexagon::PredRegsRegClassID) {
250 if (
unsigned PeepholeSrc = PeepholeMap.lookup(Reg0)) {
252 MI.getOperand(0).setReg(PeepholeSrc);
253 MRI->clearKillFlags(PeepholeSrc);
254 int NewOp = QII->getInvertedPredicatedOpcode(
MI.getOpcode());
255 MI.setDesc(QII->get(NewOp));
265 unsigned Op =
MI.getOpcode();
267 unsigned PR = 1,
S1 = 2, S2 = 3;
270 case Hexagon::C2_mux:
271 case Hexagon::C2_muxii:
274 case Hexagon::C2_muxri:
275 NewOp = Hexagon::C2_muxir;
277 case Hexagon::C2_muxir:
278 NewOp = Hexagon::C2_muxri;
283 if (
unsigned POrig = PeepholeMap.lookup(PSrc)) {
285 MI.getOperand(0).getReg())
287 .
add(
MI.getOperand(S2))
289 MRI->clearKillFlags(POrig);
290 MI.eraseFromParent();
302 Changed |= fuseIntrinsicVMinUB(MF);
309 auto I1Uses = I1.explicit_uses();
311 unsigned I1NumUses = I1.getNumExplicitOperands() - I1.getNumExplicitDefs();
313 if (!I1NumUses || I1NumUses != I2NumUses)
316 auto I2Use = I2Uses.begin();
318 if (!I1Use.isIdenticalTo(*I2Use++))
336 for (MachineBasicBlock &
MBB : MF) {
337 SmallPtrSet<MachineInstr *, 8> DeadMIs;
339 for (MachineInstr &
MI :
MBB) {
340 unsigned Opc =
MI.getOpcode();
341 if ((
Opc != Hexagon::A2_vminub &&
Opc != Hexagon::C2_cmpgtup) ||
345 unsigned SiblingOpc =
346 Opc == Hexagon::A2_vminub ? Hexagon::C2_cmpgtup : Hexagon::A2_vminub;
348 for (
const MachineOperand &MO :
MI.operands())
349 if (MO.isReg() && !MO.isDef() && MO.getReg().isPhysical())
351 MachineInstr *Sibling =
nullptr;
352 auto It =
MI.getIterator();
353 for (++It; It !=
MBB.
end(); ++It) {
354 if (!DeadMIs.
count(&*It) && It->getOpcode() == SiblingOpc &&
365 MachineInstr *VMin =
Opc == Hexagon::A2_vminub ? &
MI : Sibling;
366 MachineInstr *
Cmp =
Opc == Hexagon::A2_vminub ? Sibling : &
MI;
372 QII->get(Hexagon::A6_vminub_RdP), VMinReg)
373 .
addReg(CmpReg, RegState::Define)
380 "vminub fusion requires virtual result registers");
384 Cmp->getOperand(0).setReg(CmpDef);
391 for (MachineInstr *
MI : DeadMIs)
392 MI->eraseFromParent();
399 return new HexagonPeephole();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the DenseMap class.
static bool modifiesPhysicalInput(ArrayRef< Register > Inputs, const MachineInstr &Between, const TargetRegisterInfo *TRI)
static cl::opt< bool > FuseIntrinsicVMinUB("hexagon-fuse-intrinsic-vminub", cl::Hidden, cl::init(true), cl::desc("Fuse A2_vminub/C2_cmpgtup into " "A6_vminub_RdP."))
static cl::opt< bool > DisableOptExtTo64("disable-hexagon-opt-ext-to-64", cl::Hidden, cl::init(true), cl::desc("Disable Optimization of extensions to i64."))
static cl::opt< bool > DisableHexagonPeephole("disable-hexagon-peephole", cl::Hidden, cl::desc("Disable Peephole Optimization"))
static cl::opt< bool > DisablePNotP("disable-hexagon-pnotp", cl::Hidden, cl::desc("Disable Optimization of PNotP"))
static cl::opt< bool > DisableOptSZExt("disable-hexagon-optszext", cl::Hidden, cl::init(true), cl::desc("Disable Optimization of Sign/Zero Extends"))
static bool hasCommonInputOps(const MachineInstr &I1, const MachineInstr &I2)
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
Represent a constant reference to an array (0 or more elements consecutively in memory),...
FunctionPass class - This class is used to implement most global optimizations.
unsigned getID() const
getID() - Return the register class ID number.
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 TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
Representation of each machine instruction.
LLVM_ABI unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
bool modifiesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register.
mop_range explicit_uses()
LLVM_ABI unsigned getNumExplicitDefs() const
Returns the number of non-implicit definitions.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
void push_back(const T &Elt)
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.
self_iterator getIterator()
initializer< Ty > init(const Ty &Val)
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 * createHexagonPeephole()
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
DWARFExpression::Operation Op
MCRegisterClass TargetRegisterClass