1 //===---- PPCReduceCRLogicals.cpp - Reduce CR Bit Logical operations ------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===---------------------------------------------------------------------===//
9 // This pass aims to reduce the number of logical operations on bits in the CR
10 // register. These instructions have a fairly high latency and only a single
11 // pipeline at their disposal in modern PPC cores. Furthermore, they have a
12 // tendency to occur in fairly small blocks where there's little opportunity
13 // to hide the latency between the CR logical operation and its user.
15 //===---------------------------------------------------------------------===//
18 #include "PPCInstrInfo.h"
19 #include "PPCTargetMachine.h"
20 #include "llvm/ADT/Statistic.h"
21 #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
22 #include "llvm/CodeGen/MachineDominators.h"
23 #include "llvm/CodeGen/MachineFunctionPass.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
26 #include "llvm/Config/llvm-config.h"
27 #include "llvm/Support/Debug.h"
31 #define DEBUG_TYPE "ppc-reduce-cr-ops"
33 STATISTIC(NumContainedSingleUseBinOps
,
34 "Number of single-use binary CR logical ops contained in a block");
35 STATISTIC(NumToSplitBlocks
,
36 "Number of binary CR logical ops that can be used to split blocks");
37 STATISTIC(TotalCRLogicals
, "Number of CR logical ops.");
38 STATISTIC(TotalNullaryCRLogicals
,
39 "Number of nullary CR logical ops (CRSET/CRUNSET).");
40 STATISTIC(TotalUnaryCRLogicals
, "Number of unary CR logical ops.");
41 STATISTIC(TotalBinaryCRLogicals
, "Number of CR logical ops.");
42 STATISTIC(NumBlocksSplitOnBinaryCROp
,
43 "Number of blocks split on CR binary logical ops.");
44 STATISTIC(NumNotSplitIdenticalOperands
,
45 "Number of blocks not split due to operands being identical.");
46 STATISTIC(NumNotSplitChainCopies
,
47 "Number of blocks not split due to operands being chained copies.");
48 STATISTIC(NumNotSplitWrongOpcode
,
49 "Number of blocks not split due to the wrong opcode.");
51 /// Given a basic block \p Successor that potentially contains PHIs, this
52 /// function will look for any incoming values in the PHIs that are supposed to
53 /// be coming from \p OrigMBB but whose definition is actually in \p NewMBB.
54 /// Any such PHIs will be updated to reflect reality.
55 static void updatePHIs(MachineBasicBlock
*Successor
, MachineBasicBlock
*OrigMBB
,
56 MachineBasicBlock
*NewMBB
, MachineRegisterInfo
*MRI
) {
57 for (auto &MI
: Successor
->instrs()) {
60 // This is a really ugly-looking loop, but it was pillaged directly from
61 // MachineBasicBlock::transferSuccessorsAndUpdatePHIs().
62 for (unsigned i
= 2, e
= MI
.getNumOperands() + 1; i
!= e
; i
+= 2) {
63 MachineOperand
&MO
= MI
.getOperand(i
);
64 if (MO
.getMBB() == OrigMBB
) {
65 // Check if the instruction is actually defined in NewMBB.
66 if (MI
.getOperand(i
- 1).isReg()) {
67 MachineInstr
*DefMI
= MRI
->getVRegDef(MI
.getOperand(i
- 1).getReg());
68 if (DefMI
->getParent() == NewMBB
||
69 !OrigMBB
->isSuccessor(Successor
)) {
79 /// Given a basic block \p Successor that potentially contains PHIs, this
80 /// function will look for PHIs that have an incoming value from \p OrigMBB
81 /// and will add the same incoming value from \p NewMBB.
82 /// NOTE: This should only be used if \p NewMBB is an immediate dominator of
84 static void addIncomingValuesToPHIs(MachineBasicBlock
*Successor
,
85 MachineBasicBlock
*OrigMBB
,
86 MachineBasicBlock
*NewMBB
,
87 MachineRegisterInfo
*MRI
) {
88 assert(OrigMBB
->isSuccessor(NewMBB
) &&
89 "NewMBB must be a successor of OrigMBB");
90 for (auto &MI
: Successor
->instrs()) {
93 // This is a really ugly-looking loop, but it was pillaged directly from
94 // MachineBasicBlock::transferSuccessorsAndUpdatePHIs().
95 for (unsigned i
= 2, e
= MI
.getNumOperands() + 1; i
!= e
; i
+= 2) {
96 MachineOperand
&MO
= MI
.getOperand(i
);
97 if (MO
.getMBB() == OrigMBB
) {
98 MachineInstrBuilder
MIB(*MI
.getParent()->getParent(), &MI
);
99 MIB
.addReg(MI
.getOperand(i
- 1).getReg()).addMBB(NewMBB
);
106 struct BlockSplitInfo
{
107 MachineInstr
*OrigBranch
;
108 MachineInstr
*SplitBefore
;
109 MachineInstr
*SplitCond
;
110 bool InvertNewBranch
;
111 bool InvertOrigBranch
;
112 bool BranchToFallThrough
;
113 const MachineBranchProbabilityInfo
*MBPI
;
114 MachineInstr
*MIToDelete
;
115 MachineInstr
*NewCond
;
116 bool allInstrsInSameMBB() {
117 if (!OrigBranch
|| !SplitBefore
|| !SplitCond
)
119 MachineBasicBlock
*MBB
= OrigBranch
->getParent();
120 if (SplitBefore
->getParent() != MBB
|| SplitCond
->getParent() != MBB
)
122 if (MIToDelete
&& MIToDelete
->getParent() != MBB
)
124 if (NewCond
&& NewCond
->getParent() != MBB
)
130 /// Splits a MachineBasicBlock to branch before \p SplitBefore. The original
131 /// branch is \p OrigBranch. The target of the new branch can either be the same
132 /// as the target of the original branch or the fallthrough successor of the
133 /// original block as determined by \p BranchToFallThrough. The branch
134 /// conditions will be inverted according to \p InvertNewBranch and
135 /// \p InvertOrigBranch. If an instruction that previously fed the branch is to
136 /// be deleted, it is provided in \p MIToDelete and \p NewCond will be used as
137 /// the branch condition. The branch probabilities will be set if the
138 /// MachineBranchProbabilityInfo isn't null.
139 static bool splitMBB(BlockSplitInfo
&BSI
) {
140 assert(BSI
.allInstrsInSameMBB() &&
141 "All instructions must be in the same block.");
143 MachineBasicBlock
*ThisMBB
= BSI
.OrigBranch
->getParent();
144 MachineFunction
*MF
= ThisMBB
->getParent();
145 MachineRegisterInfo
*MRI
= &MF
->getRegInfo();
146 assert(MRI
->isSSA() && "Can only do this while the function is in SSA form.");
147 if (ThisMBB
->succ_size() != 2) {
149 dbgs() << "Don't know how to handle blocks that don't have exactly"
150 << " two successors.\n");
154 const PPCInstrInfo
*TII
= MF
->getSubtarget
<PPCSubtarget
>().getInstrInfo();
155 unsigned OrigBROpcode
= BSI
.OrigBranch
->getOpcode();
156 unsigned InvertedOpcode
=
157 OrigBROpcode
== PPC::BC
159 : OrigBROpcode
== PPC::BCn
161 : OrigBROpcode
== PPC::BCLR
? PPC::BCLRn
: PPC::BCLR
;
162 unsigned NewBROpcode
= BSI
.InvertNewBranch
? InvertedOpcode
: OrigBROpcode
;
163 MachineBasicBlock
*OrigTarget
= BSI
.OrigBranch
->getOperand(1).getMBB();
164 MachineBasicBlock
*OrigFallThrough
= OrigTarget
== *ThisMBB
->succ_begin()
165 ? *ThisMBB
->succ_rbegin()
166 : *ThisMBB
->succ_begin();
167 MachineBasicBlock
*NewBRTarget
=
168 BSI
.BranchToFallThrough
? OrigFallThrough
: OrigTarget
;
170 // It's impossible to know the precise branch probability after the split.
171 // But it still needs to be reasonable, the whole probability to original
172 // targets should not be changed.
173 // After split NewBRTarget will get two incoming edges. Assume P0 is the
174 // original branch probability to NewBRTarget, P1 and P2 are new branch
175 // probabilies to NewBRTarget after split. If the two edge frequencies are
177 // F * P1 = F * P0 / 2 ==> P1 = P0 / 2
178 // F * (1 - P1) * P2 = F * P1 ==> P2 = P1 / (1 - P1)
179 BranchProbability ProbToNewTarget
, ProbFallThrough
; // Prob for new Br.
180 BranchProbability ProbOrigTarget
, ProbOrigFallThrough
; // Prob for orig Br.
181 ProbToNewTarget
= ProbFallThrough
= BranchProbability::getUnknown();
182 ProbOrigTarget
= ProbOrigFallThrough
= BranchProbability::getUnknown();
184 if (BSI
.BranchToFallThrough
) {
185 ProbToNewTarget
= BSI
.MBPI
->getEdgeProbability(ThisMBB
, OrigFallThrough
) / 2;
186 ProbFallThrough
= ProbToNewTarget
.getCompl();
187 ProbOrigFallThrough
= ProbToNewTarget
/ ProbToNewTarget
.getCompl();
188 ProbOrigTarget
= ProbOrigFallThrough
.getCompl();
190 ProbToNewTarget
= BSI
.MBPI
->getEdgeProbability(ThisMBB
, OrigTarget
) / 2;
191 ProbFallThrough
= ProbToNewTarget
.getCompl();
192 ProbOrigTarget
= ProbToNewTarget
/ ProbToNewTarget
.getCompl();
193 ProbOrigFallThrough
= ProbOrigTarget
.getCompl();
197 // Create a new basic block.
198 MachineBasicBlock::iterator InsertPoint
= BSI
.SplitBefore
;
199 const BasicBlock
*LLVM_BB
= ThisMBB
->getBasicBlock();
200 MachineFunction::iterator It
= ThisMBB
->getIterator();
201 MachineBasicBlock
*NewMBB
= MF
->CreateMachineBasicBlock(LLVM_BB
);
202 MF
->insert(++It
, NewMBB
);
204 // Move everything after SplitBefore into the new block.
205 NewMBB
->splice(NewMBB
->end(), ThisMBB
, InsertPoint
, ThisMBB
->end());
206 NewMBB
->transferSuccessors(ThisMBB
);
207 if (!ProbOrigTarget
.isUnknown()) {
208 auto MBBI
= std::find(NewMBB
->succ_begin(), NewMBB
->succ_end(), OrigTarget
);
209 NewMBB
->setSuccProbability(MBBI
, ProbOrigTarget
);
210 MBBI
= std::find(NewMBB
->succ_begin(), NewMBB
->succ_end(), OrigFallThrough
);
211 NewMBB
->setSuccProbability(MBBI
, ProbOrigFallThrough
);
214 // Add the two successors to ThisMBB.
215 ThisMBB
->addSuccessor(NewBRTarget
, ProbToNewTarget
);
216 ThisMBB
->addSuccessor(NewMBB
, ProbFallThrough
);
218 // Add the branches to ThisMBB.
219 BuildMI(*ThisMBB
, ThisMBB
->end(), BSI
.SplitBefore
->getDebugLoc(),
220 TII
->get(NewBROpcode
))
221 .addReg(BSI
.SplitCond
->getOperand(0).getReg())
222 .addMBB(NewBRTarget
);
223 BuildMI(*ThisMBB
, ThisMBB
->end(), BSI
.SplitBefore
->getDebugLoc(),
227 BSI
.MIToDelete
->eraseFromParent();
229 // Change the condition on the original branch and invert it if requested.
230 auto FirstTerminator
= NewMBB
->getFirstTerminator();
232 assert(FirstTerminator
->getOperand(0).isReg() &&
233 "Can't update condition of unconditional branch.");
234 FirstTerminator
->getOperand(0).setReg(BSI
.NewCond
->getOperand(0).getReg());
236 if (BSI
.InvertOrigBranch
)
237 FirstTerminator
->setDesc(TII
->get(InvertedOpcode
));
239 // If any of the PHIs in the successors of NewMBB reference values that
240 // now come from NewMBB, they need to be updated.
241 for (auto *Succ
: NewMBB
->successors()) {
242 updatePHIs(Succ
, ThisMBB
, NewMBB
, MRI
);
244 addIncomingValuesToPHIs(NewBRTarget
, ThisMBB
, NewMBB
, MRI
);
246 LLVM_DEBUG(dbgs() << "After splitting, ThisMBB:\n"; ThisMBB
->dump());
247 LLVM_DEBUG(dbgs() << "NewMBB:\n"; NewMBB
->dump());
248 LLVM_DEBUG(dbgs() << "New branch-to block:\n"; NewBRTarget
->dump());
252 static bool isBinary(MachineInstr
&MI
) {
253 return MI
.getNumOperands() == 3;
256 static bool isNullary(MachineInstr
&MI
) {
257 return MI
.getNumOperands() == 1;
260 /// Given a CR logical operation \p CROp, branch opcode \p BROp as well as
261 /// a flag to indicate if the first operand of \p CROp is used as the
262 /// SplitBefore operand, determines whether either of the branches are to be
263 /// inverted as well as whether the new target should be the original
264 /// fall-through block.
266 computeBranchTargetAndInversion(unsigned CROp
, unsigned BROp
, bool UsingDef1
,
267 bool &InvertNewBranch
, bool &InvertOrigBranch
,
268 bool &TargetIsFallThrough
) {
269 // The conditions under which each of the output operands should be [un]set
270 // can certainly be written much more concisely with just 3 if statements or
271 // ternary expressions. However, this provides a much clearer overview to the
272 // reader as to what is set for each <CROp, BROp, OpUsed> combination.
273 if (BROp
== PPC::BC
|| BROp
== PPC::BCLR
) {
277 llvm_unreachable("Don't know how to handle this CR logical.");
279 InvertNewBranch
= false;
280 InvertOrigBranch
= false;
281 TargetIsFallThrough
= false;
284 InvertNewBranch
= true;
285 InvertOrigBranch
= false;
286 TargetIsFallThrough
= true;
289 InvertNewBranch
= true;
290 InvertOrigBranch
= true;
291 TargetIsFallThrough
= false;
294 InvertNewBranch
= false;
295 InvertOrigBranch
= true;
296 TargetIsFallThrough
= true;
299 InvertNewBranch
= UsingDef1
;
300 InvertOrigBranch
= !UsingDef1
;
301 TargetIsFallThrough
= false;
304 InvertNewBranch
= !UsingDef1
;
305 InvertOrigBranch
= !UsingDef1
;
306 TargetIsFallThrough
= true;
309 } else if (BROp
== PPC::BCn
|| BROp
== PPC::BCLRn
) {
313 llvm_unreachable("Don't know how to handle this CR logical.");
315 InvertNewBranch
= true;
316 InvertOrigBranch
= false;
317 TargetIsFallThrough
= true;
320 InvertNewBranch
= false;
321 InvertOrigBranch
= false;
322 TargetIsFallThrough
= false;
325 InvertNewBranch
= false;
326 InvertOrigBranch
= true;
327 TargetIsFallThrough
= true;
330 InvertNewBranch
= true;
331 InvertOrigBranch
= true;
332 TargetIsFallThrough
= false;
335 InvertNewBranch
= !UsingDef1
;
336 InvertOrigBranch
= !UsingDef1
;
337 TargetIsFallThrough
= true;
340 InvertNewBranch
= UsingDef1
;
341 InvertOrigBranch
= !UsingDef1
;
342 TargetIsFallThrough
= false;
346 llvm_unreachable("Don't know how to handle this branch.");
351 class PPCReduceCRLogicals
: public MachineFunctionPass
{
355 struct CRLogicalOpInfo
{
357 // FIXME: If chains of copies are to be handled, this should be a vector.
358 std::pair
<MachineInstr
*, MachineInstr
*> CopyDefs
;
359 std::pair
<MachineInstr
*, MachineInstr
*> TrueDefs
;
360 unsigned IsBinary
: 1;
361 unsigned IsNullary
: 1;
362 unsigned ContainedInBlock
: 1;
363 unsigned FeedsISEL
: 1;
364 unsigned FeedsBR
: 1;
365 unsigned FeedsLogical
: 1;
366 unsigned SingleUse
: 1;
367 unsigned DefsSingleUse
: 1;
370 CRLogicalOpInfo() : MI(nullptr), IsBinary(0), IsNullary(0),
371 ContainedInBlock(0), FeedsISEL(0), FeedsBR(0),
372 FeedsLogical(0), SingleUse(0), DefsSingleUse(1),
373 SubregDef1(0), SubregDef2(0) { }
378 const PPCInstrInfo
*TII
;
380 MachineRegisterInfo
*MRI
;
381 const MachineBranchProbabilityInfo
*MBPI
;
383 // A vector to contain all the CR logical operations
384 SmallVector
<CRLogicalOpInfo
, 16> AllCRLogicalOps
;
385 void initialize(MachineFunction
&MFParm
);
386 void collectCRLogicals();
387 bool handleCROp(unsigned Idx
);
388 bool splitBlockOnBinaryCROp(CRLogicalOpInfo
&CRI
);
389 static bool isCRLogical(MachineInstr
&MI
) {
390 unsigned Opc
= MI
.getOpcode();
391 return Opc
== PPC::CRAND
|| Opc
== PPC::CRNAND
|| Opc
== PPC::CROR
||
392 Opc
== PPC::CRXOR
|| Opc
== PPC::CRNOR
|| Opc
== PPC::CREQV
||
393 Opc
== PPC::CRANDC
|| Opc
== PPC::CRORC
|| Opc
== PPC::CRSET
||
394 Opc
== PPC::CRUNSET
|| Opc
== PPC::CR6SET
|| Opc
== PPC::CR6UNSET
;
396 bool simplifyCode() {
397 bool Changed
= false;
398 // Not using a range-based for loop here as the vector may grow while being
400 for (unsigned i
= 0; i
< AllCRLogicalOps
.size(); i
++)
401 Changed
|= handleCROp(i
);
406 PPCReduceCRLogicals() : MachineFunctionPass(ID
) {
407 initializePPCReduceCRLogicalsPass(*PassRegistry::getPassRegistry());
410 MachineInstr
*lookThroughCRCopy(unsigned Reg
, unsigned &Subreg
,
411 MachineInstr
*&CpDef
);
412 bool runOnMachineFunction(MachineFunction
&MF
) override
{
413 if (skipFunction(MF
.getFunction()))
416 // If the subtarget doesn't use CR bits, there's nothing to do.
417 const PPCSubtarget
&STI
= MF
.getSubtarget
<PPCSubtarget
>();
418 if (!STI
.useCRBits())
423 return simplifyCode();
425 CRLogicalOpInfo
createCRLogicalOpInfo(MachineInstr
&MI
);
426 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
427 AU
.addRequired
<MachineBranchProbabilityInfo
>();
428 AU
.addRequired
<MachineDominatorTree
>();
429 MachineFunctionPass::getAnalysisUsage(AU
);
433 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
434 LLVM_DUMP_METHOD
void PPCReduceCRLogicals::CRLogicalOpInfo::dump() {
435 dbgs() << "CRLogicalOpMI: ";
437 dbgs() << "IsBinary: " << IsBinary
<< ", FeedsISEL: " << FeedsISEL
;
438 dbgs() << ", FeedsBR: " << FeedsBR
<< ", FeedsLogical: ";
439 dbgs() << FeedsLogical
<< ", SingleUse: " << SingleUse
;
440 dbgs() << ", DefsSingleUse: " << DefsSingleUse
;
441 dbgs() << ", SubregDef1: " << SubregDef1
<< ", SubregDef2: ";
442 dbgs() << SubregDef2
<< ", ContainedInBlock: " << ContainedInBlock
;
444 dbgs() << "\nDefs:\n";
445 TrueDefs
.first
->dump();
448 TrueDefs
.second
->dump();
450 if (CopyDefs
.first
) {
451 dbgs() << "CopyDef1: ";
452 CopyDefs
.first
->dump();
454 if (CopyDefs
.second
) {
455 dbgs() << "CopyDef2: ";
456 CopyDefs
.second
->dump();
461 PPCReduceCRLogicals::CRLogicalOpInfo
462 PPCReduceCRLogicals::createCRLogicalOpInfo(MachineInstr
&MIParam
) {
466 if (isNullary(MIParam
)) {
468 Ret
.TrueDefs
= std::make_pair(nullptr, nullptr);
469 Ret
.CopyDefs
= std::make_pair(nullptr, nullptr);
471 MachineInstr
*Def1
= lookThroughCRCopy(MIParam
.getOperand(1).getReg(),
472 Ret
.SubregDef1
, Ret
.CopyDefs
.first
);
474 MRI
->hasOneNonDBGUse(Def1
->getOperand(0).getReg());
476 MRI
->hasOneNonDBGUse(Ret
.CopyDefs
.first
->getOperand(0).getReg());
477 assert(Def1
&& "Must be able to find a definition of operand 1.");
478 if (isBinary(MIParam
)) {
480 MachineInstr
*Def2
= lookThroughCRCopy(MIParam
.getOperand(2).getReg(),
482 Ret
.CopyDefs
.second
);
484 MRI
->hasOneNonDBGUse(Def2
->getOperand(0).getReg());
486 MRI
->hasOneNonDBGUse(Ret
.CopyDefs
.second
->getOperand(0).getReg());
487 assert(Def2
&& "Must be able to find a definition of operand 2.");
488 Ret
.TrueDefs
= std::make_pair(Def1
, Def2
);
490 Ret
.TrueDefs
= std::make_pair(Def1
, nullptr);
491 Ret
.CopyDefs
.second
= nullptr;
495 Ret
.ContainedInBlock
= 1;
497 for (MachineInstr
&UseMI
:
498 MRI
->use_nodbg_instructions(MIParam
.getOperand(0).getReg())) {
499 unsigned Opc
= UseMI
.getOpcode();
500 if (Opc
== PPC::ISEL
|| Opc
== PPC::ISEL8
)
502 if (Opc
== PPC::BC
|| Opc
== PPC::BCn
|| Opc
== PPC::BCLR
||
505 Ret
.FeedsLogical
= isCRLogical(UseMI
);
506 if (UseMI
.getParent() != MIParam
.getParent())
507 Ret
.ContainedInBlock
= 0;
509 Ret
.SingleUse
= MRI
->hasOneNonDBGUse(MIParam
.getOperand(0).getReg()) ? 1 : 0;
511 // We now know whether all the uses of the CR logical are in the same block.
512 if (!Ret
.IsNullary
) {
513 Ret
.ContainedInBlock
&=
514 (MIParam
.getParent() == Ret
.TrueDefs
.first
->getParent());
516 Ret
.ContainedInBlock
&=
517 (MIParam
.getParent() == Ret
.TrueDefs
.second
->getParent());
519 LLVM_DEBUG(Ret
.dump());
520 if (Ret
.IsBinary
&& Ret
.ContainedInBlock
&& Ret
.SingleUse
) {
521 NumContainedSingleUseBinOps
++;
522 if (Ret
.FeedsBR
&& Ret
.DefsSingleUse
)
528 /// Looks through a COPY instruction to the actual definition of the CR-bit
529 /// register and returns the instruction that defines it.
530 /// FIXME: This currently handles what is by-far the most common case:
531 /// an instruction that defines a CR field followed by a single copy of a bit
532 /// from that field into a virtual register. If chains of copies need to be
533 /// handled, this should have a loop until a non-copy instruction is found.
534 MachineInstr
*PPCReduceCRLogicals::lookThroughCRCopy(unsigned Reg
,
536 MachineInstr
*&CpDef
) {
538 if (!Register::isVirtualRegister(Reg
))
540 MachineInstr
*Copy
= MRI
->getVRegDef(Reg
);
544 Register CopySrc
= Copy
->getOperand(1).getReg();
545 Subreg
= Copy
->getOperand(1).getSubReg();
546 if (!Register::isVirtualRegister(CopySrc
)) {
547 const TargetRegisterInfo
*TRI
= &TII
->getRegisterInfo();
549 if (CopySrc
== PPC::CR0EQ
|| CopySrc
== PPC::CR6EQ
)
550 Subreg
= PPC::sub_eq
;
551 if (CopySrc
== PPC::CR0LT
|| CopySrc
== PPC::CR6LT
)
552 Subreg
= PPC::sub_lt
;
553 if (CopySrc
== PPC::CR0GT
|| CopySrc
== PPC::CR6GT
)
554 Subreg
= PPC::sub_gt
;
555 if (CopySrc
== PPC::CR0UN
|| CopySrc
== PPC::CR6UN
)
556 Subreg
= PPC::sub_un
;
557 // Loop backwards and return the first MI that modifies the physical CR Reg.
558 MachineBasicBlock::iterator Me
= Copy
, B
= Copy
->getParent()->begin();
560 if ((--Me
)->modifiesRegister(CopySrc
, TRI
))
564 return MRI
->getVRegDef(CopySrc
);
567 void PPCReduceCRLogicals::initialize(MachineFunction
&MFParam
) {
569 MRI
= &MF
->getRegInfo();
570 TII
= MF
->getSubtarget
<PPCSubtarget
>().getInstrInfo();
571 MBPI
= &getAnalysis
<MachineBranchProbabilityInfo
>();
573 AllCRLogicalOps
.clear();
576 /// Contains all the implemented transformations on CR logical operations.
577 /// For example, a binary CR logical can be used to split a block on its inputs,
578 /// a unary CR logical might be used to change the condition code on a
579 /// comparison feeding it. A nullary CR logical might simply be removable
580 /// if the user of the bit it [un]sets can be transformed.
581 bool PPCReduceCRLogicals::handleCROp(unsigned Idx
) {
582 // We can definitely split a block on the inputs to a binary CR operation
583 // whose defs and (single) use are within the same block.
584 bool Changed
= false;
585 CRLogicalOpInfo CRI
= AllCRLogicalOps
[Idx
];
586 if (CRI
.IsBinary
&& CRI
.ContainedInBlock
&& CRI
.SingleUse
&& CRI
.FeedsBR
&&
588 Changed
= splitBlockOnBinaryCROp(CRI
);
590 NumBlocksSplitOnBinaryCROp
++;
595 /// Splits a block that contains a CR-logical operation that feeds a branch
596 /// and whose operands are produced within the block.
598 /// %vr5<def> = CMPDI %vr2, 0; CRRC:%vr5 G8RC:%vr2
599 /// %vr6<def> = COPY %vr5:sub_eq; CRBITRC:%vr6 CRRC:%vr5
600 /// %vr7<def> = CMPDI %vr3, 0; CRRC:%vr7 G8RC:%vr3
601 /// %vr8<def> = COPY %vr7:sub_eq; CRBITRC:%vr8 CRRC:%vr7
602 /// %vr9<def> = CROR %vr6<kill>, %vr8<kill>; CRBITRC:%vr9,%vr6,%vr8
603 /// BC %vr9<kill>, <BB#2>; CRBITRC:%vr9
605 /// %vr5<def> = CMPDI %vr2, 0; CRRC:%vr5 G8RC:%vr2
606 /// %vr6<def> = COPY %vr5:sub_eq; CRBITRC:%vr6 CRRC:%vr5
607 /// BC %vr6<kill>, <BB#2>; CRBITRC:%vr6
609 /// %vr7<def> = CMPDI %vr3, 0; CRRC:%vr7 G8RC:%vr3
610 /// %vr8<def> = COPY %vr7:sub_eq; CRBITRC:%vr8 CRRC:%vr7
611 /// BC %vr9<kill>, <BB#2>; CRBITRC:%vr9
612 bool PPCReduceCRLogicals::splitBlockOnBinaryCROp(CRLogicalOpInfo
&CRI
) {
613 if (CRI
.CopyDefs
.first
== CRI
.CopyDefs
.second
) {
614 LLVM_DEBUG(dbgs() << "Unable to split as the two operands are the same\n");
615 NumNotSplitIdenticalOperands
++;
618 if (CRI
.TrueDefs
.first
->isCopy() || CRI
.TrueDefs
.second
->isCopy() ||
619 CRI
.TrueDefs
.first
->isPHI() || CRI
.TrueDefs
.second
->isPHI()) {
621 dbgs() << "Unable to split because one of the operands is a PHI or "
622 "chain of copies.\n");
623 NumNotSplitChainCopies
++;
626 // Note: keep in sync with computeBranchTargetAndInversion().
627 if (CRI
.MI
->getOpcode() != PPC::CROR
&&
628 CRI
.MI
->getOpcode() != PPC::CRAND
&&
629 CRI
.MI
->getOpcode() != PPC::CRNOR
&&
630 CRI
.MI
->getOpcode() != PPC::CRNAND
&&
631 CRI
.MI
->getOpcode() != PPC::CRORC
&&
632 CRI
.MI
->getOpcode() != PPC::CRANDC
) {
633 LLVM_DEBUG(dbgs() << "Unable to split blocks on this opcode.\n");
634 NumNotSplitWrongOpcode
++;
637 LLVM_DEBUG(dbgs() << "Splitting the following CR op:\n"; CRI
.dump());
638 MachineBasicBlock::iterator Def1It
= CRI
.TrueDefs
.first
;
639 MachineBasicBlock::iterator Def2It
= CRI
.TrueDefs
.second
;
641 bool UsingDef1
= false;
642 MachineInstr
*SplitBefore
= &*Def2It
;
643 for (auto E
= CRI
.MI
->getParent()->end(); Def2It
!= E
; ++Def2It
) {
644 if (Def1It
== Def2It
) { // Def2 comes before Def1.
645 SplitBefore
= &*Def1It
;
651 LLVM_DEBUG(dbgs() << "We will split the following block:\n";);
652 LLVM_DEBUG(CRI
.MI
->getParent()->dump());
653 LLVM_DEBUG(dbgs() << "Before instruction:\n"; SplitBefore
->dump());
655 // Get the branch instruction.
656 MachineInstr
*Branch
=
657 MRI
->use_nodbg_begin(CRI
.MI
->getOperand(0).getReg())->getParent();
659 // We want the new block to have no code in it other than the definition
660 // of the input to the CR logical and the CR logical itself. So we move
661 // those to the bottom of the block (just before the branch). Then we
662 // will split before the CR logical.
663 MachineBasicBlock
*MBB
= SplitBefore
->getParent();
664 auto FirstTerminator
= MBB
->getFirstTerminator();
665 MachineBasicBlock::iterator FirstInstrToMove
=
666 UsingDef1
? CRI
.TrueDefs
.first
: CRI
.TrueDefs
.second
;
667 MachineBasicBlock::iterator SecondInstrToMove
=
668 UsingDef1
? CRI
.CopyDefs
.first
: CRI
.CopyDefs
.second
;
670 // The instructions that need to be moved are not guaranteed to be
671 // contiguous. Move them individually.
672 // FIXME: If one of the operands is a chain of (single use) copies, they
673 // can all be moved and we can still split.
674 MBB
->splice(FirstTerminator
, MBB
, FirstInstrToMove
);
675 if (FirstInstrToMove
!= SecondInstrToMove
)
676 MBB
->splice(FirstTerminator
, MBB
, SecondInstrToMove
);
677 MBB
->splice(FirstTerminator
, MBB
, CRI
.MI
);
679 unsigned Opc
= CRI
.MI
->getOpcode();
680 bool InvertOrigBranch
, InvertNewBranch
, TargetIsFallThrough
;
681 computeBranchTargetAndInversion(Opc
, Branch
->getOpcode(), UsingDef1
,
682 InvertNewBranch
, InvertOrigBranch
,
683 TargetIsFallThrough
);
684 MachineInstr
*SplitCond
=
685 UsingDef1
? CRI
.CopyDefs
.second
: CRI
.CopyDefs
.first
;
686 LLVM_DEBUG(dbgs() << "We will " << (InvertNewBranch
? "invert" : "copy"));
687 LLVM_DEBUG(dbgs() << " the original branch and the target is the "
688 << (TargetIsFallThrough
? "fallthrough block\n"
689 : "orig. target block\n"));
690 LLVM_DEBUG(dbgs() << "Original branch instruction: "; Branch
->dump());
691 BlockSplitInfo BSI
{ Branch
, SplitBefore
, SplitCond
, InvertNewBranch
,
692 InvertOrigBranch
, TargetIsFallThrough
, MBPI
, CRI
.MI
,
693 UsingDef1
? CRI
.CopyDefs
.first
: CRI
.CopyDefs
.second
};
694 bool Changed
= splitMBB(BSI
);
695 // If we've split on a CR logical that is fed by a CR logical,
696 // recompute the source CR logical as it may be usable for splitting.
698 bool Input1CRlogical
=
699 CRI
.TrueDefs
.first
&& isCRLogical(*CRI
.TrueDefs
.first
);
700 bool Input2CRlogical
=
701 CRI
.TrueDefs
.second
&& isCRLogical(*CRI
.TrueDefs
.second
);
703 AllCRLogicalOps
.push_back(createCRLogicalOpInfo(*CRI
.TrueDefs
.first
));
705 AllCRLogicalOps
.push_back(createCRLogicalOpInfo(*CRI
.TrueDefs
.second
));
710 void PPCReduceCRLogicals::collectCRLogicals() {
711 for (MachineBasicBlock
&MBB
: *MF
) {
712 for (MachineInstr
&MI
: MBB
) {
713 if (isCRLogical(MI
)) {
714 AllCRLogicalOps
.push_back(createCRLogicalOpInfo(MI
));
716 if (AllCRLogicalOps
.back().IsNullary
)
717 TotalNullaryCRLogicals
++;
718 else if (AllCRLogicalOps
.back().IsBinary
)
719 TotalBinaryCRLogicals
++;
721 TotalUnaryCRLogicals
++;
727 } // end anonymous namespace
729 INITIALIZE_PASS_BEGIN(PPCReduceCRLogicals
, DEBUG_TYPE
,
730 "PowerPC Reduce CR logical Operation", false, false)
731 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree
)
732 INITIALIZE_PASS_END(PPCReduceCRLogicals
, DEBUG_TYPE
,
733 "PowerPC Reduce CR logical Operation", false, false)
735 char PPCReduceCRLogicals::ID
= 0;
737 llvm::createPPCReduceCRLogicalsPass() { return new PPCReduceCRLogicals(); }