31#define DEBUG_TYPE "ppc-pre-emit-peephole"
34 "Number of r+r instructions converted to r+i in pre-emit peephole");
36 "Number of instructions deleted in pre-emit peephole");
38 "Number of self copy instructions eliminated");
40 "Number of folding frame offset by using r+r in pre-emit peephole");
42 "Number of compares eliminated in pre-emit peephole");
46 cl::desc(
"enable PC Relative linker optimization"));
50 cl::desc(
"Run pre-emit peephole optimizations."));
54 cl::desc(
"Set the Data Stream Control Register."));
59 switch (
Use.getOpcode()) {
110 MachineFunctionProperties::Property::NoVRegs);
124 LLVM_DEBUG(
dbgs() <<
"Remove redundant load immediates from MBB:\n";
131 if (InstrsToErase.contains(&*BBI))
134 unsigned Opc = BBI->getOpcode();
135 if (Opc != PPC::LI && Opc != PPC::LI8 && Opc != PPC::LIS &&
140 if (!BBI->getOperand(1).isImm())
142 assert(BBI->getOperand(0).isReg() &&
143 "Expected a register for the first operand");
145 LLVM_DEBUG(
dbgs() <<
"Scanning after load immediate: "; BBI->dump(););
148 int64_t
Imm = BBI->getOperand(1).getImm();
150 if (BBI->getOperand(0).isDead()) {
151 DeadOrKillToUnset = &BBI->getOperand(0);
153 <<
" from load immediate " << *BBI
154 <<
" is a unsetting candidate\n");
158 for (
auto AfterBBI = std::next(BBI); AfterBBI !=
MBB.
instr_end();
162 int KillIdx = AfterBBI->findRegisterUseOperandIdx(Reg,
true,
TRI);
166 if (KillIdx != -1 && AfterBBI->getOperand(KillIdx).isImplicit()) {
168 <<
"Encountered an implicit kill, cannot proceed: ");
174 assert(!DeadOrKillToUnset &&
"Shouldn't kill same register twice");
175 DeadOrKillToUnset = &AfterBBI->getOperand(KillIdx);
177 <<
" Kill flag of " << *DeadOrKillToUnset <<
" from "
178 << *AfterBBI <<
" is a unsetting candidate\n");
181 if (!AfterBBI->modifiesRegister(Reg,
TRI))
185 if (AfterBBI->getOpcode() != Opc)
187 assert(AfterBBI->getOperand(0).isReg() &&
188 "Expected a register for the first operand");
191 if (!AfterBBI->getOperand(1).isImm() ||
192 AfterBBI->getOperand(1).getImm() != Imm)
198 if (DeadOrKillToUnset) {
200 <<
" Unset dead/kill flag of " << *DeadOrKillToUnset
201 <<
" from " << *DeadOrKillToUnset->
getParent());
202 if (DeadOrKillToUnset->
isDef())
208 AfterBBI->findRegisterDefOperand(Reg,
true,
true,
TRI);
209 if (DeadOrKillToUnset)
211 <<
" Dead flag of " << *DeadOrKillToUnset <<
" from "
212 << *AfterBBI <<
" is a unsetting candidate\n");
213 InstrsToErase.insert(&*AfterBBI);
220 MI->eraseFromParent();
222 NumRemovedInPreEmit += InstrsToErase.size();
223 return !InstrsToErase.empty();
234 if (!LoadedAddressReg.
isReg())
257 struct GOTDefUsePair {
267 bool MadeChange =
false;
273 if (isGOTPLDpc(*BBI)) {
275 BBI->getOperand(0).getReg(),
276 PPC::NoRegister,
true};
282 if (CandPairs.
empty())
289 GOTDefUsePair &Pair = CandPairs[
Idx];
292 if (!BBI->readsRegister(Pair.DefReg,
TRI) &&
293 !BBI->modifiesRegister(Pair.DefReg,
TRI))
299 hasPCRelativeForm(*BBI) ? &BBI->getOperand(2) :
nullptr;
302 if (UseOp && UseOp->
isReg() && UseOp->
getReg() == Pair.DefReg &&
305 Pair.UseReg = BBI->getOperand(0).getReg();
313 for (
auto Pair = ValidPairs.
begin(); Pair != ValidPairs.
end(); Pair++) {
315 assert(Pair->UseInst.isValid() && Pair->StillValid &&
316 "Kept an invalid def/use pair for GOT PCRel opt");
322 for (; BBI != Pair->UseInst; ++BBI) {
323 if (BBI->readsRegister(Pair->UseReg,
TRI) ||
324 BBI->modifiesRegister(Pair->UseReg,
TRI)) {
325 Pair->StillValid =
false;
330 if (!Pair->StillValid)
343 Pair->DefInst->addOperand(ImplDef);
344 Pair->UseInst->addOperand(ImplUse);
351 Pair->DefInst->addOperand(*MF, PCRelLabel);
352 Pair->UseInst->addOperand(*MF, PCRelLabel);
374 PPC::UACCRCRegClass.getNumRegs(),
nullptr);
377 unsigned Opc = BBI.getOpcode();
380 if (Opc == PPC::XXMTACC) {
381 Register Acc = BBI.getOperand(0).getReg();
383 "Unexpected register for XXMTACC");
384 Candidates[Acc - PPC::ACC0] = &BBI;
388 else if (Opc == PPC::XXMFACC) {
389 Register Acc = BBI.getOperand(0).getReg();
391 "Unexpected register for XXMFACC");
392 if (!Candidates[Acc - PPC::ACC0])
394 InstrsToErase.
insert(&BBI);
395 InstrsToErase.
insert(Candidates[Acc - PPC::ACC0]);
401 if (!Operand.isReg())
404 if (PPC::ACCRCRegClass.
contains(Reg))
405 Candidates[
Reg - PPC::ACC0] =
nullptr;
411 MI->eraseFromParent();
412 NumRemovedInPreEmit += InstrsToErase.size();
413 return !InstrsToErase.empty();
445 errs() <<
"Warning: Ran out of registers - Unable to set DSCR as "
456 if (
MI.getOpcode() == PPC::UNENCODED_NOP)
459 MI->eraseFromParent();
462 bool Changed =
false;
467 Changed |= removeRedundantLIs(
MBB,
TRI);
468 Changed |= addLinkerOpt(
MBB,
TRI);
469 Changed |= removeAccPrimeUnprime(
MBB);
471 unsigned Opc =
MI.getOpcode();
472 if (Opc == PPC::UNENCODED_NOP) {
480 MI.getOperand(0).getReg() ==
MI.getOperand(1).getReg() &&
481 MI.getOperand(0).getReg() ==
MI.getOperand(2).getReg()) {
482 NumberOfSelfCopies++;
489 MI.getOperand(0).getReg() ==
MI.getOperand(1).getReg()) {
490 NumberOfSelfCopies++;
498 if (
TII->convertToImmediateForm(
MI, &DefMIToErase)) {
500 NumRRConvertedInPreEmit++;
507 if (
TII->foldFrameOffset(
MI)) {
509 NumFrameOffFoldInPreEmit++;
510 LLVM_DEBUG(
dbgs() <<
"Frame offset folding by using index form: ");
513 if (
TII->optimizeCmpPostRA(
MI)) {
535 bool SeenUse =
false;
537 for (It++; It != Er; It++) {
538 if (It->modifiesRegister(CRBit,
TRI)) {
539 if ((It->getOpcode() == PPC::CRUNSET ||
540 It->getOpcode() == PPC::CRSET) &&
541 It->getOperand(0).getReg() == CRBit)
545 if (It->readsRegister(CRBit,
TRI))
548 if (!CRSetMI)
continue;
551 if ((Br->
getOpcode() == PPC::BCn && CRSetOp == PPC::CRSET) ||
552 (Br->
getOpcode() == PPC::BC && CRSetOp == PPC::CRUNSET)) {
561 for (; It != Er; It++) {
562 if (It->isDebugInstr())
continue;
563 assert(It->isTerminator() &&
"Non-terminator after a terminator");
583 if (SuccMBB->isLiveIn(CRBit) || SuccMBB->isLiveIn(CRReg)) {
592 LLVM_DEBUG(
dbgs() <<
"PPC pre-emit peephole: erasing instruction: ");
594 MI->eraseFromParent();
595 NumRemovedInPreEmit++;
604char PPCPreEmitPeephole::
ID = 0;
607 return new PPCPreEmitPeephole();
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
static Register UseReg(const MachineOperand &MO)
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
unsigned const TargetRegisterInfo * TRI
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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Represent the analysis usage information of a pass.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Implements a dense probed hash-table based set.
FunctionPass class - This class is used to implement most global optimizations.
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
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.
Context object for machine code objects.
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
instr_iterator instr_begin()
void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
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()
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.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
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
MachineOperand class - Representation of each machine instruction operand.
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)
bool isUsingPCRelativeCalls() const
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
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.
Wrapper class representing virtual and physical registers.
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
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_GOT_FLAG
MO_GOT_FLAG - If this bit is set the symbol reference is to be computed via the GOT.
@ Kill
The last use of a register.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
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)
void initializePPCPreEmitPeepholePass(PassRegistry &)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.