29#define DEBUG_TYPE "ppc-pre-emit-peephole"
32 "Number of r+r instructions converted to r+i in pre-emit peephole");
34 "Number of instructions deleted in pre-emit peephole");
36 "Number of self copy instructions eliminated");
38 "Number of folding frame offset by using r+r in pre-emit peephole");
40 "Number of compares eliminated in pre-emit peephole");
44 cl::desc(
"enable PC Relative linker optimization"));
48 cl::desc(
"Run pre-emit peephole optimizations."));
52 cl::desc(
"Set the Data Stream Control Register."));
57 switch (
Use.getOpcode()) {
98 PPCPreEmitPeephole() : MachineFunctionPass(ID) {}
100 void getAnalysisUsage(AnalysisUsage &AU)
const override {
104 MachineFunctionProperties getRequiredProperties()
const override {
105 return MachineFunctionProperties().setNoVRegs();
117 bool removeRedundantLIs(MachineBasicBlock &
MBB,
118 const TargetRegisterInfo *
TRI) {
119 LLVM_DEBUG(
dbgs() <<
"Remove redundant load immediates from MBB:\n";
122 DenseSet<MachineInstr *> InstrsToErase;
126 if (InstrsToErase.contains(&*BBI))
129 unsigned Opc = BBI->getOpcode();
130 if (
Opc != PPC::LI &&
Opc != PPC::LI8 &&
Opc != PPC::LIS &&
135 if (!BBI->getOperand(1).isImm())
137 assert(BBI->getOperand(0).isReg() &&
138 "Expected a register for the first operand");
140 LLVM_DEBUG(
dbgs() <<
"Scanning after load immediate: "; BBI->dump(););
143 int64_t
Imm = BBI->getOperand(1).getImm();
144 MachineOperand *DeadOrKillToUnset =
nullptr;
145 if (BBI->getOperand(0).isDead()) {
146 DeadOrKillToUnset = &BBI->getOperand(0);
148 <<
" from load immediate " << *BBI
149 <<
" is a unsetting candidate\n");
153 for (
auto AfterBBI = std::next(BBI); AfterBBI !=
MBB.
instr_end();
157 int KillIdx = AfterBBI->findRegisterUseOperandIdx(
Reg,
TRI,
true);
161 if (KillIdx != -1 && AfterBBI->getOperand(KillIdx).isImplicit()) {
163 <<
"Encountered an implicit kill, cannot proceed: ");
169 assert(!DeadOrKillToUnset &&
"Shouldn't kill same register twice");
170 DeadOrKillToUnset = &AfterBBI->getOperand(KillIdx);
172 <<
" Kill flag of " << *DeadOrKillToUnset <<
" from "
173 << *AfterBBI <<
" is a unsetting candidate\n");
176 if (!AfterBBI->modifiesRegister(
Reg,
TRI))
180 if (AfterBBI->getOpcode() !=
Opc)
182 assert(AfterBBI->getOperand(0).isReg() &&
183 "Expected a register for the first operand");
186 if (!AfterBBI->getOperand(1).isImm() ||
187 AfterBBI->getOperand(1).getImm() != Imm)
193 if (DeadOrKillToUnset) {
195 <<
" Unset dead/kill flag of " << *DeadOrKillToUnset
196 <<
" from " << *DeadOrKillToUnset->
getParent());
197 if (DeadOrKillToUnset->
isDef())
203 AfterBBI->findRegisterDefOperand(
Reg,
TRI,
true,
true);
204 if (DeadOrKillToUnset)
206 <<
" Dead flag of " << *DeadOrKillToUnset <<
" from "
207 << *AfterBBI <<
" is a unsetting candidate\n");
208 InstrsToErase.insert(&*AfterBBI);
214 for (MachineInstr *
MI : InstrsToErase) {
215 MI->eraseFromParent();
217 NumRemovedInPreEmit += InstrsToErase.size();
218 return !InstrsToErase.empty();
223 bool isGOTPLDpc(MachineInstr &Instr) {
224 if (
Instr.getOpcode() != PPC::PLDpc)
228 const MachineOperand &LoadedAddressReg =
Instr.getOperand(0);
229 if (!LoadedAddressReg.
isReg())
233 const MachineOperand &SymbolOp =
Instr.getOperand(1);
241 bool addLinkerOpt(MachineBasicBlock &
MBB,
const TargetRegisterInfo *
TRI) {
248 if (!MF->
getSubtarget<PPCSubtarget>().isUsingPCRelativeCalls())
252 struct GOTDefUsePair {
262 bool MadeChange =
false;
268 if (isGOTPLDpc(*BBI)) {
270 BBI->getOperand(0).getReg(),
271 PPC::NoRegister,
true};
277 if (CandPairs.
empty())
283 for (
unsigned Idx = 0; Idx < CandPairs.
size(); Idx++) {
284 GOTDefUsePair &Pair = CandPairs[Idx];
287 if (!BBI->readsRegister(Pair.DefReg,
TRI) &&
288 !BBI->modifiesRegister(Pair.DefReg,
TRI))
293 const MachineOperand *UseOp =
294 hasPCRelativeForm(*BBI) ? &BBI->getOperand(2) :
nullptr;
297 if (UseOp && UseOp->
isReg() && UseOp->
getReg() == Pair.DefReg &&
300 Pair.UseReg = BBI->getOperand(0).getReg();
308 for (
auto Pair = ValidPairs.
begin(); Pair != ValidPairs.
end(); Pair++) {
310 assert(Pair->UseInst.isValid() && Pair->StillValid &&
311 "Kept an invalid def/use pair for GOT PCRel opt");
317 for (; BBI != Pair->UseInst; ++BBI) {
318 if (BBI->readsRegister(Pair->UseReg,
TRI) ||
319 BBI->modifiesRegister(Pair->UseReg,
TRI)) {
320 Pair->StillValid =
false;
325 if (!Pair->StillValid)
334 MachineOperand ImplDef =
336 MachineOperand ImplUse =
338 Pair->DefInst->addOperand(ImplDef);
339 Pair->UseInst->addOperand(ImplUse);
344 MachineOperand PCRelLabel =
346 Pair->DefInst->addOperand(*MF, PCRelLabel);
347 Pair->UseInst->addOperand(*MF, PCRelLabel);
365 bool removeAccPrimeUnprime(MachineBasicBlock &
MBB) {
366 DenseSet<MachineInstr *> InstrsToErase;
368 SmallVector<MachineInstr *, 8> Candidates(
369 PPC::UACCRCRegClass.getNumRegs(),
nullptr);
372 unsigned Opc = BBI.getOpcode();
375 if (
Opc == PPC::XXMTACC) {
376 Register Acc = BBI.getOperand(0).getReg();
378 "Unexpected register for XXMTACC");
379 Candidates[Acc - PPC::ACC0] = &BBI;
383 else if (
Opc == PPC::XXMFACC) {
384 Register Acc = BBI.getOperand(0).getReg();
386 "Unexpected register for XXMFACC");
387 if (!Candidates[Acc - PPC::ACC0])
389 InstrsToErase.
insert(&BBI);
390 InstrsToErase.
insert(Candidates[Acc - PPC::ACC0]);
395 for (MachineOperand &Operand : BBI.operands()) {
396 if (!Operand.isReg())
400 Candidates[
Reg - PPC::ACC0] =
nullptr;
405 for (MachineInstr *
MI : InstrsToErase)
406 MI->eraseFromParent();
407 NumRemovedInPreEmit += InstrsToErase.size();
408 return !InstrsToErase.empty();
411 bool runOnMachineFunction(MachineFunction &MF)
override {
418 MachineBasicBlock &
MBB = MF.
front();
423 const PPCInstrInfo *
TII =
440 errs() <<
"Warning: Ran out of registers - Unable to set DSCR as "
448 SmallVector<MachineInstr *, 4> InstrsToErase;
449 for (MachineBasicBlock &
MBB : MF)
450 for (MachineInstr &
MI :
MBB)
451 if (
MI.getOpcode() == PPC::UNENCODED_NOP)
453 for (MachineInstr *
MI : InstrsToErase)
454 MI->eraseFromParent();
458 const PPCInstrInfo *
TII = MF.getSubtarget<PPCSubtarget>().getInstrInfo();
459 const TargetRegisterInfo *
TRI = MF.getSubtarget().getRegisterInfo();
460 SmallVector<MachineInstr *, 4> InstrsToErase;
461 for (MachineBasicBlock &
MBB : MF) {
465 for (MachineInstr &
MI :
MBB) {
466 unsigned Opc =
MI.getOpcode();
467 if (
Opc == PPC::UNENCODED_NOP) {
473 const MCInstrDesc &MCID =
TII->get(
Opc);
475 MI.getOperand(0).getReg() ==
MI.getOperand(1).getReg() &&
476 MI.getOperand(0).getReg() ==
MI.getOperand(2).getReg()) {
477 NumberOfSelfCopies++;
484 MI.getOperand(0).getReg() ==
MI.getOperand(1).getReg()) {
485 NumberOfSelfCopies++;
492 MachineInstr *DefMIToErase =
nullptr;
493 SmallSet<Register, 4> UpdatedRegs;
494 if (
TII->convertToImmediateForm(
MI, UpdatedRegs, &DefMIToErase)) {
496 NumRRConvertedInPreEmit++;
503 if (
TII->foldFrameOffset(
MI)) {
505 NumFrameOffFoldInPreEmit++;
506 LLVM_DEBUG(
dbgs() <<
"Frame offset folding by using index form: ");
509 if (
TII->optimizeCmpPostRA(
MI)) {
525 MachineInstr *Br = &*
I;
528 MachineInstr *CRSetMI =
nullptr;
531 bool SeenUse =
false;
533 for (It++; It != Er; It++) {
534 if (It->modifiesRegister(CRBit,
TRI)) {
535 if ((It->getOpcode() == PPC::CRUNSET ||
536 It->getOpcode() == PPC::CRSET) &&
537 It->getOperand(0).getReg() == CRBit)
541 if (It->readsRegister(CRBit,
TRI))
544 if (!CRSetMI)
continue;
547 if ((Br->
getOpcode() == PPC::BCn && CRSetOp == PPC::CRSET) ||
548 (Br->
getOpcode() == PPC::BC && CRSetOp == PPC::CRUNSET)) {
557 for (; It != Er; It++) {
558 if (It->isDebugInstr())
continue;
559 assert(It->isTerminator() &&
"Non-terminator after a terminator");
579 if (SuccMBB->isLiveIn(CRBit) || SuccMBB->isLiveIn(CRReg)) {
587 for (MachineInstr *
MI : InstrsToErase) {
588 LLVM_DEBUG(
dbgs() <<
"PPC pre-emit peephole: erasing instruction: ");
590 MI->eraseFromParent();
591 NumRemovedInPreEmit++;
600char PPCPreEmitPeephole::
ID = 0;
603 return new PPCPreEmitPeephole();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static Register UseReg(const MachineOperand &MO)
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static cl::opt< bool > EnablePCRelLinkerOpt("ppc-pcrel-linker-opt", cl::Hidden, cl::init(true), cl::desc("enable PC Relative linker optimization"))
static cl::opt< bool > RunPreEmitPeephole("ppc-late-peephole", cl::Hidden, cl::init(true), cl::desc("Run pre-emit peephole optimizations."))
static cl::opt< uint64_t > DSCRValue("ppc-set-dscr", cl::Hidden, cl::desc("Set the Data Stream Control Register."))
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file declares the machine register scavenger class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
FunctionPass class - This class is used to implement most global optimizations.
bool hasExternalLinkage() const
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
Insert branch code into the end of the specified MachineBasicBlock.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
instr_iterator instr_begin()
LLVM_ABI void dump() const
LLVM_ABI void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
LLVM_ABI bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
instr_iterator instr_end()
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< succ_iterator > successors()
LLVM_ABI instr_iterator getFirstInstrTerminator()
Same getFirstTerminator but it ignores bundles and return an instr_iterator instead.
MachineInstrBundleIterator< MachineInstr > iterator
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.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MCContext & getContext() const
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineBasicBlock & front() const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
static MachineOperand CreateMCSymbol(MCSymbol *Sym, unsigned TargetFlags=0)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
void setIsDead(bool Val=true)
void setIsKill(bool Val=true)
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
unsigned getTargetFlags() const
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
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)
static bool isSameClassPhysRegCopy(unsigned Opcode)
static bool hasGOTFlag(unsigned TF)
Register FindUnusedReg(const TargetRegisterClass *RC) const
Find an unused register of the specified register class.
void enterBasicBlock(MachineBasicBlock &MBB)
Start tracking liveness from the begin of basic block MBB.
iterator erase(const_iterator CI)
void push_back(const T &Elt)
A Use represents the edge between a Value definition and its users.
std::pair< iterator, bool > insert(const ValueT &V)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ MO_PCREL_OPT_FLAG
MO_PCREL_OPT_FLAG - If this bit is set the operand is part of a PC Relative linker optimization.
@ Kill
The last use of a register.
initializer< Ty > init(const Ty &Val)
NodeAddr< InstrNode * > Instr
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createPPCPreEmitPeepholePass()
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static unsigned getCRFromCRBit(unsigned SrcReg)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
ArrayRef(const T &OneElt) -> ArrayRef< T >