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:
parent
d1e4e67954
commit
346aecdb8b
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -578,8 +578,6 @@ TargetLowering::TargetLowering(const TargetMachine &tm,
|
||||
SchedPreferenceInfo = Sched::Latency;
|
||||
JumpBufSize = 0;
|
||||
JumpBufAlignment = 0;
|
||||
IfCvtBlockSizeLimit = 2;
|
||||
IfCvtDupBlockSizeLimit = 0;
|
||||
PrefLoopAlignment = 0;
|
||||
ShouldFoldAtomicFences = false;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user