llvm.org GIT mirror llvm / 1315143
Change if-conversion block size limit checks to add some flexibility. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@106901 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 10 years ago
10 changed file(s) with 101 addition(s) and 66 deletion(s). Raw diff Collapse all Expand all
329329 virtual bool isLegalToSplitMBBAt(MachineBasicBlock &MBB,
330330 MachineBasicBlock::iterator MBBI) const {
331331 return true;
332 }
333
334 /// isProfitableToIfCvt - Return true if it's profitable to first "NumInstrs"
335 /// of the specified basic block.
336 virtual
337 bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumInstrs) const {
338 return false;
339 }
340
341 /// isProfitableToIfCvt - Second variant of isProfitableToIfCvt, this one
342 /// checks for the case where two basic blocks from true and false path
343 /// of a if-then-else (diamond) are predicated on mutally exclusive
344 /// predicates.
345 virtual bool
346 isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumTInstrs,
347 MachineBasicBlock &FMBB, unsigned NumFInstrs) const {
348 return false;
349 }
350
351 /// isProfitableToDupForIfCvt - Return true if it's profitable for
352 /// if-converter to duplicate a specific number of instructions in the
353 /// specified MBB to enable if-conversion.
354 virtual bool
355 isProfitableToDupForIfCvt(MachineBasicBlock &MBB,unsigned NumInstrs) const {
356 return false;
332357 }
333358
334359 /// copyRegToReg - Emit instructions to copy between a pair of registers. It
682682 return JumpBufAlignment;
683683 }
684684
685 /// getIfCvtBlockLimit - returns the target specific if-conversion block size
686 /// limit. Any block whose size is greater should not be predicated.
687 unsigned getIfCvtBlockSizeLimit() const {
688 return IfCvtBlockSizeLimit;
689 }
690
691 /// getIfCvtDupBlockLimit - returns the target specific size limit for a
692 /// block to be considered for duplication. Any block whose size is greater
693 /// should not be duplicated to facilitate its predication.
694 unsigned getIfCvtDupBlockSizeLimit() const {
695 return IfCvtDupBlockSizeLimit;
696 }
697
698685 /// getPrefLoopAlignment - return the preferred loop alignment.
699686 ///
700687 unsigned getPrefLoopAlignment() const {
10751062 /// alignment (in bytes); default is 0
10761063 void setJumpBufAlignment(unsigned Align) {
10771064 JumpBufAlignment = Align;
1078 }
1079
1080 /// setIfCvtBlockSizeLimit - Set the target's if-conversion block size
1081 /// limit (in number of instructions); default is 2.
1082 void setIfCvtBlockSizeLimit(unsigned Limit) {
1083 IfCvtBlockSizeLimit = Limit;
1084 }
1085
1086 /// setIfCvtDupBlockSizeLimit - Set the target's block size limit (in number
1087 /// of instructions) to be considered for code duplication during
1088 /// if-conversion; default is 2.
1089 void setIfCvtDupBlockSizeLimit(unsigned Limit) {
1090 IfCvtDupBlockSizeLimit = Limit;
10911065 }
10921066
10931067 /// setPrefLoopAlignment - Set the target's preferred loop alignment. Default
15371511 /// buffers
15381512 unsigned JumpBufAlignment;
15391513
1540 /// IfCvtBlockSizeLimit - The maximum allowed size for a block to be
1541 /// if-converted.
1542 unsigned IfCvtBlockSizeLimit;
1543
1544 /// IfCvtDupBlockSizeLimit - The maximum allowed size for a block to be
1545 /// duplicated during if-conversion.
1546 unsigned IfCvtDupBlockSizeLimit;
1547
15481514 /// PrefLoopAlignment - The perferred loop alignment.
15491515 ///
15501516 unsigned PrefLoopAlignment;
187187 bool IgnoreBr = false);
188188 void MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI);
189189
190 bool MeetIfcvtSizeLimit(unsigned Size) const {
191 return Size > 0 && Size <= TLI->getIfCvtBlockSizeLimit();
190 bool MeetIfcvtSizeLimit(MachineBasicBlock &BB, unsigned Size) const {
191 return Size > 0 && TII->isProfitableToIfCvt(BB, Size);
192 }
193
194 bool MeetIfcvtSizeLimit(MachineBasicBlock &TBB, unsigned TSize,
195 MachineBasicBlock &FBB, unsigned FSize) const {
196 return TSize > 0 && FSize > 0 &&
197 TII->isProfitableToIfCvt(TBB, TSize, FBB, FSize);
192198 }
193199
194200 // blockAlwaysFallThrough - Block ends without a terminator.
435441
436442 if (TrueBBI.BB->pred_size() > 1) {
437443 if (TrueBBI.CannotBeCopied ||
438 TrueBBI.NonPredSize > TLI->getIfCvtDupBlockSizeLimit())
444 !TII->isProfitableToDupForIfCvt(*TrueBBI.BB, TrueBBI.NonPredSize))
439445 return false;
440446 Dups = TrueBBI.NonPredSize;
441447 }
472478 ++Size;
473479 }
474480 }
475 if (Size > TLI->getIfCvtDupBlockSizeLimit())
481 if (!TII->isProfitableToDupForIfCvt(*TrueBBI.BB, Size))
476482 return false;
477483 Dups = Size;
478484 }
760766 bool FNeedSub = FalseBBI.Predicate.size() > 0;
761767 bool Enqueued = false;
762768 if (CanRevCond && ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2) &&
763 MeetIfcvtSizeLimit(TrueBBI.NonPredSize - (Dups + Dups2)) &&
764 MeetIfcvtSizeLimit(FalseBBI.NonPredSize - (Dups + Dups2)) &&
769 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize - (Dups + Dups2),
770 *FalseBBI.BB, FalseBBI.NonPredSize - (Dups + Dups2)) &&
765771 FeasibilityAnalysis(TrueBBI, BBI.BrCond) &&
766772 FeasibilityAnalysis(FalseBBI, RevCond)) {
767773 // Diamond:
778784 }
779785
780786 if (ValidTriangle(TrueBBI, FalseBBI, false, Dups) &&
781 MeetIfcvtSizeLimit(TrueBBI.NonPredSize) &&
787 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize) &&
782788 FeasibilityAnalysis(TrueBBI, BBI.BrCond, true)) {
783789 // Triangle:
784790 // EBB
792798 }
793799
794800 if (ValidTriangle(TrueBBI, FalseBBI, true, Dups) &&
795 MeetIfcvtSizeLimit(TrueBBI.NonPredSize) &&
801 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize) &&
796802 FeasibilityAnalysis(TrueBBI, BBI.BrCond, true, true)) {
797803 Tokens.push_back(new IfcvtToken(BBI, ICTriangleRev, TNeedSub, Dups));
798804 Enqueued = true;
799805 }
800806
801807 if (ValidSimple(TrueBBI, Dups) &&
802 MeetIfcvtSizeLimit(TrueBBI.NonPredSize) &&
808 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize) &&
803809 FeasibilityAnalysis(TrueBBI, BBI.BrCond)) {
804810 // Simple (split, no rejoin):
805811 // EBB
815821 if (CanRevCond) {
816822 // Try the other path...
817823 if (ValidTriangle(FalseBBI, TrueBBI, false, Dups) &&
818 MeetIfcvtSizeLimit(FalseBBI.NonPredSize) &&
824 MeetIfcvtSizeLimit(*FalseBBI.BB, FalseBBI.NonPredSize) &&
819825 FeasibilityAnalysis(FalseBBI, RevCond, true)) {
820826 Tokens.push_back(new IfcvtToken(BBI, ICTriangleFalse, FNeedSub, Dups));
821827 Enqueued = true;
822828 }
823829
824830 if (ValidTriangle(FalseBBI, TrueBBI, true, Dups) &&
825 MeetIfcvtSizeLimit(FalseBBI.NonPredSize) &&
831 MeetIfcvtSizeLimit(*FalseBBI.BB, FalseBBI.NonPredSize) &&
826832 FeasibilityAnalysis(FalseBBI, RevCond, true, true)) {
827833 Tokens.push_back(new IfcvtToken(BBI, ICTriangleFRev, FNeedSub, Dups));
828834 Enqueued = true;
829835 }
830836
831837 if (ValidSimple(FalseBBI, Dups) &&
832 MeetIfcvtSizeLimit(FalseBBI.NonPredSize) &&
838 MeetIfcvtSizeLimit(*FalseBBI.BB, FalseBBI.NonPredSize) &&
833839 FeasibilityAnalysis(FalseBBI, RevCond)) {
834840 Tokens.push_back(new IfcvtToken(BBI, ICSimpleFalse, FNeedSub, Dups));
835841 Enqueued = true;
577577 SchedPreferenceInfo = Sched::Latency;
578578 JumpBufSize = 0;
579579 JumpBufAlignment = 0;
580 IfCvtBlockSizeLimit = 2;
581 IfCvtDupBlockSizeLimit = 0;
582580 PrefLoopAlignment = 0;
583581 ShouldFoldAtomicFences = false;
584582
14461446 return false;
14471447 }
14481448
1449 bool ARMBaseInstrInfo::
1450 isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumInstrs) const {
1451 if (!NumInstrs)
1452 return false;
1453 if (Subtarget.getCPUString() == "generic")
1454 // Generic (and overly aggressive) if-conversion limits for testing.
1455 return NumInstrs <= 10;
1456 else if (Subtarget.hasV7Ops())
1457 return NumInstrs <= 3;
1458 return NumInstrs <= 2;
1459 }
1460
1461 bool ARMBaseInstrInfo::
1462 isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumT,
1463 MachineBasicBlock &FMBB, unsigned NumF) const {
1464 return NumT && NumF && NumT <= 2 && NumF <= 2;
1465 }
1466
14491467 /// getInstrPredicate - If instruction is predicated, returns its predicate
14501468 /// condition, otherwise returns AL. It also returns the condition code
14511469 /// register by reference.
342342 virtual bool isSchedulingBoundary(const MachineInstr *MI,
343343 const MachineBasicBlock *MBB,
344344 const MachineFunction &MF) const;
345
346 virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB,
347 unsigned NumInstrs) const;
348
349 virtual bool isProfitableToIfCvt(MachineBasicBlock &TMBB,unsigned NumT,
350 MachineBasicBlock &FMBB,unsigned NumF) const;
351
352 virtual bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB,
353 unsigned NumInstrs) const {
354 return NumInstrs && NumInstrs == 1;
355 }
345356 };
346357
347358 static inline
530530 else
531531 setSchedulingPreference(Sched::Hybrid);
532532
533 // FIXME: If-converter should use instruction latency to determine
534 // profitability rather than relying on fixed limits.
535 if (Subtarget->getCPUString() == "generic") {
536 // Generic (and overly aggressive) if-conversion limits.
537 setIfCvtBlockSizeLimit(10);
538 setIfCvtDupBlockSizeLimit(2);
539 } else if (Subtarget->hasV7Ops()) {
540 setIfCvtBlockSizeLimit(3);
541 setIfCvtDupBlockSizeLimit(1);
542 } else if (Subtarget->hasV6Ops()) {
543 setIfCvtBlockSizeLimit(2);
544 setIfCvtDupBlockSizeLimit(1);
545 } else {
546 setIfCvtBlockSizeLimit(3);
547 setIfCvtDupBlockSizeLimit(2);
548 }
549
550533 maxStoresPerMemcpy = 1; //// temporary - rewrite interface to use type
551534 // Do not enable CodePlacementOpt for now: it currently runs after the
552535 // ARMConstantIslandPass and messes up branch relaxation and placement
2323 #include "llvm/CodeGen/MachineMemOperand.h"
2424 #include "llvm/CodeGen/PseudoSourceValue.h"
2525 #include "llvm/ADT/SmallVector.h"
26 #include "llvm/Support/CommandLine.h"
2627
2728 using namespace llvm;
29
30 static cl::opt
31 IfCvtLimit("thumb2-ifcvt-limit (default 3)",
32 cl::Hidden, cl::init(3));
33
34 static cl::opt
35 IfCvtDiamondLimit("thumb2-ifcvt-diamond-limit (default 3)",
36 cl::Hidden, cl::init(3));
2837
2938 Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI)
3039 : ARMBaseInstrInfo(STI), RI(*this, STI) {
93102 return llvm::getITInstrPredicate(MBBI, PredReg) == ARMCC::AL;
94103 }
95104
105 bool Thumb2InstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB,
106 unsigned NumInstrs) const {
107 return NumInstrs && NumInstrs <= IfCvtLimit;
108 }
109
110 bool Thumb2InstrInfo::
111 isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumT,
112 MachineBasicBlock &FMBB, unsigned NumF) const {
113 // FIXME: Catch optimization such as:
114 // r0 = movne
115 // r0 = moveq
116 return NumT && NumF &&
117 NumT <= (IfCvtDiamondLimit) && NumF <= (IfCvtDiamondLimit);
118 }
96119
97120 bool
98121 Thumb2InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
3636
3737 bool isLegalToSplitMBBAt(MachineBasicBlock &MBB,
3838 MachineBasicBlock::iterator MBBI) const;
39
40 bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumInstrs) const;
41
42 bool isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumTInstrs,
43 MachineBasicBlock &FMBB, unsigned NumFInstrs) const;
3944
4045 bool copyRegToReg(MachineBasicBlock &MBB,
4146 MachineBasicBlock::iterator I,
None ; RUN: llc < %s -stats |& grep {39.*Number of machine instrs printed}
0 ; RUN: llc < %s -stats |& grep {38.*Number of machine instrs printed}
11 ; RUN: llc < %s -stats |& not grep {.*Number of re-materialization}
22 ; This test really wants to check that the resultant "cond_true" block only
33 ; has a single store in it, and that cond_true55 only has code to materialize