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()) {
108 MachineFunctionProperties::Property::NoVRegs);
122 LLVM_DEBUG(
dbgs() <<
"Remove redundant load immediates from MBB:\n";
129 if (InstrsToErase.contains(&*BBI))
132 unsigned Opc = BBI->getOpcode();
133 if (Opc != PPC::LI && Opc != PPC::LI8 && Opc != PPC::LIS &&
138 if (!BBI->getOperand(1).isImm())
140 assert(BBI->getOperand(0).isReg() &&
141 "Expected a register for the first operand");
143 LLVM_DEBUG(
dbgs() <<
"Scanning after load immediate: "; BBI->dump(););
146 int64_t
Imm = BBI->getOperand(1).getImm();
148 if (BBI->getOperand(0).isDead()) {
149 DeadOrKillToUnset = &BBI->getOperand(0);
151 <<
" from load immediate " << *BBI
152 <<
" is a unsetting candidate\n");
156 for (
auto AfterBBI = std::next(BBI); AfterBBI !=
MBB.
instr_end();
160 int KillIdx = AfterBBI->findRegisterUseOperandIdx(Reg,
TRI,
true);
164 if (KillIdx != -1 && AfterBBI->getOperand(KillIdx).isImplicit()) {
166 <<
"Encountered an implicit kill, cannot proceed: ");
172 assert(!DeadOrKillToUnset &&
"Shouldn't kill same register twice");
173 DeadOrKillToUnset = &AfterBBI->getOperand(KillIdx);
175 <<
" Kill flag of " << *DeadOrKillToUnset <<
" from "
176 << *AfterBBI <<
" is a unsetting candidate\n");
179 if (!AfterBBI->modifiesRegister(Reg,
TRI))
183 if (AfterBBI->getOpcode() != Opc)
185 assert(AfterBBI->getOperand(0).isReg() &&
186 "Expected a register for the first operand");
189 if (!AfterBBI->getOperand(1).isImm() ||
190 AfterBBI->getOperand(1).getImm() != Imm)
196 if (DeadOrKillToUnset) {
198 <<
" Unset dead/kill flag of " << *DeadOrKillToUnset
199 <<
" from " << *DeadOrKillToUnset->
getParent());
200 if (DeadOrKillToUnset->
isDef())
206 AfterBBI->findRegisterDefOperand(Reg,
TRI,
true,
true);
207 if (DeadOrKillToUnset)
209 <<
" Dead flag of " << *DeadOrKillToUnset <<
" from "
210 << *AfterBBI <<
" is a unsetting candidate\n");
211 InstrsToErase.insert(&*AfterBBI);
218 MI->eraseFromParent();
220 NumRemovedInPreEmit += InstrsToErase.size();
221 return !InstrsToErase.empty();
227 if (
Instr.getOpcode() != PPC::PLDpc)
232 if (!LoadedAddressReg.
isReg())
255 struct GOTDefUsePair {
265 bool MadeChange =
false;
271 if (isGOTPLDpc(*BBI)) {
273 BBI->getOperand(0).getReg(),
274 PPC::NoRegister,
true};
280 if (CandPairs.
empty())
287 GOTDefUsePair &Pair = CandPairs[
Idx];
290 if (!BBI->readsRegister(Pair.DefReg,
TRI) &&
291 !BBI->modifiesRegister(Pair.DefReg,
TRI))
297 hasPCRelativeForm(*BBI) ? &BBI->getOperand(2) :
nullptr;
300 if (UseOp && UseOp->
isReg() && UseOp->
getReg() == Pair.DefReg &&
303 Pair.UseReg = BBI->getOperand(0).getReg();
311 for (
auto Pair = ValidPairs.
begin(); Pair != ValidPairs.
end(); Pair++) {
313 assert(Pair->UseInst.isValid() && Pair->StillValid &&
314 "Kept an invalid def/use pair for GOT PCRel opt");
320 for (; BBI != Pair->UseInst; ++BBI) {
321 if (BBI->readsRegister(Pair->UseReg,
TRI) ||
322 BBI->modifiesRegister(Pair->UseReg,
TRI)) {
323 Pair->StillValid =
false;
328 if (!Pair->StillValid)
341 Pair->DefInst->addOperand(ImplDef);
342 Pair->UseInst->addOperand(ImplUse);
349 Pair->DefInst->addOperand(*MF, PCRelLabel);
350 Pair->UseInst->addOperand(*MF, PCRelLabel);
372 PPC::UACCRCRegClass.getNumRegs(),
nullptr);
375 unsigned Opc = BBI.getOpcode();
378 if (Opc == PPC::XXMTACC) {
379 Register Acc = BBI.getOperand(0).getReg();
381 "Unexpected register for XXMTACC");
382 Candidates[Acc - PPC::ACC0] = &BBI;
386 else if (Opc == PPC::XXMFACC) {
387 Register Acc = BBI.getOperand(0).getReg();
389 "Unexpected register for XXMFACC");
390 if (!Candidates[Acc - PPC::ACC0])
392 InstrsToErase.
insert(&BBI);
393 InstrsToErase.
insert(Candidates[Acc - PPC::ACC0]);
399 if (!Operand.isReg())
402 if (PPC::ACCRCRegClass.
contains(Reg))
403 Candidates[
Reg - PPC::ACC0] =
nullptr;
409 MI->eraseFromParent();
410 NumRemovedInPreEmit += InstrsToErase.size();
411 return !InstrsToErase.empty();
443 errs() <<
"Warning: Ran out of registers - Unable to set DSCR as "
454 if (
MI.getOpcode() == PPC::UNENCODED_NOP)
457 MI->eraseFromParent();
460 bool Changed =
false;
465 Changed |= removeRedundantLIs(
MBB,
TRI);
466 Changed |= addLinkerOpt(
MBB,
TRI);
467 Changed |= removeAccPrimeUnprime(
MBB);
469 unsigned Opc =
MI.getOpcode();
470 if (Opc == PPC::UNENCODED_NOP) {
478 MI.getOperand(0).getReg() ==
MI.getOperand(1).getReg() &&
479 MI.getOperand(0).getReg() ==
MI.getOperand(2).getReg()) {
480 NumberOfSelfCopies++;
487 MI.getOperand(0).getReg() ==
MI.getOperand(1).getReg()) {
488 NumberOfSelfCopies++;
497 if (
TII->convertToImmediateForm(
MI, UpdatedRegs, &DefMIToErase)) {
499 NumRRConvertedInPreEmit++;
506 if (
TII->foldFrameOffset(
MI)) {
508 NumFrameOffFoldInPreEmit++;
509 LLVM_DEBUG(
dbgs() <<
"Frame offset folding by using index form: ");
512 if (
TII->optimizeCmpPostRA(
MI)) {
534 bool SeenUse =
false;
536 for (It++; It != Er; It++) {
537 if (It->modifiesRegister(CRBit,
TRI)) {
538 if ((It->getOpcode() == PPC::CRUNSET ||
539 It->getOpcode() == PPC::CRSET) &&
540 It->getOperand(0).getReg() == CRBit)
544 if (It->readsRegister(CRBit,
TRI))
547 if (!CRSetMI)
continue;
550 if ((Br->
getOpcode() == PPC::BCn && CRSetOp == PPC::CRSET) ||
551 (Br->
getOpcode() == PPC::BC && CRSetOp == PPC::CRUNSET)) {
560 for (; It != Er; It++) {
561 if (It->isDebugInstr())
continue;
562 assert(It->isTerminator() &&
"Non-terminator after a terminator");
582 if (SuccMBB->isLiveIn(CRBit) || SuccMBB->isLiveIn(CRReg)) {
591 LLVM_DEBUG(
dbgs() <<
"PPC pre-emit peephole: erasing instruction: ");
593 MI->eraseFromParent();
594 NumRemovedInPreEmit++;
603char PPCPreEmitPeephole::
ID = 0;
606 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
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())
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)
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.
MCSymbol * createNamedTempSymbol()
Create a temporary symbol with a unique name whose name cannot be omitted in the symbol table.
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)
static bool hasGOTFlag(unsigned TF)
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.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
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.
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_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.
Reg
All possible values of the reg field in the ModR/M byte.
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)
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.