1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00

Change if-conversion block size limit checks to add some flexibility.

llvm-svn: 106901
This commit is contained in:
Evan Cheng 2010-06-25 22:42:03 +00:00
parent d1e4e67954
commit 346aecdb8b
10 changed files with 101 additions and 66 deletions

View File

@ -331,6 +331,31 @@ public:
MachineBasicBlock::iterator MBBI) const {
return true;
}
/// isProfitableToIfCvt - Return true if it's profitable to first "NumInstrs"
/// of the specified basic block.
virtual
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumInstrs) const {
return false;
}
/// isProfitableToIfCvt - Second variant of isProfitableToIfCvt, this one
/// checks for the case where two basic blocks from true and false path
/// of a if-then-else (diamond) are predicated on mutally exclusive
/// predicates.
virtual bool
isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumTInstrs,
MachineBasicBlock &FMBB, unsigned NumFInstrs) const {
return false;
}
/// isProfitableToDupForIfCvt - Return true if it's profitable for
/// if-converter to duplicate a specific number of instructions in the
/// specified MBB to enable if-conversion.
virtual bool
isProfitableToDupForIfCvt(MachineBasicBlock &MBB,unsigned NumInstrs) const {
return false;
}
/// copyRegToReg - Emit instructions to copy between a pair of registers. It
/// returns false if the target does not how to copy between the specified

View File

