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()) {
119 LLVM_DEBUG(
dbgs() <<
"Remove redundant load immediates from MBB:\n";
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();
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);
215 MI->eraseFromParent();
217 NumRemovedInPreEmit += InstrsToErase.size();
218 return !InstrsToErase.empty();
224 if (
Instr.getOpcode() != PPC::PLDpc)
229 if (!LoadedAddressReg.
isReg())
252 struct GOTDefUsePair {
262 bool MadeChange =
false;
268 if (isGOTPLDpc(*BBI)) {
270 BBI->getOperand(0).getReg(),
271 PPC::NoRegister,
true};
277 if (CandPairs.
empty())
284 GOTDefUsePair &Pair = CandPairs[
Idx];
287 if (!BBI->readsRegister(Pair.DefReg,
TRI) &&
288 !BBI->modifiesRegister(Pair.DefReg,
TRI))
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)
338 Pair->DefInst->addOperand(ImplDef);
339 Pair->UseInst->addOperand(ImplUse);
346 Pair->DefInst->addOperand(*MF, PCRelLabel);
347 Pair->UseInst->addOperand(*MF, PCRelLabel);
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]);
396 if (!Operand.isReg())
399 if (PPC::ACCRCRegClass.
contains(Reg))
400 Candidates[
Reg - PPC::ACC0] =
nullptr;
406 MI->eraseFromParent();
407 NumRemovedInPreEmit += InstrsToErase.size();
408 return !InstrsToErase.empty();
440 errs() <<
"Warning: Ran out of registers - Unable to set DSCR as "
451 if (
MI.getOpcode() == PPC::UNENCODED_NOP)
454 MI->eraseFromParent();
457 bool Changed =
false;
462 Changed |= removeRedundantLIs(
MBB,
TRI);
463 Changed |= addLinkerOpt(
MBB,
TRI);
464 Changed |= removeAccPrimeUnprime(
MBB);
466 unsigned Opc =
MI.getOpcode();
467 if (
Opc == PPC::UNENCODED_NOP) {
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++;
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)) {
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)) {
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!")
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.
Register 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.
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.
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()
LLVM_ABI void dump() const
LLVM_ABI void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
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.
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.
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
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)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.