Factorize (and generalize) the code promoting SELECT
[oota-llvm.git] / lib / CodeGen / IfConversion.cpp
index 2b3bdc2c983cbf143774a432b9745e04614db023..8d212a606fdf305012b13e8e20decadcb19923c0 100644 (file)
@@ -56,7 +56,7 @@ STATISTIC(NumIfConvBBs,    "Number of if-converted blocks");
 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.
@@ -103,8 +103,8 @@ namespace {
       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),
@@ -146,10 +146,10 @@ namespace {
     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);
@@ -161,7 +161,7 @@ namespace {
     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);
@@ -173,9 +173,9 @@ namespace {
                           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);
 
@@ -215,6 +215,9 @@ namespace {
   char IfConverter::ID = 0;
 }
 
+static RegisterPass<IfConverter>
+X("if-converter", "If Converter");
+
 FunctionPass *llvm::createIfConverterPass() { return new IfConverter(); }
 
 bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
@@ -237,7 +240,7 @@ 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;
@@ -253,6 +256,10 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
       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.
@@ -278,9 +285,10 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
                  : BBI.TrueBB->getNumber()) << ") ";
         RetVal = IfConvertSimple(BBI, Kind);
         DOUT << (RetVal ? "succeeded!" : "failed!") << "\n";
-        if (RetVal)
+        if (RetVal) {
           if (isFalse) NumSimpleFalse++;
           else         NumSimple++;
+        }
        break;
       }
       case ICTriangle:
@@ -319,7 +327,7 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
         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;
@@ -428,7 +436,7 @@ bool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
 
     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 {
@@ -600,7 +608,7 @@ void IfConverter::ScanInstructions(BBInfo &BBI) {
 /// 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)
@@ -616,8 +624,8 @@ bool IfConverter::FeasibilityAnalysis(BBInfo &BBI,
       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;
@@ -646,7 +654,7 @@ IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB,
   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;
@@ -668,7 +676,7 @@ IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB,
     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;
@@ -811,7 +819,7 @@ void IfConverter::InvalidatePreds(MachineBasicBlock *BB) {
 ///
 static void InsertUncondBranch(MachineBasicBlock *BB, MachineBasicBlock *ToBB,
                                const TargetInstrInfo *TII) {
-  std::vector<MachineOperand> NoCond;
+  SmallVector<MachineOperand, 0> NoCond;
   TII->InsertBranch(*BB, ToBB, NULL, NoCond);
 }
 
@@ -819,7 +827,7 @@ static void InsertUncondBranch(MachineBasicBlock *BB, MachineBasicBlock *ToBB,
 /// 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());
 }
@@ -832,7 +840,7 @@ bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) {
   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);
 
@@ -845,7 +853,8 @@ bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) {
   }
 
   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);
@@ -897,7 +906,7 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
   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);
 
@@ -910,21 +919,23 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
   }
 
   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;
+        }
       }
     }
   }
@@ -950,7 +961,8 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
 
   // 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);
@@ -1022,10 +1034,11 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
   // 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;
@@ -1107,7 +1120,7 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
 /// 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;
@@ -1128,8 +1141,10 @@ void IfConverter::PredicateBlock(BBInfo &BBI,
 /// 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 TargetInstrDesc &TID = I->getDesc();
@@ -1138,7 +1153,7 @@ void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
     if (IgnoreBr && !isPredicated && TID.isBranch())
       break;
 
-    MachineInstr *MI = I->clone();
+    MachineInstr *MI = MF.CloneMachineInstr(I);
     ToBBI.BB->insert(ToBBI.BB->end(), MI);
     ToBBI.NonPredSize++;