}
/// isProfitableToIfCvt - Return true if it's profitable to first "NumInstrs"
- /// of the specified basic block.
+ /// of the specified basic block, where the probability of the instructions
+ /// being executed is given by Probability.
virtual
- bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumInstrs) const {
+ bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumInstrs,
+ float Probability) 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.
+ /// predicates, where the probability of the true path being taken is given
+ /// by Probability.
virtual bool
isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumTInstrs,
- MachineBasicBlock &FMBB, unsigned NumFInstrs) const {
+ MachineBasicBlock &FMBB, unsigned NumFInstrs,
+ float Probability) 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.
+ /// specified MBB to enable if-conversion, where the probability of the
+ /// instructions being executed is given by Probability.
virtual bool
- isProfitableToDupForIfCvt(MachineBasicBlock &MBB,unsigned NumInstrs) const {
+ isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumInstrs,
+ float Probability) const {
return false;
}
void MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI, bool AddEdges = true);
bool MeetIfcvtSizeLimit(MachineBasicBlock &BB, unsigned Size) const {
- return Size > 0 && TII->isProfitableToIfCvt(BB, Size);
+ return Size > 0 && TII->isProfitableToIfCvt(BB, Size, 0.5);
}
bool MeetIfcvtSizeLimit(MachineBasicBlock &TBB, unsigned TSize,
MachineBasicBlock &FBB, unsigned FSize) const {
return TSize > 0 && FSize > 0 &&
- TII->isProfitableToIfCvt(TBB, TSize, FBB, FSize);
+ TII->isProfitableToIfCvt(TBB, TSize, FBB, FSize, 0.5);
}
// blockAlwaysFallThrough - Block ends without a terminator.
if (TrueBBI.BB->pred_size() > 1) {
if (TrueBBI.CannotBeCopied ||
- !TII->isProfitableToDupForIfCvt(*TrueBBI.BB, TrueBBI.NonPredSize))
+ !TII->isProfitableToDupForIfCvt(*TrueBBI.BB, TrueBBI.NonPredSize, 0.5))
return false;
Dups = TrueBBI.NonPredSize;
}
++Size;
}
}
- if (!TII->isProfitableToDupForIfCvt(*TrueBBI.BB, Size))
+ if (!TII->isProfitableToDupForIfCvt(*TrueBBI.BB, Size, 0.5))
return false;
Dups = Size;
}
return false;
}
-bool ARMBaseInstrInfo::
-isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumInstrs) const {
+bool ARMBaseInstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB,
+ unsigned NumInstrs,
+ float Probability) 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;
+
+ // Attempt to estimate the relative costs of predication versus branching.
+ float UnpredCost = Probability * NumInstrs;
+ UnpredCost += 2.0; // FIXME: Should model a misprediction cost.
+
+ float PredCost = NumInstrs;
+
+ return PredCost < UnpredCost;
+
}
bool ARMBaseInstrInfo::
isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumT,
- MachineBasicBlock &FMBB, unsigned NumF) const {
- return NumT && NumF && NumT <= 2 && NumF <= 2;
+ MachineBasicBlock &FMBB, unsigned NumF,
+ float Probability) const {
+ if (!NumT || !NumF)
+ return false;
+
+ // Attempt to estimate the relative costs of predication versus branching.
+ float UnpredCost = Probability * NumT + (1.0 - Probability) * NumF;
+ UnpredCost += 2.0; // FIXME: Should model a misprediction cost.
+
+ float PredCost = NumT + NumF;
+
+ return PredCost < UnpredCost;
}
/// getInstrPredicate - If instruction is predicated, returns its predicate
const MachineFunction &MF) const;
virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB,
- unsigned NumInstrs) const;
+ unsigned NumInstrs, float Prob) const;
virtual bool isProfitableToIfCvt(MachineBasicBlock &TMBB,unsigned NumT,
- MachineBasicBlock &FMBB,unsigned NumF) const;
+ MachineBasicBlock &FMBB,unsigned NumF,
+ float Probability) const;
virtual bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB,
- unsigned NumInstrs) const {
+ unsigned NumInstrs,
+ float Probability) const {
return NumInstrs && NumInstrs == 1;
}
using namespace llvm;
-static cl::opt<unsigned>
-IfCvtLimit("thumb2-ifcvt-limit", cl::Hidden,
- cl::desc("Thumb2 if-conversion limit (default 3)"),
- cl::init(3));
-
-static cl::opt<unsigned>
-IfCvtDiamondLimit("thumb2-ifcvt-diamond-limit", cl::Hidden,
- cl::desc("Thumb2 diamond if-conversion limit (default 3)"),
- cl::init(3));
-
Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI)
: ARMBaseInstrInfo(STI), RI(*this, STI) {
}
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);
-}
-
void Thumb2InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, DebugLoc DL,
unsigned DestReg, unsigned SrcReg,
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;
-
void copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, DebugLoc DL,
unsigned DestReg, unsigned SrcReg,
; in a register, and it shouldn't require any reloads here.
; CHECK: @ %bb24
-; CHECK-NEXT: @ in Loop: Header=BB1_1 Depth=1
-; CHECK-NEXT: sub{{.*}} [[REGISTER:(r[0-9]+)|(lr)]], #1
+; CHECK: subs{{.*}} [[REGISTER:(r[0-9]+)|(lr)]], #1
; CHECK-NEXT: bne.w
%92 = icmp eq i32 %tmp81, %indvar78 ; <i1> [#uses=1]