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 int NewOp = QII->getInvertedPredicatedOpcode(
MI.getOpcode());
254 MI.setDesc(QII->get(NewOp));
264 unsigned Op =
MI.getOpcode();
266 unsigned PR = 1,
S1 = 2, S2 = 3;
269 case Hexagon::C2_mux:
270 case Hexagon::C2_muxii:
273 case Hexagon::C2_muxri:
274 NewOp = Hexagon::C2_muxir;
276 case Hexagon::C2_muxir:
277 NewOp = Hexagon::C2_muxri;
282 if (
unsigned POrig = PeepholeMap.lookup(PSrc)) {
284 MI.getOperand(0).getReg())
286 .
add(
MI.getOperand(S2))
288 MI.eraseFromParent();
300 Changed |= fuseIntrinsicVMinUB(MF);
307 auto I1Uses = I1.explicit_uses();
309 unsigned I1NumUses = I1.getNumExplicitOperands() - I1.getNumExplicitDefs();
311 if (!I1NumUses || I1NumUses != I2NumUses)
314 auto I2Use = I2Uses.begin();
316 if (!I1Use.isIdenticalTo(*I2Use++))
334 for (MachineBasicBlock &
MBB : MF) {
335 SmallPtrSet<MachineInstr *, 8> DeadMIs;
337 for (MachineInstr &
MI :
MBB) {
338 unsigned Opc =
MI.getOpcode();
339 if ((
Opc != Hexagon::A2_vminub &&
Opc != Hexagon::C2_cmpgtup) ||
343 unsigned SiblingOpc =
344 Opc == Hexagon::A2_vminub ? Hexagon::C2_cmpgtup : Hexagon::A2_vminub;
346 for (
const MachineOperand &MO :
MI.operands())
347 if (MO.isReg() && !MO.isDef() && MO.getReg().isPhysical())
349 MachineInstr *Sibling =
nullptr;
350 auto It =
MI.getIterator();
351 for (++It; It !=
MBB.
end(); ++It) {
352 if (!DeadMIs.
count(&*It) && It->getOpcode() == SiblingOpc &&
363 MachineInstr *VMin =
Opc == Hexagon::A2_vminub ? &
MI : Sibling;
364 MachineInstr *
Cmp =
Opc == Hexagon::A2_vminub ? Sibling : &
MI;
370 QII->get(Hexagon::A6_vminub_RdP), VMinReg)
371 .
addReg(CmpReg, RegState::Define)
378 "vminub fusion requires virtual result registers");
382 Cmp->getOperand(0).setReg(CmpDef);
389 for (MachineInstr *
MI : DeadMIs)
390 MI->eraseFromParent();
397 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)
MachineRegisterInfo & MRI
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