36 #define DEBUG_TYPE "ppc-mi-peepholes" 38 STATISTIC(RemoveTOCSave,
"Number of TOC saves removed");
40 "Number of functions with multiple TOC saves that must be kept");
41 STATISTIC(NumEliminatedSExt,
"Number of eliminated sign-extensions");
42 STATISTIC(NumEliminatedZExt,
"Number of eliminated zero-extensions");
43 STATISTIC(NumOptADDLIs,
"Number of optimized ADD instruction fed by LI");
45 "Number of instructions converted to their immediate form");
46 STATISTIC(NumFunctionsEnteredInMIPeephole,
47 "Number of functions entered in PPC MI Peepholes");
49 "Number of fixed-point iterations converting reg-reg instructions " 54 cl::desc(
"Iterate to a fixed point when attempting to " 55 "convert reg-reg instructions to reg-imm"));
59 cl::desc(
"Convert eligible reg+reg instructions to reg+imm"));
63 cl::desc(
"enable elimination of sign-extensions"),
68 cl::desc(
"enable elimination of zero-extensions"),
91 bool simplifyCode(
void);
94 bool eliminateRedundantCompare(
void);
95 bool eliminateRedundantTOCSaves(std::map<MachineInstr *, bool> &TOCSaves);
96 void UpdateTOCSaves(std::map<MachineInstr *, bool> &TOCSaves,
112 return simplifyCode();
120 MDT = &getAnalysis<MachineDominatorTree>();
128 assert(Op &&
"Invalid Operand!");
144 if (Opcode == PPC::RLDICL || Opcode == PPC::RLDICLo ||
145 Opcode == PPC::RLDCL || Opcode == PPC::RLDCLo)
148 if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDICo) &&
152 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINMo ||
153 Opcode == PPC::RLWNM || Opcode == PPC::RLWNMo ||
154 Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&
158 if (Opcode == PPC::ANDIo) {
163 if (Opcode == PPC::CNTLZW || Opcode == PPC::CNTLZWo ||
164 Opcode == PPC::CNTTZW || Opcode == PPC::CNTTZWo ||
165 Opcode == PPC::CNTLZW8 || Opcode == PPC::CNTTZW8)
169 if (Opcode == PPC::CNTLZD || Opcode == PPC::CNTLZDo ||
170 Opcode == PPC::CNTTZD || Opcode == PPC::CNTTZDo)
174 if (Opcode == PPC::LHZ || Opcode == PPC::LHZX ||
175 Opcode == PPC::LHZ8 || Opcode == PPC::LHZX8 ||
176 Opcode == PPC::LHZU || Opcode == PPC::LHZUX ||
177 Opcode == PPC::LHZU8 || Opcode == PPC::LHZUX8)
180 if (Opcode == PPC::LBZ || Opcode == PPC::LBZX ||
181 Opcode == PPC::LBZ8 || Opcode == PPC::LBZX8 ||
182 Opcode == PPC::LBZU || Opcode == PPC::LBZUX ||
183 Opcode == PPC::LBZU8 || Opcode == PPC::LBZUX8)
198 void PPCMIPeephole::UpdateTOCSaves(
199 std::map<MachineInstr *, bool> &TOCSaves,
MachineInstr *MI) {
202 for (
auto It = TOCSaves.begin(); It != TOCSaves.end(); It++ ) {
206 if (It->second && MDT->
dominates(MI, CurrInst))
219 bool PPCMIPeephole::simplifyCode(
void) {
222 std::map<MachineInstr *, bool> TOCSaves;
224 NumFunctionsEnteredInMIPeephole++;
229 bool SomethingChanged =
false;
231 NumFixedPointIterations++;
232 SomethingChanged =
false;
243 NumConvertedToImmediateForm++;
244 SomethingChanged =
true;
282 UpdateTOCSaves(TOCSaves, &MI);
304 if (TrueReg1 == TrueReg2
307 unsigned DefOpc = DefMI ? DefMI->
getOpcode() : 0;
313 auto isConversionOfLoadAndSplat = [=]() ->
bool {
314 if (DefOpc != PPC::XVCVDPSXDS && DefOpc != PPC::XVCVDPUXDS)
320 if (LoadMI && LoadMI->
getOpcode() == PPC::LXVDSX)
325 if (DefMI && (Immed == 0 || Immed == 3)) {
326 if (DefOpc == PPC::LXVDSX || isConversionOfLoadAndSplat()) {
328 "to load-and-splat/copy: ");
347 if ((FeedImmed == 0 || FeedImmed == 3) && FeedReg1 == FeedReg2) {
361 else if ((Immed == 0 || Immed == 3)
362 && FeedImmed == 2 && FeedReg1 == FeedReg2) {
373 else if (Immed == 2 && FeedImmed == 2 && FeedReg1 == FeedReg2) {
382 }
else if ((Immed == 0 || Immed == 3) && DefOpc == PPC::XXPERMDIs &&
401 unsigned OpNo = MyOpcode == PPC::XXSPLTW ? 1 : 2;
410 auto isConvertOfSplat = [=]() ->
bool {
411 if (DefOpcode != PPC::XVCVSPSXWS && DefOpcode != PPC::XVCVSPUXWS)
417 return Splt && (Splt->
getOpcode() == PPC::LXVWSX ||
420 bool AlreadySplat = (MyOpcode == DefOpcode) ||
421 (MyOpcode == PPC::VSPLTB && DefOpcode == PPC::VSPLTBs) ||
422 (MyOpcode == PPC::VSPLTH && DefOpcode == PPC::VSPLTHs) ||
423 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::XXSPLTWs) ||
424 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::LXVWSX) ||
425 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::MTVSRWS)||
426 (MyOpcode == PPC::XXSPLTW && isConvertOfSplat());
440 if (DefOpcode == PPC::XXSLDWI) {
446 if (ShiftOp1 == ShiftOp2) {
447 unsigned NewElem = (SplatImm + ShiftImm) & 0x3;
455 <<
" to " << NewElem <<
" in instruction: ");
463 case PPC::XVCVDPSP: {
489 auto removeFRSPIfPossible = [&](
MachineInstr *RoundInstr) {
490 if (RoundInstr->getOpcode() == PPC::FRSP &&
493 unsigned ConvReg1 = RoundInstr->getOperand(1).getReg();
494 unsigned FRSPDefines = RoundInstr->getOperand(0).getReg();
506 RoundInstr->eraseFromParent();
514 removeFRSPIfPossible(P1);
515 removeFRSPIfPossible(P2);
518 removeFRSPIfPossible(P1);
524 case PPC::EXTSH8_32_64: {
537 auto is64Bit = [] (
unsigned Opcode) {
538 return Opcode == PPC::EXTSH8;
540 auto isXForm = [] (
unsigned Opcode) {
541 return Opcode == PPC::LHZX;
543 auto getSextLoadOp = [] (
bool is64Bit,
bool isXForm) {
545 if (isXForm)
return PPC::LHAX8;
546 else return PPC::LHA8;
548 if (isXForm)
return PPC::LHAX;
549 else return PPC::LHA;
568 case PPC::EXTSW_32_64: {
581 auto is64Bit = [] (
unsigned Opcode) {
582 return Opcode == PPC::EXTSW || Opcode == PPC::EXTSW_32_64;
584 auto isXForm = [] (
unsigned Opcode) {
585 return Opcode == PPC::LWZX;
587 auto getSextLoadOp = [] (
bool is64Bit,
bool isXForm) {
589 if (isXForm)
return PPC::LWAX;
590 else return PPC::LWA;
592 if (isXForm)
return PPC::LWAX_32;
593 else return PPC::LWA_32;
607 }
else if (MI.
getOpcode() == PPC::EXTSW_32_64 &&
613 MF->getRegInfo().createVirtualRegister(&PPC::G8RCRegClass);
644 if (!(SrcMI && SrcMI->
getOpcode() == PPC::INSERT_SUBREG &&
651 if (ImpDefMI->
getOpcode() != PPC::IMPLICIT_DEF)
break;
654 if (SubRegMI->
getOpcode() == PPC::COPY) {
660 unsigned KnownZeroCount = getKnownLeadingZeroCount(SrcMI, TII);
680 assert(PhiOp &&
"Invalid Operand!");
683 return DefPhiMI && (DefPhiMI->
getOpcode() == PPC::PHI) &&
689 assert(PhiOp &&
"Invalid Operand!");
690 assert(DominatorOp &&
"Invalid Operand!");
692 MachineInstr *DefDomMI = getVRegDefOrNull(DominatorOp, MRI);
711 if (isSingleUsePHI(&Op2) && dominatesAllSingleUseLIs(&Op1, &Op2))
713 else if (!isSingleUsePHI(&Op1) || !dominatesAllSingleUseLIs(&Op2, &Op1))
717 unsigned DominatorReg = Op2.
getReg();
720 ? &PPC::G8RC_and_G8RC_NOX0RegClass
721 : &PPC::GPRC_and_GPRC_NOR0RegClass;
745 .addReg(DominatorReg)
773 Simplified |= eliminateRedundantTOCSaves(TOCSaves);
775 Simplified |= eliminateRedundantCompare();
787 static bool isSupportedCmpOp(
unsigned opCode) {
788 return (opCode == PPC::CMPLD || opCode == PPC::CMPD ||
789 opCode == PPC::CMPLW || opCode == PPC::CMPW ||
790 opCode == PPC::CMPLDI || opCode == PPC::CMPDI ||
791 opCode == PPC::CMPLWI || opCode == PPC::CMPWI);
794 static bool is64bitCmpOp(
unsigned opCode) {
795 return (opCode == PPC::CMPLD || opCode == PPC::CMPD ||
796 opCode == PPC::CMPLDI || opCode == PPC::CMPDI);
799 static bool isSignedCmpOp(
unsigned opCode) {
800 return (opCode == PPC::CMPD || opCode == PPC::CMPW ||
801 opCode == PPC::CMPDI || opCode == PPC::CMPWI);
804 static unsigned getSignedCmpOpCode(
unsigned opCode) {
805 if (opCode == PPC::CMPLD)
return PPC::CMPD;
806 if (opCode == PPC::CMPLW)
return PPC::CMPW;
807 if (opCode == PPC::CMPLDI)
return PPC::CMPDI;
808 if (opCode == PPC::CMPLWI)
return PPC::CMPWI;
816 bool SignedCmp = isSignedCmpOp(CMPI->
getOpcode());
817 if ((!SignedCmp && Imm == 0) || (SignedCmp && Imm == 0x8000))
835 bool SignedCmp = isSignedCmpOp(CMPI->
getOpcode());
836 if ((!SignedCmp && Imm == 0xFFFF) || (SignedCmp && Imm == 0x7FFF))
851 static unsigned getIncomingRegForBlock(
MachineInstr *Phi,
867 unsigned SrcReg =
Reg;
869 unsigned NextReg = SrcReg;
872 NextReg = getIncomingRegForBlock(Inst, BB1);
891 auto BII = BB.getFirstInstrTerminator();
895 if (BB.succ_size() == 2 &&
896 BII != BB.instr_end() &&
897 (*BII).getOpcode() == PPC::BCC &&
898 (*BII).getOperand(1).isReg()) {
900 unsigned CndReg = (*BII).getOperand(1).getReg();
925 return BB.succ_size() == 1;
928 if (!isEligibleBB(MBB))
932 if (NumPredBBs == 1) {
934 if (isEligibleBB(*TmpMBB)) {
936 MBBtoMoveCmp =
nullptr;
940 else if (NumPredBBs == 2) {
948 if (isEligibleBB(*Pred1MBB) && isEligibleForMoveCmp(*Pred2MBB)) {
953 else if (isEligibleBB(*Pred2MBB) && isEligibleForMoveCmp(*Pred1MBB)) {
964 for (
int I = 1;
I <= 2;
I++)
972 MBBtoMoveCmp = Pred2MBB;
983 bool PPCMIPeephole::eliminateRedundantTOCSaves(
984 std::map<MachineInstr *, bool> &TOCSaves) {
985 bool Simplified =
false;
987 for (
auto TOCSave : TOCSaves) {
988 if (!TOCSave.second) {
989 TOCSave.first->eraseFromParent();
1025 bool PPCMIPeephole::eliminateRedundantCompare(
void) {
1026 bool Simplified =
false;
1058 if (!eligibleForCompareElimination(MBB2, MBB1, MBBtoMoveCmp, MRI))
1066 bool IsPartiallyRedundant = (MBBtoMoveCmp !=
nullptr);
1070 if (!isSupportedCmpOp(CMPI1->
getOpcode()) ||
1071 !isSupportedCmpOp(CMPI2->
getOpcode()) ||
1075 unsigned NewOpCode = 0;
1076 unsigned NewPredicate1 = 0, NewPredicate2 = 0;
1077 int16_t Imm1 = 0, NewImm1 = 0, Imm2 = 0, NewImm2 = 0;
1078 bool SwapOperands =
false;
1090 if (!
I->getOperand(2).isImm())
1092 int16_t Imm = (int16_t)
I->getOperand(2).getImm();
1096 if (isEqOrNe(BI2) && !CmpAgainstImmWithSignBit(CMPI2) &&
1099 else if (isEqOrNe(BI1) && !CmpAgainstImmWithSignBit(CMPI1) &&
1109 nullptr,
nullptr,
MRI);
1111 nullptr,
nullptr,
MRI);
1117 if (Cmp1Operand1 == Cmp2Operand1 && Cmp1Operand2 == Cmp2Operand2) {
1120 else if (Cmp1Operand1 == Cmp2Operand2 && Cmp1Operand2 == Cmp2Operand1) {
1127 SwapOperands =
true;
1135 nullptr,
nullptr,
MRI);
1138 if (Cmp1Operand1 != Cmp2Operand1)
1146 if (Imm1 != Imm2 && (!isEqOrNe(BI2) || !isEqOrNe(BI1))) {
1147 int Diff = Imm1 - Imm2;
1148 if (Diff < -2 || Diff > 2)
1151 unsigned PredToInc1 = getPredicateToIncImm(BI1, CMPI1);
1152 unsigned PredToDec1 = getPredicateToDecImm(BI1, CMPI1);
1153 unsigned PredToInc2 = getPredicateToIncImm(BI2, CMPI2);
1154 unsigned PredToDec2 = getPredicateToDecImm(BI2, CMPI2);
1156 if (PredToInc2 && PredToDec1) {
1157 NewPredicate2 = PredToInc2;
1158 NewPredicate1 = PredToDec1;
1163 else if (Diff == 1) {
1166 NewPredicate2 = PredToInc2;
1168 else if (PredToDec1) {
1170 NewPredicate1 = PredToDec1;
1173 else if (Diff == -1) {
1176 NewPredicate2 = PredToDec2;
1178 else if (PredToInc1) {
1180 NewPredicate1 = PredToInc1;
1183 else if (Diff == -2) {
1184 if (PredToDec2 && PredToInc1) {
1185 NewPredicate2 = PredToDec2;
1186 NewPredicate1 = PredToInc1;
1194 if (NewImm2 != NewImm1)
1198 LLVM_DEBUG(
dbgs() <<
"Optimize two pairs of compare and branch:\n");
1205 if (NewOpCode != 0 && NewOpCode != CMPI1->
getOpcode()) {
1206 CMPI1->
setDesc(TII->get(NewOpCode));
1208 if (NewPredicate1) {
1211 if (NewPredicate2) {
1214 if (NewImm1 != Imm1) {
1218 if (IsPartiallyRedundant) {
1227 if (NewImm2 != Imm2)
1230 for (
int I = 1;
I <= 2;
I++) {
1237 "We cannot support if an operand comes from this BB.");
1238 unsigned SrcReg = getIncomingRegForBlock(Inst, MBBtoMoveCmp);
1247 BuildMI(MBB2, MBB2.begin(), DL,
1248 TII->get(PPC::PHI), NewVReg)
1265 if (IsPartiallyRedundant) {
1268 <<
" to handle partial redundancy.\n");
1281 "PowerPC MI Peephole Optimization",
false,
false)
1285 char PPCMIPeephole::ID = 0;
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
MachineBasicBlock * getMBB() const
This class represents lattice values for constants.
instr_iterator getFirstInstrTerminator()
Same getFirstTerminator but it ignores bundles and return an instr_iterator instead.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned getReg() const
getReg - Returns the register number.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
void initializePPCMIPeepholePass(PassRegistry &)
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
iterator_range< mop_iterator > operands()
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void dump() const
dump - Print the current MachineFunction to cerr, useful for debugger use.
std::size_t countLeadingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the most significant bit to the least stopping at the first 1...
bool isSignExtended(const MachineInstr &MI, const unsigned depth=0) const
Return true if the output of the instruction is always a sign-extended, i.e.
AnalysisUsage & addRequired()
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
unsigned getNumOperands() const
Retuns the total number of operands.
A Use represents the edge between a Value definition and its users.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
INITIALIZE_PASS_BEGIN(PPCMIPeephole, DEBUG_TYPE, "PowerPC MI Peephole Optimization", false, false) INITIALIZE_PASS_END(PPCMIPeephole
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
bool isTOCSaveMI(const MachineInstr &MI) const
static cl::opt< bool > EnableSExtElimination("ppc-eliminate-signext", cl::desc("enable elimination of sign-extensions"), cl::init(false), cl::Hidden)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static cl::opt< bool > ConvertRegReg("ppc-convert-rr-to-ri", cl::Hidden, cl::init(true), cl::desc("Convert eligible reg+reg instructions to reg+imm"))
initializer< Ty > init(const Ty &Val)
MachineInstrBundleIterator< MachineInstr > iterator
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool is64Bit(const char *name)
Represent the analysis usage information of a pass.
use_instr_iterator use_instr_begin(unsigned RegNo) const
void setImm(int64_t immVal)
FunctionPass class - This class is used to implement most global optimizations.
std::vector< MachineBasicBlock * >::iterator pred_iterator
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
pred_iterator pred_begin()
unsigned getPredicateHint(Predicate Opcode)
Return the hint bits of the predicate.
bool isDebugInstr() const
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void setIsKill(bool Val=true)
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
static cl::opt< bool > FixedPointRegToImm("ppc-reg-to-imm-fixed-point", cl::Hidden, cl::init(true), cl::desc("Iterate to a fixed point when attempting to " "convert reg-reg instructions to reg-imm"))
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
MachineOperand class - Representation of each machine instruction operand.
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
MachineInstrBuilder MachineInstrBuilder & DefMI
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
unsigned pred_size() const
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringRef > StandardNames)
Initialize the set of available library functions based on the specified target triple.
const MachineBasicBlock * getParent() 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
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
static cl::opt< bool > EnableZExtElimination("ppc-eliminate-zeroext", cl::desc("enable elimination of zero-extensions"), cl::init(false), cl::Hidden)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
bool hasOneNonDBGUse(unsigned RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug instruction using the specified regis...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
FunctionPass * createPPCMIPeepholePass()
unsigned getPredicateCondition(Predicate Opcode)
Return the condition without hint bits.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void setRegClass(unsigned Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
void RemoveOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
const MachineOperand & getOperand(unsigned i) const
const PPCRegisterInfo & getRegisterInfo() const
getRegisterInfo - TargetInstrInfo is a superset of MRegister info.
virtual unsigned lookThruCopyLike(unsigned SrcReg, const MachineRegisterInfo *MRI) const
Returns the original SrcReg unless it is the target of a copy-like operation, in which case we chain ...
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool convertToImmediateForm(MachineInstr &MI, MachineInstr **KilledDef=nullptr) const
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
XXPERMDI - The PPC XXPERMDI instruction.
bool isZeroExtended(const MachineInstr &MI, const unsigned depth=0) const
Return true if the output of the instruction is always zero-extended, i.e.
Predicate getSwappedPredicate(Predicate Opcode)
Assume the condition register is set by MI(a,b), return the predicate if we modify the instructions s...