@ -683,19 +683,6 @@ public:
return JumpBufAlignment;
}
/// getIfCvtBlockLimit - returns the target specific if-conversion block size
/// limit. Any block whose size is greater should not be predicated.
unsigned getIfCvtBlockSizeLimit() const {
return IfCvtBlockSizeLimit;
}
/// getIfCvtDupBlockLimit - returns the target specific size limit for a
/// block to be considered for duplication. Any block whose size is greater
/// should not be duplicated to facilitate its predication.
unsigned getIfCvtDupBlockSizeLimit() const {
return IfCvtDupBlockSizeLimit;
}
/// getPrefLoopAlignment - return the preferred loop alignment.
///
unsigned getPrefLoopAlignment() const {
@ -1078,19 +1065,6 @@ protected:
JumpBufAlignment = Align;
}
/// setIfCvtBlockSizeLimit - Set the target's if-conversion block size
/// limit (in number of instructions); default is 2.
void setIfCvtBlockSizeLimit(unsigned Limit) {
IfCvtBlockSizeLimit = Limit;
}
/// setIfCvtDupBlockSizeLimit - Set the target's block size limit (in number
/// of instructions) to be considered for code duplication during
/// if-conversion; default is 2.
void setIfCvtDupBlockSizeLimit(unsigned Limit) {
IfCvtDupBlockSizeLimit = Limit;
}
/// setPrefLoopAlignment - Set the target's preferred loop alignment. Default
/// alignment is zero, it means the target does not care about loop alignment.
void setPrefLoopAlignment(unsigned Align) {
@ -1538,14 +1512,6 @@ private:
/// buffers
unsigned JumpBufAlignment;
/// IfCvtBlockSizeLimit - The maximum allowed size for a block to be
/// if-converted.
unsigned IfCvtBlockSizeLimit;
/// IfCvtDupBlockSizeLimit - The maximum allowed size for a block to be
/// duplicated during if-conversion.
unsigned IfCvtDupBlockSizeLimit;
/// PrefLoopAlignment - The perferred loop alignment.
///
unsigned PrefLoopAlignment;

View File

@ -188,8 +188,14 @@ namespace {
bool IgnoreBr = false);
void MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI);
bool MeetIfcvtSizeLimit(unsigned Size) const {
return Size > 0 && Size <= TLI->getIfCvtBlockSizeLimit();
bool MeetIfcvtSizeLimit(MachineBasicBlock &BB, unsigned Size) const {
return Size > 0 && TII->isProfitableToIfCvt(BB, Size);
}
bool MeetIfcvtSizeLimit(MachineBasicBlock &TBB, unsigned TSize,
MachineBasicBlock &FBB, unsigned FSize) const {
return TSize > 0 && FSize > 0 &&
TII->isProfitableToIfCvt(TBB, TSize, FBB, FSize);
}
// blockAlwaysFallThrough - Block ends without a terminator.
@ -436,7 +442,7 @@ bool IfConverter::ValidSimple(BBInfo &TrueBBI, unsigned &Dups) const {
if (TrueBBI.BB->pred_size() > 1) {
if (TrueBBI.CannotBeCopied ||
TrueBBI.NonPredSize > TLI->getIfCvtDupBlockSizeLimit())
!TII->isProfitableToDupForIfCvt(*TrueBBI.BB, TrueBBI.NonPredSize))
return false;
Dups = TrueBBI.NonPredSize;
}
@ -473,7 +479,7 @@ bool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
++Size;
}
}
if (Size > TLI->getIfCvtDupBlockSizeLimit())
if (!TII->isProfitableToDupForIfCvt(*TrueBBI.BB, Size))
return false;
Dups = Size;
}
@ -761,8 +767,8 @@ IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB,
bool FNeedSub = FalseBBI.Predicate.size() > 0;
bool Enqueued = false;
if (CanRevCond && ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2) &&
MeetIfcvtSizeLimit(TrueBBI.NonPredSize - (Dups + Dups2)) &&
MeetIfcvtSizeLimit(FalseBBI.NonPredSize - (Dups + Dups2)) &&
MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize - (Dups + Dups2),
*FalseBBI.BB, FalseBBI.NonPredSize - (Dups + Dups2)) &&
FeasibilityAnalysis(TrueBBI, BBI.BrCond) &&
FeasibilityAnalysis(FalseBBI, RevCond)) {
// Diamond:
@ -779,7 +785,7 @@ IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB,
}
if (ValidTriangle(TrueBBI, FalseBBI, false, Dups) &&
MeetIfcvtSizeLimit(TrueBBI.NonPredSize) &&
MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize) &&
FeasibilityAnalysis(TrueBBI, BBI.BrCond, true)) {
// Triangle:
// EBB
@ -793,14 +799,14 @@ IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB,
}
if (ValidTriangle(TrueBBI, FalseBBI, true, Dups) &&
MeetIfcvtSizeLimit(TrueBBI.NonPredSize) &&
MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize) &&
FeasibilityAnalysis(TrueBBI, BBI.BrCond, true, true)) {
Tokens.push_back(new IfcvtToken(BBI, ICTriangleRev, TNeedSub, Dups));
Enqueued = true;
}
if (ValidSimple(TrueBBI, Dups) &&
MeetIfcvtSizeLimit(TrueBBI.NonPredSize) &&
MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize) &&
FeasibilityAnalysis(TrueBBI, BBI.BrCond)) {
// Simple (split, no rejoin):
// EBB
@ -816,21 +822,21 @@ IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB,
if (CanRevCond) {
// Try the other path...
if (ValidTriangle(FalseBBI, TrueBBI, false, Dups) &&
MeetIfcvtSizeLimit(FalseBBI.NonPredSize) &&
MeetIfcvtSizeLimit(*FalseBBI.BB, FalseBBI.NonPredSize) &&
FeasibilityAnalysis(FalseBBI, RevCond, true)) {
Tokens.push_back(new IfcvtToken(BBI, ICTriangleFalse, FNeedSub, Dups));
Enqueued = true;
}
if (ValidTriangle(FalseBBI, TrueBBI, true, Dups) &&
MeetIfcvtSizeLimit(FalseBBI.NonPredSize) &&
MeetIfcvtSizeLimit(*FalseBBI.BB, FalseBBI.NonPredSize) &&
FeasibilityAnalysis(FalseBBI, RevCond, true, true)) {
Tokens.push_back(new IfcvtToken(BBI, ICTriangleFRev, FNeedSub, Dups));
Enqueued = true;
}
if (ValidSimple(FalseBBI, Dups) &&
MeetIfcvtSizeLimit(FalseBBI.NonPredSize) &&
MeetIfcvtSizeLimit(*FalseBBI.BB, FalseBBI.NonPredSize) &&
FeasibilityAnalysis(FalseBBI, RevCond)) {
Tokens.push_back(new IfcvtToken(BBI, ICSimpleFalse, FNeedSub, Dups));
Enqueued = true;

View File

@ -578,8 +578,6 @@ TargetLowering::TargetLowering(const TargetMachine &tm,
SchedPreferenceInfo = Sched::Latency;
JumpBufSize = 0;
JumpBufAlignment = 0;
IfCvtBlockSizeLimit = 2;
IfCvtDupBlockSizeLimit = 0;
PrefLoopAlignment = 0;
ShouldFoldAtomicFences = false;

View File

@ -1447,6 +1447,24 @@ bool ARMBaseInstrInfo::isSchedulingBoundary(const MachineInstr *MI,
return false;
}
bool ARMBaseInstrInfo::
isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumInstrs) const {
if (!NumInstrs)
return false;
if (Subtarget.getCPUString() == "generic")
// Generic (and overly aggressive) if-conversion limits for testing.
return NumInstrs <= 10;
else if (Subtarget.hasV7Ops())
return NumInstrs <= 3;
return NumInstrs <= 2;
}
bool ARMBaseInstrInfo::
isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumT,
MachineBasicBlock &FMBB, unsigned NumF) const {
return NumT && NumF && NumT <= 2 && NumF <= 2;
}
/// getInstrPredicate - If instruction is predicated, returns its predicate
/// condition, otherwise returns AL. It also returns the condition code
/// register by reference.

View File

@ -343,6 +343,17 @@ public:
virtual bool isSchedulingBoundary(const MachineInstr *MI,
const MachineBasicBlock *MBB,
const MachineFunction &MF) const;
virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB,
unsigned NumInstrs) const;
virtual bool isProfitableToIfCvt(MachineBasicBlock &TMBB,unsigned NumT,
MachineBasicBlock &FMBB,unsigned NumF) const;
virtual bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB,
unsigned NumInstrs) const {
return NumInstrs && NumInstrs == 1;
}
};
static inline

