33 #define DEBUG_TYPE "ppc-mi-peepholes"
57 bool simplifyCode(
void);
61 unsigned lookThruCopyLike(
unsigned SrcReg);
69 return simplifyCode();
78 DEBUG(
dbgs() <<
"*** PowerPC MI peephole pass ***\n\n");
83 bool PPCMIPeephole::simplifyCode(
void) {
98 if (
MI.isDebugValue())
102 switch (
MI.getOpcode()) {
107 case PPC::XXPERMDI: {
111 int Immed =
MI.getOperand(3).getImm();
121 unsigned TrueReg1 = lookThruCopyLike(
MI.getOperand(1).getReg());
122 unsigned TrueReg2 = lookThruCopyLike(
MI.getOperand(2).getReg());
124 if (TrueReg1 == TrueReg2
127 unsigned DefOpc = DefMI ? DefMI->
getOpcode() : 0;
133 auto isConversionOfLoadAndSplat = [=]() ->
bool {
134 if (DefOpc != PPC::XVCVDPSXDS && DefOpc != PPC::XVCVDPUXDS)
139 if (LoadMI && LoadMI->
getOpcode() == PPC::LXVDSX)
144 if (DefMI && (Immed == 0 || Immed == 3)) {
145 if (DefOpc == PPC::LXVDSX || isConversionOfLoadAndSplat()) {
147 <<
"Optimizing load-and-splat/splat "
148 "to load-and-splat/copy: ");
151 TII->get(PPC::COPY),
MI.getOperand(0).getReg())
160 if (DefOpc == PPC::XXPERMDI) {
167 if ((FeedImmed == 0 || FeedImmed == 3) && FeedReg1 == FeedReg2) {
169 <<
"Optimizing splat/swap or splat/splat "
173 TII->get(PPC::COPY),
MI.getOperand(0).getReg())
182 else if ((Immed == 0 || Immed == 3)
183 && FeedImmed == 2 && FeedReg1 == FeedReg2) {
184 DEBUG(
dbgs() <<
"Optimizing swap/splat => splat: ");
188 MI.getOperand(3).setImm(3 - Immed);
194 else if (Immed == 2 && FeedImmed == 2 && FeedReg1 == FeedReg2) {
195 DEBUG(
dbgs() <<
"Optimizing swap/swap => copy: ");
198 TII->get(PPC::COPY),
MI.getOperand(0).getReg())
203 }
else if ((Immed == 0 || Immed == 3) && DefOpc == PPC::XXPERMDIs &&
211 DEBUG(
dbgs() <<
"Removing redundant splat: ");
221 unsigned MyOpcode =
MI.getOpcode();
222 unsigned OpNo = MyOpcode == PPC::XXSPLTW ? 1 : 2;
223 unsigned TrueReg = lookThruCopyLike(
MI.getOperand(OpNo).getReg());
230 auto isConvertOfSplat = [=]() ->
bool {
231 if (DefOpcode != PPC::XVCVSPSXWS && DefOpcode != PPC::XVCVSPUXWS)
237 return Splt && (Splt->
getOpcode() == PPC::LXVWSX ||
240 bool AlreadySplat = (MyOpcode == DefOpcode) ||
241 (MyOpcode == PPC::VSPLTB && DefOpcode == PPC::VSPLTBs) ||
242 (MyOpcode == PPC::VSPLTH && DefOpcode == PPC::VSPLTHs) ||
243 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::XXSPLTWs) ||
244 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::LXVWSX) ||
245 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::MTVSRWS)||
246 (MyOpcode == PPC::XXSPLTW && isConvertOfSplat());
250 DEBUG(
dbgs() <<
"Changing redundant splat to a copy: ");
253 MI.getOperand(0).getReg())
260 if (DefOpcode == PPC::XXSLDWI) {
265 unsigned SplatImm =
MI.getOperand(2).getImm();
266 if (ShiftOp1 == ShiftOp2) {
267 unsigned NewElem = (SplatImm + ShiftImm) & 0x3;
268 if (
MRI->hasOneNonDBGUse(ShiftRes)) {
269 DEBUG(
dbgs() <<
"Removing redundant shift: ");
274 DEBUG(
dbgs() <<
"Changing splat immediate from " << SplatImm <<
275 " to " << NewElem <<
" in instruction: ");
277 MI.getOperand(1).setReg(ShiftOp1);
278 MI.getOperand(2).setImm(NewElem);
283 case PPC::XVCVDPSP: {
285 unsigned TrueReg = lookThruCopyLike(
MI.getOperand(1).getReg());
292 if (DefMI && DefMI->
getOpcode() == PPC::XXPERMDI) {
306 auto removeFRSPIfPossible = [&](
MachineInstr *RoundInstr) {
307 if (RoundInstr->getOpcode() == PPC::FRSP &&
308 MRI->hasOneNonDBGUse(RoundInstr->getOperand(0).getReg())) {
310 unsigned ConvReg1 = RoundInstr->getOperand(1).getReg();
311 unsigned FRSPDefines = RoundInstr->getOperand(0).getReg();
317 DEBUG(
dbgs() <<
"Removing redundant FRSP:\n");
318 DEBUG(RoundInstr->dump());
319 DEBUG(
dbgs() <<
"As it feeds instruction:\n");
321 DEBUG(
dbgs() <<
"Through instruction:\n");
323 RoundInstr->eraseFromParent();
331 removeFRSPIfPossible(P1);
332 removeFRSPIfPossible(P2);
335 removeFRSPIfPossible(P1);
359 unsigned PPCMIPeephole::lookThruCopyLike(
unsigned SrcReg) {
385 "PowerPC MI Peephole Optimization",
false,
false)
389 char PPCMIPeephole::
ID = 0;
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
void initializePPCMIPeepholePass(PassRegistry &)
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
A Use represents the edge between a Value definition and its users.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
bool isCopyLike() const
Return true if the instruction behaves like a copy.
INITIALIZE_PASS_BEGIN(PPCMIPeephole, DEBUG_TYPE,"PowerPC MI Peephole Optimization", false, false) INITIALIZE_PASS_END(PPCMIPeephole
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned const MachineRegisterInfo * MRI
const MachineOperand & getOperand(unsigned i) const
PowerPC MI Peephole false
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
FunctionPass class - This class is used to implement most global optimizations.
void dump() const
dump - Print the current MachineFunction to cerr, useful for debugger use.
void dump(const TargetInstrInfo *TII=nullptr) const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringRef > StandardNames)
initialize - Initialize the set of available library functions based on the specified target triple...
bool isSubregToReg() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
PowerPC MI Peephole Optimization
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
unsigned getReg() const
getReg - Returns the register number.
FunctionPass * createPPCMIPeepholePass()
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...