27 #include "llvm/Config/llvm-config.h" 32 #define DEBUG_TYPE "ppc-reduce-cr-ops" 35 "Number of single-use binary CR logical ops contained in a block");
37 "Number of binary CR logical ops that can be used to split blocks");
38 STATISTIC(TotalCRLogicals,
"Number of CR logical ops.");
40 "Number of nullary CR logical ops (CRSET/CRUNSET).");
41 STATISTIC(TotalUnaryCRLogicals,
"Number of unary CR logical ops.");
42 STATISTIC(TotalBinaryCRLogicals,
"Number of CR logical ops.");
44 "Number of blocks split on CR binary logical ops.");
46 "Number of blocks not split due to operands being identical.");
48 "Number of blocks not split due to operands being chained copies.");
50 "Number of blocks not split due to the wrong opcode.");
62 for (
auto &
MI : Successor->
instrs()) {
67 for (
unsigned i = 2, e =
MI.getNumOperands() + 1; i != e; i += 2) {
69 if (MO.
getMBB() == OrigMBB) {
71 if (
MI.getOperand(i - 1).isReg()) {
94 "NewMBB must be a successor of OrigMBB");
95 for (
auto &
MI : Successor->
instrs()) {
100 for (
unsigned i = 2, e =
MI.getNumOperands() + 1; i != e; i += 2) {
102 if (MO.
getMBB() == OrigMBB) {
104 MIB.
addReg(
MI.getOperand(i - 1).getReg()).addMBB(NewMBB);
122 if (!OrigBranch || !SplitBefore || !SplitCond)
127 if (MIToDelete && MIToDelete->
getParent() != MBB)
129 if (NewCond && NewCond->
getParent() != MBB)
146 "All instructions must be in the same block.");
151 assert(MRI->
isSSA() &&
"Can only do this while the function is in SSA form.");
152 if (ThisMBB->succ_size() != 2) {
154 dbgs() <<
"Don't know how to handle blocks that don't have exactly" 155 <<
" two successors.\n");
161 unsigned InvertedOpcode =
162 OrigBROpcode == PPC::BC
164 : OrigBROpcode == PPC::BCn
166 : OrigBROpcode == PPC::BCLR ? PPC::BCLRn : PPC::BCLR;
167 unsigned NewBROpcode = BSI.
InvertNewBranch ? InvertedOpcode : OrigBROpcode;
170 ? *ThisMBB->succ_rbegin()
171 : *ThisMBB->succ_begin();
180 const BasicBlock *LLVM_BB = ThisMBB->getBasicBlock();
186 NewMBB->
splice(NewMBB->
end(), ThisMBB, InsertPoint, ThisMBB->end());
191 ThisMBB->addSuccessor(NewBRTarget, ProbToNewTarget);
192 ThisMBB->addSuccessor(NewMBB, ProbToNewTarget.
getCompl());
196 TII->get(NewBROpcode))
198 .addMBB(NewBRTarget);
208 assert(FirstTerminator->getOperand(0).isReg() &&
209 "Can't update condition of unconditional branch.");
213 FirstTerminator->setDesc(TII->get(InvertedOpcode));
222 LLVM_DEBUG(
dbgs() <<
"After splitting, ThisMBB:\n"; ThisMBB->dump());
243 bool &InvertNewBranch,
bool &InvertOrigBranch,
244 bool &TargetIsFallThrough) {
249 if (BROp == PPC::BC || BROp == PPC::BCLR) {
255 InvertNewBranch =
false;
256 InvertOrigBranch =
false;
257 TargetIsFallThrough =
false;
260 InvertNewBranch =
true;
261 InvertOrigBranch =
false;
262 TargetIsFallThrough =
true;
265 InvertNewBranch =
true;
266 InvertOrigBranch =
true;
267 TargetIsFallThrough =
false;
270 InvertNewBranch =
false;
271 InvertOrigBranch =
true;
272 TargetIsFallThrough =
true;
275 InvertNewBranch = UsingDef1;
276 InvertOrigBranch = !UsingDef1;
277 TargetIsFallThrough =
false;
280 InvertNewBranch = !UsingDef1;
281 InvertOrigBranch = !UsingDef1;
282 TargetIsFallThrough =
true;
285 }
else if (BROp == PPC::BCn || BROp == PPC::BCLRn) {
291 InvertNewBranch =
true;
292 InvertOrigBranch =
false;
293 TargetIsFallThrough =
true;
296 InvertNewBranch =
false;
297 InvertOrigBranch =
false;
298 TargetIsFallThrough =
false;
301 InvertNewBranch =
false;
302 InvertOrigBranch =
true;
303 TargetIsFallThrough =
true;
306 InvertNewBranch =
true;
307 InvertOrigBranch =
true;
308 TargetIsFallThrough =
false;
311 InvertNewBranch = !UsingDef1;
312 InvertOrigBranch = !UsingDef1;
313 TargetIsFallThrough =
true;
316 InvertNewBranch = UsingDef1;
317 InvertOrigBranch = !UsingDef1;
318 TargetIsFallThrough =
false;
331 struct CRLogicalOpInfo {
334 std::pair<MachineInstr*, MachineInstr*> CopyDefs;
335 std::pair<MachineInstr*, MachineInstr*> TrueDefs;
336 unsigned IsBinary : 1;
337 unsigned IsNullary : 1;
338 unsigned ContainedInBlock : 1;
339 unsigned FeedsISEL : 1;
340 unsigned FeedsBR : 1;
341 unsigned FeedsLogical : 1;
342 unsigned SingleUse : 1;
343 unsigned DefsSingleUse : 1;
346 CRLogicalOpInfo() :
MI(
nullptr), IsBinary(0), IsNullary(0),
347 ContainedInBlock(0), FeedsISEL(0), FeedsBR(0),
348 FeedsLogical(0), SingleUse(0), DefsSingleUse(1),
349 SubregDef1(0), SubregDef2(0) { }
360 std::vector<CRLogicalOpInfo> AllCRLogicalOps;
362 void collectCRLogicals();
363 bool handleCROp(CRLogicalOpInfo &CRI);
364 bool splitBlockOnBinaryCROp(CRLogicalOpInfo &CRI);
367 return Opc == PPC::CRAND || Opc == PPC::CRNAND || Opc == PPC::CROR ||
368 Opc == PPC::CRXOR || Opc == PPC::CRNOR || Opc == PPC::CREQV ||
369 Opc == PPC::CRANDC || Opc == PPC::CRORC || Opc == PPC::CRSET ||
372 bool simplifyCode() {
373 bool Changed =
false;
376 for (
unsigned i = 0; i < AllCRLogicalOps.size(); i++)
377 Changed |= handleCROp(AllCRLogicalOps[i]);
399 return simplifyCode();
401 CRLogicalOpInfo createCRLogicalOpInfo(
MachineInstr &MI);
409 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 411 dbgs() <<
"CRLogicalOpMI: ";
413 dbgs() <<
"IsBinary: " << IsBinary <<
", FeedsISEL: " << FeedsISEL;
414 dbgs() <<
", FeedsBR: " << FeedsBR <<
", FeedsLogical: ";
415 dbgs() << FeedsLogical <<
", SingleUse: " << SingleUse;
416 dbgs() <<
", DefsSingleUse: " << DefsSingleUse;
417 dbgs() <<
", SubregDef1: " << SubregDef1 <<
", SubregDef2: ";
418 dbgs() << SubregDef2 <<
", ContainedInBlock: " << ContainedInBlock;
420 dbgs() <<
"\nDefs:\n";
421 TrueDefs.first->dump();
424 TrueDefs.second->dump();
426 if (CopyDefs.first) {
427 dbgs() <<
"CopyDef1: ";
428 CopyDefs.first->dump();
430 if (CopyDefs.second) {
431 dbgs() <<
"CopyDef2: ";
432 CopyDefs.second->dump();
437 PPCReduceCRLogicals::CRLogicalOpInfo
438 PPCReduceCRLogicals::createCRLogicalOpInfo(
MachineInstr &MIParam) {
444 Ret.TrueDefs = std::make_pair(
nullptr,
nullptr);
445 Ret.CopyDefs = std::make_pair(
nullptr,
nullptr);
448 Ret.SubregDef1, Ret.CopyDefs.first);
452 MRI->hasOneNonDBGUse(Ret.CopyDefs.first->getOperand(0).getReg());
453 assert(Def1 &&
"Must be able to find a definition of operand 1.");
458 Ret.CopyDefs.second);
462 MRI->hasOneNonDBGUse(Ret.CopyDefs.second->getOperand(0).getReg());
463 assert(Def2 &&
"Must be able to find a definition of operand 2.");
464 Ret.TrueDefs = std::make_pair(Def1, Def2);
466 Ret.TrueDefs = std::make_pair(Def1,
nullptr);
467 Ret.CopyDefs.second =
nullptr;
471 Ret.ContainedInBlock = 1;
475 unsigned Opc =
UseMI.getOpcode();
476 if (Opc == PPC::ISEL || Opc == PPC::ISEL8)
478 if (Opc == PPC::BC || Opc == PPC::BCn || Opc == PPC::BCLR ||
481 Ret.FeedsLogical = isCRLogical(
UseMI);
483 Ret.ContainedInBlock = 0;
488 if (!Ret.IsNullary) {
489 Ret.ContainedInBlock &=
490 (MIParam.
getParent() == Ret.TrueDefs.first->getParent());
492 Ret.ContainedInBlock &=
493 (MIParam.
getParent() == Ret.TrueDefs.second->getParent());
496 if (Ret.IsBinary && Ret.ContainedInBlock && Ret.SingleUse) {
497 NumContainedSingleUseBinOps++;
498 if (Ret.FeedsBR && Ret.DefsSingleUse)
525 if (CopySrc == PPC::CR0EQ || CopySrc == PPC::CR6EQ)
526 Subreg = PPC::sub_eq;
527 if (CopySrc == PPC::CR0LT || CopySrc == PPC::CR6LT)
528 Subreg = PPC::sub_lt;
529 if (CopySrc == PPC::CR0GT || CopySrc == PPC::CR6GT)
530 Subreg = PPC::sub_gt;
531 if (CopySrc == PPC::CR0UN || CopySrc == PPC::CR6UN)
532 Subreg = PPC::sub_un;
536 if ((--Me)->modifiesRegister(CopySrc, TRI))
540 return MRI->getVRegDef(CopySrc);
545 MRI = &MF->getRegInfo();
547 MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
549 AllCRLogicalOps.clear();
557 bool PPCReduceCRLogicals::handleCROp(CRLogicalOpInfo &CRI) {
560 bool Changed =
false;
561 if (CRI.IsBinary && CRI.ContainedInBlock && CRI.SingleUse && CRI.FeedsBR &&
563 Changed = splitBlockOnBinaryCROp(CRI);
565 NumBlocksSplitOnBinaryCROp++;
587 bool PPCReduceCRLogicals::splitBlockOnBinaryCROp(CRLogicalOpInfo &CRI) {
588 if (CRI.CopyDefs.first == CRI.CopyDefs.second) {
589 LLVM_DEBUG(
dbgs() <<
"Unable to split as the two operands are the same\n");
590 NumNotSplitIdenticalOperands++;
593 if (CRI.TrueDefs.first->isCopy() || CRI.TrueDefs.second->isCopy() ||
594 CRI.TrueDefs.first->isPHI() || CRI.TrueDefs.second->isPHI()) {
596 dbgs() <<
"Unable to split because one of the operands is a PHI or " 597 "chain of copies.\n");
598 NumNotSplitChainCopies++;
602 if (CRI.MI->getOpcode() != PPC::CROR &&
603 CRI.MI->getOpcode() != PPC::CRAND &&
604 CRI.MI->getOpcode() != PPC::CRNOR &&
605 CRI.MI->getOpcode() != PPC::CRNAND &&
606 CRI.MI->getOpcode() != PPC::CRORC &&
607 CRI.MI->getOpcode() != PPC::CRANDC) {
609 NumNotSplitWrongOpcode++;
612 LLVM_DEBUG(
dbgs() <<
"Splitting the following CR op:\n"; CRI.dump());
616 bool UsingDef1 =
false;
618 for (
auto E = CRI.MI->getParent()->end(); Def2It !=
E; ++Def2It) {
619 if (Def1It == Def2It) {
620 SplitBefore = &*Def1It;
632 MRI->use_nodbg_begin(CRI.MI->getOperand(0).getReg())->
getParent();
641 UsingDef1 ? CRI.TrueDefs.first : CRI.TrueDefs.second;
643 UsingDef1 ? CRI.CopyDefs.first : CRI.CopyDefs.second;
649 MBB->
splice(FirstTerminator, MBB, FirstInstrToMove);
650 if (FirstInstrToMove != SecondInstrToMove)
651 MBB->
splice(FirstTerminator, MBB, SecondInstrToMove);
652 MBB->
splice(FirstTerminator, MBB, CRI.MI);
654 unsigned Opc = CRI.MI->getOpcode();
655 bool InvertOrigBranch, InvertNewBranch, TargetIsFallThrough;
657 InvertNewBranch, InvertOrigBranch,
658 TargetIsFallThrough);
660 UsingDef1 ? CRI.CopyDefs.second : CRI.CopyDefs.first;
661 LLVM_DEBUG(
dbgs() <<
"We will " << (InvertNewBranch ?
"invert" :
"copy"));
662 LLVM_DEBUG(
dbgs() <<
" the original branch and the target is the " 663 << (TargetIsFallThrough ?
"fallthrough block\n" 664 :
"orig. target block\n"));
665 LLVM_DEBUG(
dbgs() <<
"Original branch instruction: "; Branch->dump());
667 InvertOrigBranch, TargetIsFallThrough, MBPI, CRI.MI,
668 UsingDef1 ? CRI.CopyDefs.first : CRI.CopyDefs.second };
673 bool Input1CRlogical =
674 CRI.TrueDefs.first && isCRLogical(*CRI.TrueDefs.first);
675 bool Input2CRlogical =
676 CRI.TrueDefs.second && isCRLogical(*CRI.TrueDefs.second);
678 AllCRLogicalOps.push_back(createCRLogicalOpInfo(*CRI.TrueDefs.first));
680 AllCRLogicalOps.push_back(createCRLogicalOpInfo(*CRI.TrueDefs.second));
685 void PPCReduceCRLogicals::collectCRLogicals() {
688 if (isCRLogical(
MI)) {
689 AllCRLogicalOps.push_back(createCRLogicalOpInfo(
MI));
691 if (AllCRLogicalOps.back().IsNullary)
692 TotalNullaryCRLogicals++;
693 else if (AllCRLogicalOps.back().IsBinary)
694 TotalBinaryCRLogicals++;
696 TotalUnaryCRLogicals++;
705 "PowerPC Reduce CR logical Operation",
false,
false)
710 char PPCReduceCRLogicals::
ID = 0;
INITIALIZE_PASS_BEGIN(PPCReduceCRLogicals, DEBUG_TYPE, "PowerPC Reduce CR logical Operation", false, false) INITIALIZE_PASS_END(PPCReduceCRLogicals
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
BranchProbability getCompl() const
MachineBasicBlock * getMBB() const
This class represents lattice values for constants.
bool allInstrsInSameMBB()
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 transferSuccessors(MachineBasicBlock *FromMBB)
Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...
unsigned getSubReg() const
MachineInstr * OrigBranch
static void dump(StringRef Title, SpillInfo const &Spills)
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
iterator_range< succ_iterator > successors()
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
unsigned getNumOperands() const
Retuns the total number of operands.
static bool isNullary(MachineInstr &MI)
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
void initializePPCReduceCRLogicalsPass(PassRegistry &)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
static void updatePHIs(MachineBasicBlock *Successor, MachineBasicBlock *OrigMBB, MachineBasicBlock *NewMBB, MachineRegisterInfo *MRI)
Given a basic block Successor that potentially contains PHIs, this function will look for any incomin...
FunctionPass * createPPCReduceCRLogicalsPass()
MachineInstr * SplitBefore
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
unsigned const MachineRegisterInfo * MRI
LLVM Basic Block Representation.
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.
PowerPC Reduce CR logical Operation
ch, gl = CR6[UN]SET ch, inglue - Toggle CR bit 6 for SVR4 vararg calls
MachineInstrBuilder & UseMI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void setMBB(MachineBasicBlock *MBB)
Represent the analysis usage information of a pass.
static void computeBranchTargetAndInversion(unsigned CROp, unsigned BROp, bool UsingDef1, bool &InvertNewBranch, bool &InvertOrigBranch, bool &TargetIsFallThrough)
Given a CR logical operation CROp, branch opcode BROp as well as a flag to indicate if the first oper...
FunctionPass class - This class is used to implement most global optimizations.
succ_iterator succ_begin()
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static bool isBinary(MachineInstr &MI)
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.
static BranchProbability getUnknown()
Iterator for intrusive lists based on ilist_node.
MachineOperand class - Representation of each machine instruction operand.
MachineInstr * MIToDelete
MachineInstrBuilder MachineInstrBuilder & DefMI
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.
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.
BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
Representation of each machine instruction.
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.
bool useCRBits() const
useCRBits - Return true if we should store and manipulate i1 values in the individual condition regis...
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void insert(iterator MBBI, MachineBasicBlock *MBB)
static void addIncomingValuesToPHIs(MachineBasicBlock *Successor, MachineBasicBlock *OrigMBB, MachineBasicBlock *NewMBB, MachineRegisterInfo *MRI)
Given a basic block Successor that potentially contains PHIs, this function will look for PHIs that h...
static const Function * getParent(const Value *V)
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
const MachineOperand & getOperand(unsigned i) const
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
const MachineBranchProbabilityInfo * MBPI
static bool splitMBB(BlockSplitInfo &BSI)
Splits a MachineBasicBlock to branch before SplitBefore.