#include "llvm/ADT/STLExtras.h"
using namespace llvm;
-namespace {
- // Hidden options for help debugging.
- cl::opt<int> IfCvtFnStart("ifcvt-fn-start", cl::init(-1), cl::Hidden);
- cl::opt<int> IfCvtFnStop("ifcvt-fn-stop", cl::init(-1), cl::Hidden);
- cl::opt<int> IfCvtLimit("ifcvt-limit", cl::init(-1), cl::Hidden);
- cl::opt<bool> DisableSimple("disable-ifcvt-simple",
- cl::init(false), cl::Hidden);
- cl::opt<bool> DisableSimpleF("disable-ifcvt-simple-false",
- cl::init(false), cl::Hidden);
- cl::opt<bool> DisableTriangle("disable-ifcvt-triangle",
- cl::init(false), cl::Hidden);
- cl::opt<bool> DisableTriangleR("disable-ifcvt-triangle-rev",
- cl::init(false), cl::Hidden);
- cl::opt<bool> DisableTriangleF("disable-ifcvt-triangle-false",
- cl::init(false), cl::Hidden);
- cl::opt<bool> DisableTriangleFR("disable-ifcvt-triangle-false-rev",
- cl::init(false), cl::Hidden);
- cl::opt<bool> DisableDiamond("disable-ifcvt-diamond",
- cl::init(false), cl::Hidden);
-}
+// Hidden options for help debugging.
+static cl::opt<int> IfCvtFnStart("ifcvt-fn-start", cl::init(-1), cl::Hidden);
+static cl::opt<int> IfCvtFnStop("ifcvt-fn-stop", cl::init(-1), cl::Hidden);
+static cl::opt<int> IfCvtLimit("ifcvt-limit", cl::init(-1), cl::Hidden);
+static cl::opt<bool> DisableSimple("disable-ifcvt-simple",
+ cl::init(false), cl::Hidden);
+static cl::opt<bool> DisableSimpleF("disable-ifcvt-simple-false",
+ cl::init(false), cl::Hidden);
+static cl::opt<bool> DisableTriangle("disable-ifcvt-triangle",
+ cl::init(false), cl::Hidden);
+static cl::opt<bool> DisableTriangleR("disable-ifcvt-triangle-rev",
+ cl::init(false), cl::Hidden);
+static cl::opt<bool> DisableTriangleF("disable-ifcvt-triangle-false",
+ cl::init(false), cl::Hidden);
+static cl::opt<bool> DisableTriangleFR("disable-ifcvt-triangle-false-rev",
+ cl::init(false), cl::Hidden);
+static cl::opt<bool> DisableDiamond("disable-ifcvt-diamond",
+ cl::init(false), cl::Hidden);
STATISTIC(NumSimple, "Number of simple if-conversions performed");
STATISTIC(NumSimpleFalse, "Number of simple (F) if-conversions performed");
STATISTIC(NumDupBBs, "Number of duplicated blocks");
namespace {
- class IfConverter : public MachineFunctionPass {
+ class VISIBILITY_HIDDEN IfConverter : public MachineFunctionPass {
enum IfcvtKind {
ICNotClassfied, // BB data valid, but not classified.
ICSimpleFalse, // Same as ICSimple, but on the false path.
MachineBasicBlock *BB;
MachineBasicBlock *TrueBB;
MachineBasicBlock *FalseBB;
- std::vector<MachineOperand> BrCond;
- std::vector<MachineOperand> Predicate;
+ SmallVector<MachineOperand, 4> BrCond;
+ SmallVector<MachineOperand, 4> Predicate;
BBInfo() : IsDone(false), IsBeingAnalyzed(false),
IsAnalyzed(false), IsEnqueued(false), IsBrAnalyzable(false),
HasFallThrough(false), IsUnpredicable(false),
bool MadeChange;
public:
static char ID;
- IfConverter() : MachineFunctionPass((intptr_t)&ID) {}
+ IfConverter() : MachineFunctionPass(&ID) {}
virtual bool runOnMachineFunction(MachineFunction &MF);
- virtual const char *getPassName() const { return "If converter"; }
+ virtual const char *getPassName() const { return "If Converter"; }
private:
bool ReverseBranchCondition(BBInfo &BBI);
void ScanInstructions(BBInfo &BBI);
BBInfo &AnalyzeBlock(MachineBasicBlock *BB,
std::vector<IfcvtToken*> &Tokens);
- bool FeasibilityAnalysis(BBInfo &BBI, std::vector<MachineOperand> &Cond,
+ bool FeasibilityAnalysis(BBInfo &BBI, SmallVectorImpl<MachineOperand> &Cond,
bool isTriangle = false, bool RevBranch = false);
bool AnalyzeBlocks(MachineFunction &MF,
std::vector<IfcvtToken*> &Tokens);
unsigned NumDups1, unsigned NumDups2);
void PredicateBlock(BBInfo &BBI,
MachineBasicBlock::iterator E,
- std::vector<MachineOperand> &Cond);
+ SmallVectorImpl<MachineOperand> &Cond);
void CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
- std::vector<MachineOperand> &Cond,
+ SmallVectorImpl<MachineOperand> &Cond,
bool IgnoreBr = false);
void MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI);
char IfConverter::ID = 0;
}
+static RegisterPass<IfConverter>
+X("if-converter", "If Converter");
+
FunctionPass *llvm::createIfConverterPass() { return new IfConverter(); }
bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
// Look for root nodes, i.e. blocks without successors.
for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
- if (I->succ_size() == 0)
+ if (I->succ_empty())
Roots.push_back(I);
std::vector<IfcvtToken*> Tokens;
Tokens.pop_back();
BBInfo &BBI = Token->BBI;
IfcvtKind Kind = Token->Kind;
+ unsigned NumDups = Token->NumDups;
+ unsigned NumDups2 = Token->NumDups2;
+
+ delete Token;
// If the block has been evicted out of the queue or it has already been
// marked dead (due to it being predicated), then skip it.
: BBI.TrueBB->getNumber()) << ") ";
RetVal = IfConvertSimple(BBI, Kind);
DOUT << (RetVal ? "succeeded!" : "failed!") << "\n";
- if (RetVal)
+ if (RetVal) {
if (isFalse) NumSimpleFalse++;
else NumSimple++;
+ }
break;
}
case ICTriangle:
DOUT << "Ifcvt (Diamond): BB#" << BBI.BB->getNumber() << " (T:"
<< BBI.TrueBB->getNumber() << ",F:"
<< BBI.FalseBB->getNumber() << ") ";
- RetVal = IfConvertDiamond(BBI, Kind, Token->NumDups, Token->NumDups2);
+ RetVal = IfConvertDiamond(BBI, Kind, NumDups, NumDups2);
DOUT << (RetVal ? "succeeded!" : "failed!") << "\n";
if (RetVal) NumDiamonds++;
break;
unsigned Size = TrueBBI.NonPredSize;
if (TrueBBI.IsBrAnalyzable) {
- if (TrueBBI.TrueBB && TrueBBI.BrCond.size() == 0)
+ if (TrueBBI.TrueBB && TrueBBI.BrCond.empty())
// End with an unconditional branch. It will be removed.
--Size;
else {
MachineBasicBlock::iterator I = BB->end();
while (I != BB->begin()) {
--I;
- if (!I->getDesc()->isBranch())
+ if (!I->getDesc().isBranch())
break;
}
return I;
bool SeenCondBr = false;
for (MachineBasicBlock::iterator I = BBI.BB->begin(), E = BBI.BB->end();
I != E; ++I) {
- const TargetInstrDescriptor *TID = I->getDesc();
- if (TID->isNotDuplicable())
+ const TargetInstrDesc &TID = I->getDesc();
+ if (TID.isNotDuplicable())
BBI.CannotBeCopied = true;
bool isPredicated = TII->isPredicated(I);
- bool isCondBr = BBI.IsBrAnalyzable && TID->isBranch() && !TID->isBarrier();
+ bool isCondBr = BBI.IsBrAnalyzable && TID.isConditionalBranch();
if (!isCondBr) {
if (!isPredicated)
if (TII->DefinesPredicate(I, PredDefs))
BBI.ClobbersPred = true;
- if (!TID->isPredicable()) {
+ if (!TID.isPredicable()) {
BBI.IsUnpredicable = true;
return;
}
/// FeasibilityAnalysis - Determine if the block is a suitable candidate to be
/// predicated by the specified predicate.
bool IfConverter::FeasibilityAnalysis(BBInfo &BBI,
- std::vector<MachineOperand> &Pred,
+ SmallVectorImpl<MachineOperand> &Pred,
bool isTriangle, bool RevBranch) {
// If the block is dead or unpredicable, then it cannot be predicated.
if (BBI.IsDone || BBI.IsUnpredicable)
return false;
// Test predicate subsumsion.
- std::vector<MachineOperand> RevPred(Pred);
- std::vector<MachineOperand> Cond(BBI.BrCond);
+ SmallVector<MachineOperand, 4> RevPred(Pred.begin(), Pred.end());
+ SmallVector<MachineOperand, 4> Cond(BBI.BrCond.begin(), BBI.BrCond.end());
if (RevBranch) {
if (TII->ReverseBranchCondition(Cond))
return false;
ScanInstructions(BBI);
// Unanalyable or ends with fallthrough or unconditional branch.
- if (!BBI.IsBrAnalyzable || BBI.BrCond.size() == 0) {
+ if (!BBI.IsBrAnalyzable || BBI.BrCond.empty()) {
BBI.IsBeingAnalyzed = false;
BBI.IsAnalyzed = true;
return BBI;
return BBI;
}
- std::vector<MachineOperand> RevCond(BBI.BrCond);
+ SmallVector<MachineOperand, 4> RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
bool CanRevCond = !TII->ReverseBranchCondition(RevCond);
unsigned Dups = 0;
///
static void InsertUncondBranch(MachineBasicBlock *BB, MachineBasicBlock *ToBB,
const TargetInstrInfo *TII) {
- std::vector<MachineOperand> NoCond;
+ SmallVector<MachineOperand, 0> NoCond;
TII->InsertBranch(*BB, ToBB, NULL, NoCond);
}
/// successors.
void IfConverter::RemoveExtraEdges(BBInfo &BBI) {
MachineBasicBlock *TBB = NULL, *FBB = NULL;
- std::vector<MachineOperand> Cond;
+ SmallVector<MachineOperand, 4> Cond;
if (!TII->AnalyzeBranch(*BBI.BB, TBB, FBB, Cond))
BBI.BB->CorrectExtraCFGEdges(TBB, FBB, !Cond.empty());
}
BBInfo *CvtBBI = &TrueBBI;
BBInfo *NextBBI = &FalseBBI;
- std::vector<MachineOperand> Cond(BBI.BrCond);
+ SmallVector<MachineOperand, 4> Cond(BBI.BrCond.begin(), BBI.BrCond.end());
if (Kind == ICSimpleFalse)
std::swap(CvtBBI, NextBBI);
}
if (Kind == ICSimpleFalse)
- TII->ReverseBranchCondition(Cond);
+ if (TII->ReverseBranchCondition(Cond))
+ assert(false && "Unable to reverse branch condition!");
if (CvtBBI->BB->pred_size() > 1) {
BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
BBInfo *CvtBBI = &TrueBBI;
BBInfo *NextBBI = &FalseBBI;
- std::vector<MachineOperand> Cond(BBI.BrCond);
+ SmallVector<MachineOperand, 4> Cond(BBI.BrCond.begin(), BBI.BrCond.end());
if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
std::swap(CvtBBI, NextBBI);
}
if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
- TII->ReverseBranchCondition(Cond);
+ if (TII->ReverseBranchCondition(Cond))
+ assert(false && "Unable to reverse branch condition!");
if (Kind == ICTriangleRev || Kind == ICTriangleFRev) {
- ReverseBranchCondition(*CvtBBI);
- // BB has been changed, modify its predecessors (except for this
- // one) so they don't get ifcvt'ed based on bad intel.
- for (MachineBasicBlock::pred_iterator PI = CvtBBI->BB->pred_begin(),
- E = CvtBBI->BB->pred_end(); PI != E; ++PI) {
- MachineBasicBlock *PBB = *PI;
- if (PBB == BBI.BB)
- continue;
- BBInfo &PBBI = BBAnalysis[PBB->getNumber()];
- if (PBBI.IsEnqueued) {
- PBBI.IsAnalyzed = false;
- PBBI.IsEnqueued = false;
+ if (ReverseBranchCondition(*CvtBBI)) {
+ // BB has been changed, modify its predecessors (except for this
+ // one) so they don't get ifcvt'ed based on bad intel.
+ for (MachineBasicBlock::pred_iterator PI = CvtBBI->BB->pred_begin(),
+ E = CvtBBI->BB->pred_end(); PI != E; ++PI) {
+ MachineBasicBlock *PBB = *PI;
+ if (PBB == BBI.BB)
+ continue;
+ BBInfo &PBBI = BBAnalysis[PBB->getNumber()];
+ if (PBBI.IsEnqueued) {
+ PBBI.IsAnalyzed = false;
+ PBBI.IsEnqueued = false;
+ }
}
}
}
// If 'true' block has a 'false' successor, add an exit branch to it.
if (HasEarlyExit) {
- std::vector<MachineOperand> RevCond(CvtBBI->BrCond);
+ SmallVector<MachineOperand, 4> RevCond(CvtBBI->BrCond.begin(),
+ CvtBBI->BrCond.end());
if (TII->ReverseBranchCondition(RevCond))
assert(false && "Unable to reverse branch condition!");
TII->InsertBranch(*BBI.BB, CvtBBI->FalseBB, NULL, RevCond);
// block would clobber the predicate, in that case, do the opposite.
BBInfo *BBI1 = &TrueBBI;
BBInfo *BBI2 = &FalseBBI;
- std::vector<MachineOperand> RevCond(BBI.BrCond);
- TII->ReverseBranchCondition(RevCond);
- std::vector<MachineOperand> *Cond1 = &BBI.BrCond;
- std::vector<MachineOperand> *Cond2 = &RevCond;
+ SmallVector<MachineOperand, 4> RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
+ if (TII->ReverseBranchCondition(RevCond))
+ assert(false && "Unable to reverse branch condition!");
+ SmallVector<MachineOperand, 4> *Cond1 = &BBI.BrCond;
+ SmallVector<MachineOperand, 4> *Cond2 = &RevCond;
// Figure out the more profitable ordering.
bool DoSwap = false;
/// specified end with the specified condition.
void IfConverter::PredicateBlock(BBInfo &BBI,
MachineBasicBlock::iterator E,
- std::vector<MachineOperand> &Cond) {
+ SmallVectorImpl<MachineOperand> &Cond) {
for (MachineBasicBlock::iterator I = BBI.BB->begin(); I != E; ++I) {
if (TII->isPredicated(I))
continue;
/// CopyAndPredicateBlock - Copy and predicate instructions from source BB to
/// the destination block. Skip end of block branches if IgnoreBr is true.
void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
- std::vector<MachineOperand> &Cond,
+ SmallVectorImpl<MachineOperand> &Cond,
bool IgnoreBr) {
+ MachineFunction &MF = *ToBBI.BB->getParent();
+
for (MachineBasicBlock::iterator I = FromBBI.BB->begin(),
E = FromBBI.BB->end(); I != E; ++I) {
- const TargetInstrDescriptor *TID = I->getDesc();
+ const TargetInstrDesc &TID = I->getDesc();
bool isPredicated = TII->isPredicated(I);
// Do not copy the end of the block branches.
- if (IgnoreBr && !isPredicated && TID->isBranch())
+ if (IgnoreBr && !isPredicated && TID.isBranch())
break;
- MachineInstr *MI = I->clone();
+ MachineInstr *MI = MF.CloneMachineInstr(I);
ToBBI.BB->insert(ToBBI.BB->end(), MI);
ToBBI.NonPredSize++;
// Fallthrough edge can't be transferred.
if (Succ == FallThrough)
continue;
- if (!ToBBI.BB->isSuccessor(Succ))
- ToBBI.BB->addSuccessor(Succ);
+ ToBBI.BB->addSuccessor(Succ);
}
std::copy(FromBBI.Predicate.begin(), FromBBI.Predicate.end(),
if (Succ == FallThrough)
continue;
FromBBI.BB->removeSuccessor(Succ);
- if (!ToBBI.BB->isSuccessor(Succ))
- ToBBI.BB->addSuccessor(Succ);
+ ToBBI.BB->addSuccessor(Succ);
}
// Now FromBBI always fall through to the next block!
- if (NBB && !FromBBI.BB->isSuccessor(NBB))
+ if (NBB)
FromBBI.BB->addSuccessor(NBB);
std::copy(FromBBI.Predicate.begin(), FromBBI.Predicate.end(),