View File

@ -531,23 +531,6 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
else
setSchedulingPreference(Sched::Hybrid);
// FIXME: If-converter should use instruction latency to determine
// profitability rather than relying on fixed limits.
if (Subtarget->getCPUString() == "generic") {
// Generic (and overly aggressive) if-conversion limits.
setIfCvtBlockSizeLimit(10);
setIfCvtDupBlockSizeLimit(2);
} else if (Subtarget->hasV7Ops()) {
setIfCvtBlockSizeLimit(3);
setIfCvtDupBlockSizeLimit(1);
} else if (Subtarget->hasV6Ops()) {
setIfCvtBlockSizeLimit(2);
setIfCvtDupBlockSizeLimit(1);
} else {
setIfCvtBlockSizeLimit(3);
setIfCvtDupBlockSizeLimit(2);
}
maxStoresPerMemcpy = 1; //// temporary - rewrite interface to use type
// Do not enable CodePlacementOpt for now: it currently runs after the
// ARMConstantIslandPass and messes up branch relaxation and placement

View File

@ -24,9 +24,18 @@
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/CommandLine.h"
using namespace llvm;
static cl::opt<unsigned>
IfCvtLimit("thumb2-ifcvt-limit (default 3)",
cl::Hidden, cl::init(3));
static cl::opt<unsigned>
IfCvtDiamondLimit("thumb2-ifcvt-diamond-limit (default 3)",
cl::Hidden, cl::init(3));
Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI)
: ARMBaseInstrInfo(STI), RI(*this, STI) {
}
@ -94,6 +103,20 @@ Thumb2InstrInfo::isLegalToSplitMBBAt(MachineBasicBlock &MBB,
return llvm::getITInstrPredicate(MBBI, PredReg) == ARMCC::AL;
}
bool Thumb2InstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB,
unsigned NumInstrs) const {
return NumInstrs && NumInstrs <= IfCvtLimit;
}
bool Thumb2InstrInfo::
isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumT,
MachineBasicBlock &FMBB, unsigned NumF) const {
// FIXME: Catch optimization such as:
// r0 = movne
// r0 = moveq
return NumT && NumF &&
NumT <= (IfCvtDiamondLimit) && NumF <= (IfCvtDiamondLimit);
}
bool
Thumb2InstrInfo::copyRegToReg(MachineBasicBlock &MBB,

View File

@ -38,6 +38,11 @@ public:
bool isLegalToSplitMBBAt(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI) const;
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumInstrs) const;
bool isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumTInstrs,
MachineBasicBlock &FMBB, unsigned NumFInstrs) const;
bool copyRegToReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
unsigned DestReg, unsigned SrcReg,

View File

@ -1,4 +1,4 @@
; RUN: llc < %s -stats |& grep {39.*Number of machine instrs printed}
; RUN: llc < %s -stats |& grep {38.*Number of machine instrs printed}
; RUN: llc < %s -stats |& not grep {.*Number of re-materialization}
; This test really wants to check that the resultant "cond_true" block only
; has a single store in it, and that cond_true55 only has code to materialize