26 #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.");
63 for (
unsigned i = 2,
e =
MI.getNumOperands() + 1;
i !=
e;
i += 2) {
65 if (MO.
getMBB() == OrigMBB) {
67 if (
MI.getOperand(
i - 1).isReg()) {
90 "NewMBB must be a successor of OrigMBB");
96 for (
unsigned i = 2,
e =
MI.getNumOperands() + 1;
i !=
e;
i += 2) {
98 if (MO.
getMBB() == OrigMBB) {
118 if (!OrigBranch || !SplitBefore || !SplitCond)
142 "All instructions must be in the same block.");
147 assert(
MRI->
isSSA() &&
"Can only do this while the function is in SSA form.");
150 dbgs() <<
"Don't know how to handle blocks that don't have exactly"
151 <<
" two successors.\n");
157 unsigned InvertedOpcode =
158 OrigBROpcode == PPC::BC
160 : OrigBROpcode == PPC::BCn
162 : OrigBROpcode == PPC::BCLR ? PPC::BCLRn : PPC::BCLR;
163 unsigned NewBROpcode = BSI.
InvertNewBranch ? InvertedOpcode : OrigBROpcode;
187 ProbFallThrough = ProbToNewTarget.
getCompl();
188 ProbOrigFallThrough = ProbToNewTarget / ProbToNewTarget.
getCompl();
189 ProbOrigTarget = ProbOrigFallThrough.
getCompl();
192 ProbFallThrough = ProbToNewTarget.
getCompl();
193 ProbOrigTarget = ProbToNewTarget / ProbToNewTarget.
getCompl();
194 ProbOrigFallThrough = ProbOrigTarget.
getCompl();
206 NewMBB->
splice(NewMBB->
end(), ThisMBB, InsertPoint, ThisMBB->
end());
221 TII->get(NewBROpcode))
233 assert(FirstTerminator->getOperand(0).isReg() &&
234 "Can't update condition of unconditional branch.");
238 FirstTerminator->setDesc(
TII->get(InvertedOpcode));
254 return MI.getNumOperands() == 3;
258 return MI.getNumOperands() == 1;
268 bool &InvertNewBranch,
bool &InvertOrigBranch,
269 bool &TargetIsFallThrough) {
274 if (BROp == PPC::BC || BROp == PPC::BCLR) {
280 InvertNewBranch =
false;
281 InvertOrigBranch =
false;
282 TargetIsFallThrough =
false;
285 InvertNewBranch =
true;
286 InvertOrigBranch =
false;
287 TargetIsFallThrough =
true;
290 InvertNewBranch =
true;
291 InvertOrigBranch =
true;
292 TargetIsFallThrough =
false;
295 InvertNewBranch =
false;
296 InvertOrigBranch =
true;
297 TargetIsFallThrough =
true;
300 InvertNewBranch = UsingDef1;
301 InvertOrigBranch = !UsingDef1;
302 TargetIsFallThrough =
false;
305 InvertNewBranch = !UsingDef1;
306 InvertOrigBranch = !UsingDef1;
307 TargetIsFallThrough =
true;
310 }
else if (BROp == PPC::BCn || BROp == PPC::BCLRn) {
316 InvertNewBranch =
true;
317 InvertOrigBranch =
false;
318 TargetIsFallThrough =
true;
321 InvertNewBranch =
false;
322 InvertOrigBranch =
false;
323 TargetIsFallThrough =
false;
326 InvertNewBranch =
false;
327 InvertOrigBranch =
true;
328 TargetIsFallThrough =
true;
331 InvertNewBranch =
true;
332 InvertOrigBranch =
true;
333 TargetIsFallThrough =
false;
336 InvertNewBranch = !UsingDef1;
337 InvertOrigBranch = !UsingDef1;
338 TargetIsFallThrough =
true;
341 InvertNewBranch = UsingDef1;
342 InvertOrigBranch = !UsingDef1;
343 TargetIsFallThrough =
false;
356 struct CRLogicalOpInfo {
359 std::pair<MachineInstr*, MachineInstr*> CopyDefs;
360 std::pair<MachineInstr*, MachineInstr*> TrueDefs;
361 unsigned IsBinary : 1;
362 unsigned IsNullary : 1;
363 unsigned ContainedInBlock : 1;
364 unsigned FeedsISEL : 1;
365 unsigned FeedsBR : 1;
366 unsigned FeedsLogical : 1;
367 unsigned SingleUse : 1;
368 unsigned DefsSingleUse : 1;
371 CRLogicalOpInfo() :
MI(nullptr), IsBinary(0), IsNullary(0),
372 ContainedInBlock(0), FeedsISEL(0), FeedsBR(0),
373 FeedsLogical(0), SingleUse(0), DefsSingleUse(1),
374 SubregDef1(0), SubregDef2(0) { }
387 void collectCRLogicals();
388 bool handleCROp(
unsigned Idx);
389 bool splitBlockOnBinaryCROp(CRLogicalOpInfo &CRI);
391 unsigned Opc =
MI.getOpcode();
392 return Opc == PPC::CRAND || Opc == PPC::CRNAND || Opc == PPC::CROR ||
393 Opc == PPC::CRXOR || Opc == PPC::CRNOR || Opc == PPC::CREQV ||
394 Opc == PPC::CRANDC || Opc == PPC::CRORC || Opc == PPC::CRSET ||
397 bool simplifyCode() {
398 bool Changed =
false;
401 for (
unsigned i = 0;
i < AllCRLogicalOps.size();
i++)
402 Changed |= handleCROp(
i);
424 return simplifyCode();
434 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
436 dbgs() <<
"CRLogicalOpMI: ";
438 dbgs() <<
"IsBinary: " << IsBinary <<
", FeedsISEL: " << FeedsISEL;
439 dbgs() <<
", FeedsBR: " << FeedsBR <<
", FeedsLogical: ";
440 dbgs() << FeedsLogical <<
", SingleUse: " << SingleUse;
441 dbgs() <<
", DefsSingleUse: " << DefsSingleUse;
442 dbgs() <<
", SubregDef1: " << SubregDef1 <<
", SubregDef2: ";
443 dbgs() << SubregDef2 <<
", ContainedInBlock: " << ContainedInBlock;
445 dbgs() <<
"\nDefs:\n";
446 TrueDefs.first->dump();
449 TrueDefs.second->dump();
451 if (CopyDefs.first) {
452 dbgs() <<
"CopyDef1: ";
453 CopyDefs.first->dump();
455 if (CopyDefs.second) {
456 dbgs() <<
"CopyDef2: ";
457 CopyDefs.second->dump();
462 PPCReduceCRLogicals::CRLogicalOpInfo
463 PPCReduceCRLogicals::createCRLogicalOpInfo(
MachineInstr &MIParam) {
469 Ret.TrueDefs = std::make_pair(
nullptr,
nullptr);
470 Ret.CopyDefs = std::make_pair(
nullptr,
nullptr);
473 Ret.SubregDef1,
Ret.CopyDefs.first);
474 assert(Def1 &&
"Must be able to find a definition of operand 1.");
483 Ret.CopyDefs.second);
484 assert(Def2 &&
"Must be able to find a definition of operand 2.");
489 Ret.TrueDefs = std::make_pair(Def1, Def2);
491 Ret.TrueDefs = std::make_pair(Def1,
nullptr);
492 Ret.CopyDefs.second =
nullptr;
496 Ret.ContainedInBlock = 1;
500 unsigned Opc =
UseMI.getOpcode();
501 if (Opc ==
PPC::ISEL || Opc == PPC::ISEL8)
503 if (Opc == PPC::BC || Opc == PPC::BCn || Opc == PPC::BCLR ||
506 Ret.FeedsLogical = isCRLogical(
UseMI);
508 Ret.ContainedInBlock = 0;
513 if (!
Ret.IsNullary) {
514 Ret.ContainedInBlock &=
515 (MIParam.
getParent() ==
Ret.TrueDefs.first->getParent());
517 Ret.ContainedInBlock &=
518 (MIParam.
getParent() ==
Ret.TrueDefs.second->getParent());
521 if (
Ret.IsBinary &&
Ret.ContainedInBlock &&
Ret.SingleUse) {
522 NumContainedSingleUseBinOps++;
523 if (
Ret.FeedsBR &&
Ret.DefsSingleUse)
546 Subreg =
Copy->getOperand(1).getSubReg();
550 if (CopySrc == PPC::CR0EQ || CopySrc == PPC::CR6EQ)
551 Subreg = PPC::sub_eq;
552 if (CopySrc == PPC::CR0LT || CopySrc == PPC::CR6LT)
553 Subreg = PPC::sub_lt;
554 if (CopySrc == PPC::CR0GT || CopySrc == PPC::CR6GT)
555 Subreg = PPC::sub_gt;
556 if (CopySrc == PPC::CR0UN || CopySrc == PPC::CR6UN)
557 Subreg = PPC::sub_un;
561 if ((--Me)->modifiesRegister(CopySrc,
TRI))
572 MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
574 AllCRLogicalOps.
clear();
582 bool PPCReduceCRLogicals::handleCROp(
unsigned Idx) {
585 bool Changed =
false;
586 CRLogicalOpInfo CRI = AllCRLogicalOps[Idx];
587 if (CRI.IsBinary && CRI.ContainedInBlock && CRI.SingleUse && CRI.FeedsBR &&
589 Changed = splitBlockOnBinaryCROp(CRI);
591 NumBlocksSplitOnBinaryCROp++;
613 bool PPCReduceCRLogicals::splitBlockOnBinaryCROp(CRLogicalOpInfo &CRI) {
614 if (CRI.CopyDefs.first == CRI.CopyDefs.second) {
615 LLVM_DEBUG(
dbgs() <<
"Unable to split as the two operands are the same\n");
616 NumNotSplitIdenticalOperands++;
619 if (CRI.TrueDefs.first->isCopy() || CRI.TrueDefs.second->isCopy() ||
620 CRI.TrueDefs.first->isPHI() || CRI.TrueDefs.second->isPHI()) {
622 dbgs() <<
"Unable to split because one of the operands is a PHI or "
623 "chain of copies.\n");
624 NumNotSplitChainCopies++;
628 if (CRI.MI->getOpcode() != PPC::CROR &&
629 CRI.MI->getOpcode() != PPC::CRAND &&
630 CRI.MI->getOpcode() != PPC::CRNOR &&
631 CRI.MI->getOpcode() != PPC::CRNAND &&
632 CRI.MI->getOpcode() != PPC::CRORC &&
633 CRI.MI->getOpcode() != PPC::CRANDC) {
635 NumNotSplitWrongOpcode++;
638 LLVM_DEBUG(
dbgs() <<
"Splitting the following CR op:\n"; CRI.dump());
642 bool UsingDef1 =
false;
644 for (
auto E = CRI.MI->getParent()->end(); Def2It !=
E; ++Def2It) {
645 if (Def1It == Def2It) {
646 SplitBefore = &*Def1It;
667 UsingDef1 ? CRI.TrueDefs.first : CRI.TrueDefs.second;
669 UsingDef1 ? CRI.CopyDefs.first : CRI.CopyDefs.second;
676 if (FirstInstrToMove != SecondInstrToMove)
680 unsigned Opc = CRI.MI->getOpcode();
681 bool InvertOrigBranch, InvertNewBranch, TargetIsFallThrough;
683 InvertNewBranch, InvertOrigBranch,
684 TargetIsFallThrough);
686 UsingDef1 ? CRI.CopyDefs.second : CRI.CopyDefs.first;
687 LLVM_DEBUG(
dbgs() <<
"We will " << (InvertNewBranch ?
"invert" :
"copy"));
688 LLVM_DEBUG(
dbgs() <<
" the original branch and the target is the "
689 << (TargetIsFallThrough ?
"fallthrough block\n"
690 :
"orig. target block\n"));
693 InvertOrigBranch, TargetIsFallThrough, MBPI, CRI.MI,
694 UsingDef1 ? CRI.CopyDefs.first : CRI.CopyDefs.second };
699 bool Input1CRlogical =
700 CRI.TrueDefs.first && isCRLogical(*CRI.TrueDefs.first);
701 bool Input2CRlogical =
702 CRI.TrueDefs.second && isCRLogical(*CRI.TrueDefs.second);
704 AllCRLogicalOps.push_back(createCRLogicalOpInfo(*CRI.TrueDefs.first));
706 AllCRLogicalOps.push_back(createCRLogicalOpInfo(*CRI.TrueDefs.second));
711 void PPCReduceCRLogicals::collectCRLogicals() {
714 if (isCRLogical(
MI)) {
715 AllCRLogicalOps.push_back(createCRLogicalOpInfo(
MI));
717 if (AllCRLogicalOps.back().IsNullary)
718 TotalNullaryCRLogicals++;
719 else if (AllCRLogicalOps.back().IsBinary)
720 TotalBinaryCRLogicals++;
722 TotalUnaryCRLogicals++;
731 "PowerPC Reduce CR logical Operation",
false,
false)
736 char PPCReduceCRLogicals::
ID = 0;