119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===-- IfConversion.cpp - Machine code if conversion pass. ---------------===//
219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//                     The LLVM Compiler Infrastructure
419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file is distributed under the University of Illinois Open Source
619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// License. See LICENSE.TXT for details.
719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
1019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file implements the machine instruction level if-conversion pass.
1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define DEBUG_TYPE "ifcvt"
1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "BranchFolding.h"
1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Function.h"
1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/Passes.h"
1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineModuleInfo.h"
1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineFunctionPass.h"
2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCInstrItineraries.h"
2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetInstrInfo.h"
2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetLowering.h"
2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetMachine.h"
2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetRegisterInfo.h"
2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/CommandLine.h"
2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/Debug.h"
2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/ErrorHandling.h"
2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/raw_ostream.h"
3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/SmallSet.h"
3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/Statistic.h"
3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/STLExtras.h"
3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanusing namespace llvm;
3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Hidden options for help debugging.
3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic cl::opt<int> IfCvtFnStart("ifcvt-fn-start", cl::init(-1), cl::Hidden);
3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic cl::opt<int> IfCvtFnStop("ifcvt-fn-stop", cl::init(-1), cl::Hidden);
3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic cl::opt<int> IfCvtLimit("ifcvt-limit", cl::init(-1), cl::Hidden);
3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic cl::opt<bool> DisableSimple("disable-ifcvt-simple",
4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   cl::init(false), cl::Hidden);
4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic cl::opt<bool> DisableSimpleF("disable-ifcvt-simple-false",
4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                    cl::init(false), cl::Hidden);
4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic cl::opt<bool> DisableTriangle("disable-ifcvt-triangle",
4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                     cl::init(false), cl::Hidden);
4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic cl::opt<bool> DisableTriangleR("disable-ifcvt-triangle-rev",
4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                      cl::init(false), cl::Hidden);
4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic cl::opt<bool> DisableTriangleF("disable-ifcvt-triangle-false",
4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                      cl::init(false), cl::Hidden);
4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic cl::opt<bool> DisableTriangleFR("disable-ifcvt-triangle-false-rev",
5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       cl::init(false), cl::Hidden);
5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic cl::opt<bool> DisableDiamond("disable-ifcvt-diamond",
5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                    cl::init(false), cl::Hidden);
5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic cl::opt<bool> IfCvtBranchFold("ifcvt-branch-fold",
5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                     cl::init(true), cl::Hidden);
5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumSimple,       "Number of simple if-conversions performed");
5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumSimpleFalse,  "Number of simple (F) if-conversions performed");
5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumTriangle,     "Number of triangle if-conversions performed");
5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumTriangleRev,  "Number of triangle (R) if-conversions performed");
6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumTriangleFalse,"Number of triangle (F) if-conversions performed");
6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumTriangleFRev, "Number of triangle (F/R) if-conversions performed");
6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumDiamonds,     "Number of diamond if-conversions performed");
6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumIfConvBBs,    "Number of if-converted blocks");
6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumDupBBs,       "Number of duplicated blocks");
6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace {
6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  class IfConverter : public MachineFunctionPass {
6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    enum IfcvtKind {
6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ICNotClassfied,  // BB data valid, but not classified.
7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ICSimpleFalse,   // Same as ICSimple, but on the false path.
7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ICSimple,        // BB is entry of an one split, no rejoin sub-CFG.
7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ICTriangleFRev,  // Same as ICTriangleFalse, but false path rev condition.
7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ICTriangleRev,   // Same as ICTriangle, but true path rev condition.
7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ICTriangleFalse, // Same as ICTriangle, but on the false path.
7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ICTriangle,      // BB is entry of a triangle sub-CFG.
7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ICDiamond        // BB is entry of a diamond sub-CFG.
7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    };
7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// BBInfo - One per MachineBasicBlock, this is used to cache the result
8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// if-conversion feasibility analysis. This includes results from
8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// TargetInstrInfo::AnalyzeBranch() (i.e. TBB, FBB, and Cond), and its
8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// classification, and common tail block of its successors (if it's a
8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// diamond shape), its size, whether it's predicable, and whether any
8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// instruction can clobber the 'would-be' predicate.
8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ///
8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// IsDone          - True if BB is not to be considered for ifcvt.
8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// IsBeingAnalyzed - True if BB is currently being analyzed.
8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// IsAnalyzed      - True if BB has been analyzed (info is still valid).
8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// IsEnqueued      - True if BB has been enqueued to be ifcvt'ed.
9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// IsBrAnalyzable  - True if AnalyzeBranch() returns false.
9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// HasFallThrough  - True if BB may fallthrough to the following BB.
9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// IsUnpredicable  - True if BB is known to be unpredicable.
9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// ClobbersPred    - True if BB could modify predicates (e.g. has
9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ///                   cmp, call, etc.)
9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// NonPredSize     - Number of non-predicated instructions.
9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// ExtraCost       - Extra cost for multi-cycle instructions.
9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// ExtraCost2      - Some instructions are slower when predicated
9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// BB              - Corresponding MachineBasicBlock.
9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// TrueBB / FalseBB- See AnalyzeBranch().
10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// BrCond          - Conditions for end of block conditional branches.
10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// Predicate       - Predicate used in the BB.
10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    struct BBInfo {
10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      bool IsDone          : 1;
10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      bool IsBeingAnalyzed : 1;
10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      bool IsAnalyzed      : 1;
10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      bool IsEnqueued      : 1;
10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      bool IsBrAnalyzable  : 1;
10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      bool HasFallThrough  : 1;
10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      bool IsUnpredicable  : 1;
11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      bool CannotBeCopied  : 1;
11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      bool ClobbersPred    : 1;
11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      unsigned NonPredSize;
11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      unsigned ExtraCost;
11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      unsigned ExtraCost2;
11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MachineBasicBlock *BB;
11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MachineBasicBlock *TrueBB;
11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MachineBasicBlock *FalseBB;
11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      SmallVector<MachineOperand, 4> BrCond;
11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      SmallVector<MachineOperand, 4> Predicate;
12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      BBInfo() : IsDone(false), IsBeingAnalyzed(false),
12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                 IsAnalyzed(false), IsEnqueued(false), IsBrAnalyzable(false),
12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                 HasFallThrough(false), IsUnpredicable(false),
12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                 CannotBeCopied(false), ClobbersPred(false), NonPredSize(0),
12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                 ExtraCost(0), ExtraCost2(0), BB(0), TrueBB(0), FalseBB(0) {}
12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    };
12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// IfcvtToken - Record information about pending if-conversions to attempt:
12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// BBI             - Corresponding BBInfo.
12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// Kind            - Type of block. See IfcvtKind.
13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// NeedSubsumption - True if the to-be-predicated BB has already been
13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ///                   predicated.
13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// NumDups      - Number of instructions that would be duplicated due
13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ///                   to this if-conversion. (For diamonds, the number of
13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ///                   identical instructions at the beginnings of both
13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ///                   paths).
13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// NumDups2     - For diamonds, the number of identical instructions
13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ///                   at the ends of both paths.
13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    struct IfcvtToken {
13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      BBInfo &BBI;
14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      IfcvtKind Kind;
14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      bool NeedSubsumption;
14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      unsigned NumDups;
14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      unsigned NumDups2;
14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      IfcvtToken(BBInfo &b, IfcvtKind k, bool s, unsigned d, unsigned d2 = 0)
14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        : BBI(b), Kind(k), NeedSubsumption(s), NumDups(d), NumDups2(d2) {}
14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    };
14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// BBAnalysis - Results of if-conversion feasibility analysis indexed by
14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// basic block number.
15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::vector<BBInfo> BBAnalysis;
15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const TargetLowering *TLI;
15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const TargetInstrInfo *TII;
15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const TargetRegisterInfo *TRI;
15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const InstrItineraryData *InstrItins;
15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MachineBranchProbabilityInfo *MBPI;
15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool MadeChange;
15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    int FnNum;
16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  public:
16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    static char ID;
16219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IfConverter() : MachineFunctionPass(ID), FnNum(-1) {
16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      initializeIfConverterPass(*PassRegistry::getPassRegistry());
16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
16519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      AU.addRequired<MachineBranchProbabilityInfo>();
16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MachineFunctionPass::getAnalysisUsage(AU);
16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual bool runOnMachineFunction(MachineFunction &MF);
17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual const char *getPassName() const { return "If Converter"; }
17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  private:
17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool ReverseBranchCondition(BBInfo &BBI);
17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool ValidSimple(BBInfo &TrueBBI, unsigned &Dups,
17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     const BranchProbability &Prediction) const;
17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                       bool FalseBranch, unsigned &Dups,
18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                       const BranchProbability &Prediction) const;
18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                      unsigned &Dups1, unsigned &Dups2) const;
18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void ScanInstructions(BBInfo &BBI);
18419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBInfo &AnalyzeBlock(MachineBasicBlock *BB,
18519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         std::vector<IfcvtToken*> &Tokens);
18619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool FeasibilityAnalysis(BBInfo &BBI, SmallVectorImpl<MachineOperand> &Cond,
18719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             bool isTriangle = false, bool RevBranch = false);
18819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void AnalyzeBlocks(MachineFunction &MF, std::vector<IfcvtToken*> &Tokens);
18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void InvalidatePreds(MachineBasicBlock *BB);
19019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void RemoveExtraEdges(BBInfo &BBI);
19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool IfConvertSimple(BBInfo &BBI, IfcvtKind Kind);
19219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind);
19319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
19419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                          unsigned NumDups1, unsigned NumDups2);
19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void PredicateBlock(BBInfo &BBI,
19619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                        MachineBasicBlock::iterator E,
19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                        SmallVectorImpl<MachineOperand> &Cond,
19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                        SmallSet<unsigned, 4> &Redefs);
19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               SmallVectorImpl<MachineOperand> &Cond,
20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               SmallSet<unsigned, 4> &Redefs,
20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               bool IgnoreBr = false);
20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI, bool AddEdges = true);
20419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool MeetIfcvtSizeLimit(MachineBasicBlock &BB,
20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            unsigned Cycle, unsigned Extra,
20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            const BranchProbability &Prediction) const {
20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return Cycle > 0 && TII->isProfitableToIfCvt(BB, Cycle, Extra,
20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                   Prediction);
21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool MeetIfcvtSizeLimit(MachineBasicBlock &TBB,
21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            unsigned TCycle, unsigned TExtra,
21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            MachineBasicBlock &FBB,
21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            unsigned FCycle, unsigned FExtra,
21619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            const BranchProbability &Prediction) const {
21719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return TCycle > 0 && FCycle > 0 &&
21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        TII->isProfitableToIfCvt(TBB, TCycle, TExtra, FBB, FCycle, FExtra,
21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                 Prediction);
22019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // blockAlwaysFallThrough - Block ends without a terminator.
22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool blockAlwaysFallThrough(BBInfo &BBI) const {
22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return BBI.IsBrAnalyzable && BBI.TrueBB == NULL;
22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // IfcvtTokenCmp - Used to sort if-conversion candidates.
22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    static bool IfcvtTokenCmp(IfcvtToken *C1, IfcvtToken *C2) {
22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      int Incr1 = (C1->Kind == ICDiamond)
23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        ? -(int)(C1->NumDups + C1->NumDups2) : (int)C1->NumDups;
23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      int Incr2 = (C2->Kind == ICDiamond)
23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        ? -(int)(C2->NumDups + C2->NumDups2) : (int)C2->NumDups;
23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Incr1 > Incr2)
23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return true;
23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      else if (Incr1 == Incr2) {
23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Favors subsumption.
23719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (C1->NeedSubsumption == false && C2->NeedSubsumption == true)
23819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          return true;
23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        else if (C1->NeedSubsumption == C2->NeedSubsumption) {
24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // Favors diamond over triangle, etc.
24119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if ((unsigned)C1->Kind < (unsigned)C2->Kind)
24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            return true;
24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          else if (C1->Kind == C2->Kind)
24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            return C1->BBI.BB->getNumber() < C2->BBI.BB->getNumber();
24519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
24619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
24719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
24819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
25019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  char IfConverter::ID = 0;
25219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS_BEGIN(IfConverter, "if-converter", "If Converter", false, false)
25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
25619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS_END(IfConverter, "if-converter", "If Converter", false, false)
25719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
25819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanFunctionPass *llvm::createIfConverterPass() { return new IfConverter(); }
25919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
26019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool IfConverter::runOnMachineFunction(MachineFunction &MF) {
26119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  TLI = MF.getTarget().getTargetLowering();
26219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  TII = MF.getTarget().getInstrInfo();
26319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  TRI = MF.getTarget().getRegisterInfo();
26419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
26519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  InstrItins = MF.getTarget().getInstrItineraryData();
26619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!TII) return false;
26719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
26819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Tail merge tend to expose more if-conversion opportunities.
26919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BranchFolder BF(true, false);
27019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool BFChange = BF.OptimizeFunction(MF, TII,
27119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   MF.getTarget().getRegisterInfo(),
27219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   getAnalysisIfAvailable<MachineModuleInfo>());
27319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
27419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DEBUG(dbgs() << "\nIfcvt: function (" << ++FnNum <<  ") \'"
27519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               << MF.getFunction()->getName() << "\'");
27619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
27719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (FnNum < IfCvtFnStart || (IfCvtFnStop != -1 && FnNum > IfCvtFnStop)) {
27819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    DEBUG(dbgs() << " skipped\n");
27919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
28019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DEBUG(dbgs() << "\n");
28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MF.RenumberBlocks();
28419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBAnalysis.resize(MF.getNumBlockIDs());
28519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
28619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::vector<IfcvtToken*> Tokens;
28719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MadeChange = false;
28819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle +
28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    NumTriangleRev + NumTriangleFalse + NumTriangleFRev + NumDiamonds;
29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (IfCvtLimit == -1 || (int)NumIfCvts < IfCvtLimit) {
29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Do an initial analysis for each basic block and find all the potential
29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // candidates to perform if-conversion.
29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool Change = false;
29419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AnalyzeBlocks(MF, Tokens);
29519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    while (!Tokens.empty()) {
29619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      IfcvtToken *Token = Tokens.back();
29719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Tokens.pop_back();
29819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      BBInfo &BBI = Token->BBI;
29919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      IfcvtKind Kind = Token->Kind;
30019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      unsigned NumDups = Token->NumDups;
30119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      unsigned NumDups2 = Token->NumDups2;
30219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      delete Token;
30419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
30519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // If the block has been evicted out of the queue or it has already been
30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // marked dead (due to it being predicated), then skip it.
30719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (BBI.IsDone)
30819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        BBI.IsEnqueued = false;
30919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!BBI.IsEnqueued)
31019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        continue;
31119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
31219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      BBI.IsEnqueued = false;
31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
31419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      bool RetVal = false;
31519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      switch (Kind) {
31619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      default: assert(false && "Unexpected!");
31719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
31819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case ICSimple:
31919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case ICSimpleFalse: {
32019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        bool isFalse = Kind == ICSimpleFalse;
32119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if ((isFalse && DisableSimpleF) || (!isFalse && DisableSimple)) break;
32219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        DEBUG(dbgs() << "Ifcvt (Simple" << (Kind == ICSimpleFalse ?
32319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                            " false" : "")
32419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     << "): BB#" << BBI.BB->getNumber() << " ("
32519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     << ((Kind == ICSimpleFalse)
32619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         ? BBI.FalseBB->getNumber()
32719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         : BBI.TrueBB->getNumber()) << ") ");
32819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        RetVal = IfConvertSimple(BBI, Kind);
32919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        DEBUG(dbgs() << (RetVal ? "succeeded!" : "failed!") << "\n");
33019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (RetVal) {
33119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (isFalse) ++NumSimpleFalse;
33219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          else         ++NumSimple;
33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
33419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       break;
33519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
33619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case ICTriangle:
33719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case ICTriangleRev:
33819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case ICTriangleFalse:
33919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case ICTriangleFRev: {
34019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        bool isFalse = Kind == ICTriangleFalse;
34119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        bool isRev   = (Kind == ICTriangleRev || Kind == ICTriangleFRev);
34219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (DisableTriangle && !isFalse && !isRev) break;
34319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (DisableTriangleR && !isFalse && isRev) break;
34419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (DisableTriangleF && isFalse && !isRev) break;
34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (DisableTriangleFR && isFalse && isRev) break;
34619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        DEBUG(dbgs() << "Ifcvt (Triangle");
34719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (isFalse)
34819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          DEBUG(dbgs() << " false");
34919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (isRev)
35019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          DEBUG(dbgs() << " rev");
35119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        DEBUG(dbgs() << "): BB#" << BBI.BB->getNumber() << " (T:"
35219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     << BBI.TrueBB->getNumber() << ",F:"
35319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     << BBI.FalseBB->getNumber() << ") ");
35419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        RetVal = IfConvertTriangle(BBI, Kind);
35519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        DEBUG(dbgs() << (RetVal ? "succeeded!" : "failed!") << "\n");
35619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (RetVal) {
35719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (isFalse) {
35819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            if (isRev) ++NumTriangleFRev;
35919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            else       ++NumTriangleFalse;
36019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          } else {
36119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            if (isRev) ++NumTriangleRev;
36219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            else       ++NumTriangle;
36319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          }
36419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
36519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
36619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
36719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case ICDiamond: {
36819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (DisableDiamond) break;
36919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        DEBUG(dbgs() << "Ifcvt (Diamond): BB#" << BBI.BB->getNumber() << " (T:"
37019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     << BBI.TrueBB->getNumber() << ",F:"
37119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     << BBI.FalseBB->getNumber() << ") ");
37219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        RetVal = IfConvertDiamond(BBI, Kind, NumDups, NumDups2);
37319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        DEBUG(dbgs() << (RetVal ? "succeeded!" : "failed!") << "\n");
37419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (RetVal) ++NumDiamonds;
37519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
37619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
37719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
37819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
37919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Change |= RetVal;
38019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
38119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle + NumTriangleRev +
38219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        NumTriangleFalse + NumTriangleFRev + NumDiamonds;
38319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (IfCvtLimit != -1 && (int)NumIfCvts >= IfCvtLimit)
38419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
38519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
38619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
38719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!Change)
38819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
38919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MadeChange |= Change;
39019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
39119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
39219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Delete tokens in case of early exit.
39319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (!Tokens.empty()) {
39419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IfcvtToken *Token = Tokens.back();
39519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Tokens.pop_back();
39619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    delete Token;
39719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
39819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
39919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Tokens.clear();
40019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBAnalysis.clear();
40119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
40219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (MadeChange && IfCvtBranchFold) {
40319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BranchFolder BF(false, false);
40419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BF.OptimizeFunction(MF, TII,
40519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                        MF.getTarget().getRegisterInfo(),
40619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                        getAnalysisIfAvailable<MachineModuleInfo>());
40719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
40819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
40919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MadeChange |= BFChange;
41019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return MadeChange;
41119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
41219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
41319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// findFalseBlock - BB has a fallthrough. Find its 'false' successor given
41419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// its 'true' successor.
41519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic MachineBasicBlock *findFalseBlock(MachineBasicBlock *BB,
41619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                         MachineBasicBlock *TrueBB) {
41719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(),
41819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         E = BB->succ_end(); SI != E; ++SI) {
41919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MachineBasicBlock *SuccBB = *SI;
42019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (SuccBB != TrueBB)
42119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return SuccBB;
42219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
42319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return NULL;
42419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
42519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
42619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ReverseBranchCondition - Reverse the condition of the end of the block
42719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// branch. Swap block's 'true' and 'false' successors.
42819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool IfConverter::ReverseBranchCondition(BBInfo &BBI) {
42919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DebugLoc dl;  // FIXME: this is nowhere
43019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!TII->ReverseBranchCondition(BBI.BrCond)) {
43119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    TII->RemoveBranch(*BBI.BB);
43219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    TII->InsertBranch(*BBI.BB, BBI.FalseBB, BBI.TrueBB, BBI.BrCond, dl);
43319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::swap(BBI.TrueBB, BBI.FalseBB);
43419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
43519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
43619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
43719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
43819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
43919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// getNextBlock - Returns the next block in the function blocks ordering. If
44019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// it is the end, returns NULL.
44119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic inline MachineBasicBlock *getNextBlock(MachineBasicBlock *BB) {
44219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineFunction::iterator I = BB;
44319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineFunction::iterator E = BB->getParent()->end();
44419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (++I == E)
44519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return NULL;
44619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return I;
44719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
44819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
44919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ValidSimple - Returns true if the 'true' block (along with its
45019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// predecessor) forms a valid simple shape for ifcvt. It also returns the
45119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// number of instructions that the ifcvt would need to duplicate if performed
45219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// in Dups.
45319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool IfConverter::ValidSimple(BBInfo &TrueBBI, unsigned &Dups,
45419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                              const BranchProbability &Prediction) const {
45519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Dups = 0;
45619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
45719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
45819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
45919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TrueBBI.IsBrAnalyzable)
46019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
46119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
46219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TrueBBI.BB->pred_size() > 1) {
46319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (TrueBBI.CannotBeCopied ||
46419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        !TII->isProfitableToDupForIfCvt(*TrueBBI.BB, TrueBBI.NonPredSize,
46519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                        Prediction))
46619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
46719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Dups = TrueBBI.NonPredSize;
46819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
46919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
47019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
47119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
47219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
47319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ValidTriangle - Returns true if the 'true' and 'false' blocks (along
47419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// with their common predecessor) forms a valid triangle shape for ifcvt.
47519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// If 'FalseBranch' is true, it checks if 'true' block's false branch
47619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// branches to the 'false' block rather than the other way around. It also
47719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// returns the number of instructions that the ifcvt would need to duplicate
47819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// if performed in 'Dups'.
47919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
48019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                bool FalseBranch, unsigned &Dups,
48119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                const BranchProbability &Prediction) const {
48219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Dups = 0;
48319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
48419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
48519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
48619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TrueBBI.BB->pred_size() > 1) {
48719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (TrueBBI.CannotBeCopied)
48819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
48919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
49019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned Size = TrueBBI.NonPredSize;
49119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (TrueBBI.IsBrAnalyzable) {
49219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (TrueBBI.TrueBB && TrueBBI.BrCond.empty())
49319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Ends with an unconditional branch. It will be removed.
49419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        --Size;
49519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      else {
49619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        MachineBasicBlock *FExit = FalseBranch
49719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          ? TrueBBI.TrueBB : TrueBBI.FalseBB;
49819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (FExit)
49919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // Require a conditional branch
50019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          ++Size;
50119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
50219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
50319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!TII->isProfitableToDupForIfCvt(*TrueBBI.BB, Size, Prediction))
50419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
50519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Dups = Size;
50619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
50719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
50819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineBasicBlock *TExit = FalseBranch ? TrueBBI.FalseBB : TrueBBI.TrueBB;
50919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!TExit && blockAlwaysFallThrough(TrueBBI)) {
51019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MachineFunction::iterator I = TrueBBI.BB;
51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (++I == TrueBBI.BB->getParent()->end())
51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
51319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    TExit = I;
51419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
51519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return TExit && TExit == FalseBBI.BB;
51619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
51719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
51819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ValidDiamond - Returns true if the 'true' and 'false' blocks (along
51919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// with their common predecessor) forms a valid diamond shape for ifcvt.
52019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool IfConverter::ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
52119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               unsigned &Dups1, unsigned &Dups2) const {
52219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Dups1 = Dups2 = 0;
52319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
52419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)
52519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
52619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
52719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineBasicBlock *TT = TrueBBI.TrueBB;
52819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineBasicBlock *FT = FalseBBI.TrueBB;
52919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
53019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!TT && blockAlwaysFallThrough(TrueBBI))
53119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    TT = getNextBlock(TrueBBI.BB);
53219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!FT && blockAlwaysFallThrough(FalseBBI))
53319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FT = getNextBlock(FalseBBI.BB);
53419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TT != FT)
53519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
53619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TT == NULL && (TrueBBI.IsBrAnalyzable || FalseBBI.IsBrAnalyzable))
53719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
53819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if  (TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1)
53919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
54019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
54119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // FIXME: Allow true block to have an early exit?
54219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TrueBBI.FalseBB || FalseBBI.FalseBB ||
54319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      (TrueBBI.ClobbersPred && FalseBBI.ClobbersPred))
54419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
54519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
54619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Count duplicate instructions at the beginning of the true and false blocks.
54719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineBasicBlock::iterator TIB = TrueBBI.BB->begin();
54819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineBasicBlock::iterator FIB = FalseBBI.BB->begin();
54919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineBasicBlock::iterator TIE = TrueBBI.BB->end();
55019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineBasicBlock::iterator FIE = FalseBBI.BB->end();
55119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (TIB != TIE && FIB != FIE) {
55219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Skip dbg_value instructions. These do not count.
55319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (TIB->isDebugValue()) {
55419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      while (TIB != TIE && TIB->isDebugValue())
55519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        ++TIB;
55619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (TIB == TIE)
55719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
55819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
55919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (FIB->isDebugValue()) {
56019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      while (FIB != FIE && FIB->isDebugValue())
56119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        ++FIB;
56219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (FIB == FIE)
56319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
56419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
56519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!TIB->isIdenticalTo(FIB))
56619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
56719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ++Dups1;
56819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ++TIB;
56919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ++FIB;
57019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
57119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
57219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Now, in preparation for counting duplicate instructions at the ends of the
57319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // blocks, move the end iterators up past any branch instructions.
57419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (TIE != TIB) {
57519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    --TIE;
57619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!TIE->getDesc().isBranch())
57719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
57819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
57919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (FIE != FIB) {
58019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    --FIE;
58119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!FIE->getDesc().isBranch())
58219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
58319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
58419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
58519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If Dups1 includes all of a block, then don't count duplicate
58619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // instructions at the end of the blocks.
58719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TIB == TIE || FIB == FIE)
58819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
58919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
59019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Count duplicate instructions at the ends of the blocks.
59119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (TIE != TIB && FIE != FIB) {
59219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Skip dbg_value instructions. These do not count.
59319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (TIE->isDebugValue()) {
59419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      while (TIE != TIB && TIE->isDebugValue())
59519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        --TIE;
59619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (TIE == TIB)
59719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
59819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
59919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (FIE->isDebugValue()) {
60019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      while (FIE != FIB && FIE->isDebugValue())
60119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        --FIE;
60219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (FIE == FIB)
60319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
60419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
60519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!TIE->isIdenticalTo(FIE))
60619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
60719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ++Dups2;
60819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    --TIE;
60919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    --FIE;
61019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
61119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
61219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
61319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
61419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
61519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ScanInstructions - Scan all the instructions in the block to determine if
61619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// the block is predicable. In most cases, that means all the instructions
61719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// in the block are isPredicable(). Also checks if the block contains any
61819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// instruction which can clobber a predicate (e.g. condition code register).
61919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// If so, the block is not predicable unless it's the last instruction.
62019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid IfConverter::ScanInstructions(BBInfo &BBI) {
62119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (BBI.IsDone)
62219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return;
62319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
62419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool AlreadyPredicated = BBI.Predicate.size() > 0;
62519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // First analyze the end of BB branches.
62619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.TrueBB = BBI.FalseBB = NULL;
62719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.BrCond.clear();
62819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.IsBrAnalyzable =
62919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    !TII->AnalyzeBranch(*BBI.BB, BBI.TrueBB, BBI.FalseBB, BBI.BrCond);
63019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.HasFallThrough = BBI.IsBrAnalyzable && BBI.FalseBB == NULL;
63119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
63219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (BBI.BrCond.size()) {
63319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // No false branch. This BB must end with a conditional branch and a
63419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // fallthrough.
63519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!BBI.FalseBB)
63619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      BBI.FalseBB = findFalseBlock(BBI.BB, BBI.TrueBB);
63719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!BBI.FalseBB) {
63819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Malformed bcc? True and false blocks are the same?
63919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      BBI.IsUnpredicable = true;
64019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return;
64119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
64219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
64319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
64419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Then scan all the instructions.
64519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.NonPredSize = 0;
64619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.ExtraCost = 0;
64719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.ExtraCost2 = 0;
64819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.ClobbersPred = false;
64919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MachineBasicBlock::iterator I = BBI.BB->begin(), E = BBI.BB->end();
65019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       I != E; ++I) {
65119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (I->isDebugValue())
65219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
65319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
65419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCInstrDesc &MCID = I->getDesc();
65519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (MCID.isNotDuplicable())
65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      BBI.CannotBeCopied = true;
65719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
65819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool isPredicated = TII->isPredicated(I);
65919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool isCondBr = BBI.IsBrAnalyzable && MCID.isConditionalBranch();
66019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
66119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!isCondBr) {
66219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!isPredicated) {
66319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        BBI.NonPredSize++;
66419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        unsigned ExtraPredCost = 0;
66519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        unsigned NumCycles = TII->getInstrLatency(InstrItins, &*I,
66619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                  &ExtraPredCost);
66719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (NumCycles > 1)
66819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          BBI.ExtraCost += NumCycles-1;
66919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        BBI.ExtraCost2 += ExtraPredCost;
67019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      } else if (!AlreadyPredicated) {
67119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // FIXME: This instruction is already predicated before the
67219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // if-conversion pass. It's probably something like a conditional move.
67319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Mark this block unpredicable for now.
67419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        BBI.IsUnpredicable = true;
67519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return;
67619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
67719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
67819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
67919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (BBI.ClobbersPred && !isPredicated) {
68019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Predicate modification instruction should end the block (except for
68119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // already predicated instructions and end of block branches).
68219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (isCondBr) {
68319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // A conditional branch is not predicable, but it may be eliminated.
68419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        continue;
68519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
68619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
68719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Predicate may have been modified, the subsequent (currently)
68819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // unpredicated instructions cannot be correctly predicated.
68919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      BBI.IsUnpredicable = true;
69019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return;
69119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
69219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
69319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // FIXME: Make use of PredDefs? e.g. ADDC, SUBC sets predicates but are
69419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // still potentially predicable.
69519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::vector<MachineOperand> PredDefs;
69619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (TII->DefinesPredicate(I, PredDefs))
69719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      BBI.ClobbersPred = true;
69819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
69919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!TII->isPredicable(I)) {
70019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      BBI.IsUnpredicable = true;
70119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return;
70219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
70319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
70419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
70519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
70619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// FeasibilityAnalysis - Determine if the block is a suitable candidate to be
70719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// predicated by the specified predicate.
70819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool IfConverter::FeasibilityAnalysis(BBInfo &BBI,
70919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                      SmallVectorImpl<MachineOperand> &Pred,
71019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                      bool isTriangle, bool RevBranch) {
71119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If the block is dead or unpredicable, then it cannot be predicated.
71219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (BBI.IsDone || BBI.IsUnpredicable)
71319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
71419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
71519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If it is already predicated, check if its predicate subsumes the new
71619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // predicate.
71719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (BBI.Predicate.size() && !TII->SubsumesPredicate(BBI.Predicate, Pred))
71819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
71919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
72019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (BBI.BrCond.size()) {
72119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!isTriangle)
72219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
72319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
72419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Test predicate subsumption.
72519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SmallVector<MachineOperand, 4> RevPred(Pred.begin(), Pred.end());
72619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SmallVector<MachineOperand, 4> Cond(BBI.BrCond.begin(), BBI.BrCond.end());
72719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (RevBranch) {
72819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (TII->ReverseBranchCondition(Cond))
72919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return false;
73019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
73119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (TII->ReverseBranchCondition(RevPred) ||
73219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        !TII->SubsumesPredicate(Cond, RevPred))
73319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
73419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
73519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
73619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
73719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
73819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
73919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// AnalyzeBlock - Analyze the structure of the sub-CFG starting from
74019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// the specified block. Record its successors and whether it looks like an
74119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// if-conversion candidate.
74219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanIfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB,
74319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             std::vector<IfcvtToken*> &Tokens) {
74419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBInfo &BBI = BBAnalysis[BB->getNumber()];
74519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
74619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (BBI.IsAnalyzed || BBI.IsBeingAnalyzed)
74719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return BBI;
74819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
74919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.BB = BB;
75019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.IsBeingAnalyzed = true;
75119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
75219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ScanInstructions(BBI);
75319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
75419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Unanalyzable or ends with fallthrough or unconditional branch, or if is not
75519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // considered for ifcvt anymore.
75619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!BBI.IsBrAnalyzable || BBI.BrCond.empty() || BBI.IsDone) {
75719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.IsBeingAnalyzed = false;
75819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.IsAnalyzed = true;
75919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return BBI;
76019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
76119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
76219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Do not ifcvt if either path is a back edge to the entry block.
76319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (BBI.TrueBB == BB || BBI.FalseBB == BB) {
76419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.IsBeingAnalyzed = false;
76519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.IsAnalyzed = true;
76619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return BBI;
76719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
76819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
76919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Do not ifcvt if true and false fallthrough blocks are the same.
77019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!BBI.FalseBB) {
77119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.IsBeingAnalyzed = false;
77219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.IsAnalyzed = true;
77319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return BBI;
77419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
77519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
77619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBInfo &TrueBBI  = AnalyzeBlock(BBI.TrueBB, Tokens);
77719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBInfo &FalseBBI = AnalyzeBlock(BBI.FalseBB, Tokens);
77819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
77919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TrueBBI.IsDone && FalseBBI.IsDone) {
78019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.IsBeingAnalyzed = false;
78119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.IsAnalyzed = true;
78219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return BBI;
78319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
78419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
78519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<MachineOperand, 4> RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
78619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool CanRevCond = !TII->ReverseBranchCondition(RevCond);
78719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
78819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned Dups = 0;
78919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned Dups2 = 0;
79019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool TNeedSub = TrueBBI.Predicate.size() > 0;
79119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool FNeedSub = FalseBBI.Predicate.size() > 0;
79219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool Enqueued = false;
79319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
79419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BranchProbability Prediction = MBPI->getEdgeProbability(BB, TrueBBI.BB);
79519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
79619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (CanRevCond && ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2) &&
79719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MeetIfcvtSizeLimit(*TrueBBI.BB, (TrueBBI.NonPredSize - (Dups + Dups2) +
79819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       TrueBBI.ExtraCost), TrueBBI.ExtraCost2,
79919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         *FalseBBI.BB, (FalseBBI.NonPredSize - (Dups + Dups2) +
80019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                        FalseBBI.ExtraCost),FalseBBI.ExtraCost2,
80119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         Prediction) &&
80219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      FeasibilityAnalysis(TrueBBI, BBI.BrCond) &&
80319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      FeasibilityAnalysis(FalseBBI, RevCond)) {
80419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Diamond:
80519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //   EBB
80619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //   / \_
80719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //  |   |
80819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // TBB FBB
80919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //   \ /
81019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //  TailBB
81119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Note TailBB can be empty.
81219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Tokens.push_back(new IfcvtToken(BBI, ICDiamond, TNeedSub|FNeedSub, Dups,
81319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                    Dups2));
81419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Enqueued = true;
81519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
81619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
81719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (ValidTriangle(TrueBBI, FalseBBI, false, Dups, Prediction) &&
81819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
81919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         TrueBBI.ExtraCost2, Prediction) &&
82019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      FeasibilityAnalysis(TrueBBI, BBI.BrCond, true)) {
82119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Triangle:
82219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //   EBB
82319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //   | \_
82419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //   |  |
82519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //   | TBB
82619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //   |  /
82719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //   FBB
82819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Tokens.push_back(new IfcvtToken(BBI, ICTriangle, TNeedSub, Dups));
82919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Enqueued = true;
83019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
83119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
83219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (ValidTriangle(TrueBBI, FalseBBI, true, Dups, Prediction) &&
83319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
83419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         TrueBBI.ExtraCost2, Prediction) &&
83519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      FeasibilityAnalysis(TrueBBI, BBI.BrCond, true, true)) {
83619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Tokens.push_back(new IfcvtToken(BBI, ICTriangleRev, TNeedSub, Dups));
83719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Enqueued = true;
83819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
83919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
84019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (ValidSimple(TrueBBI, Dups, Prediction) &&
84119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
84219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         TrueBBI.ExtraCost2, Prediction) &&
84319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      FeasibilityAnalysis(TrueBBI, BBI.BrCond)) {
84419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Simple (split, no rejoin):
84519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //   EBB
84619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //   | \_
84719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //   |  |
84819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //   | TBB---> exit
84919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //   |
85019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //   FBB
85119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Tokens.push_back(new IfcvtToken(BBI, ICSimple, TNeedSub, Dups));
85219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Enqueued = true;
85319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
85419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
85519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (CanRevCond) {
85619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Try the other path...
85719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (ValidTriangle(FalseBBI, TrueBBI, false, Dups,
85819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                      Prediction.getCompl()) &&
85919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        MeetIfcvtSizeLimit(*FalseBBI.BB,
86019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           FalseBBI.NonPredSize + FalseBBI.ExtraCost,
86119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           FalseBBI.ExtraCost2, Prediction.getCompl()) &&
86219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        FeasibilityAnalysis(FalseBBI, RevCond, true)) {
86319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Tokens.push_back(new IfcvtToken(BBI, ICTriangleFalse, FNeedSub, Dups));
86419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Enqueued = true;
86519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
86619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
86719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (ValidTriangle(FalseBBI, TrueBBI, true, Dups,
86819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                      Prediction.getCompl()) &&
86919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        MeetIfcvtSizeLimit(*FalseBBI.BB,
87019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           FalseBBI.NonPredSize + FalseBBI.ExtraCost,
87119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           FalseBBI.ExtraCost2, Prediction.getCompl()) &&
87219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        FeasibilityAnalysis(FalseBBI, RevCond, true, true)) {
87319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Tokens.push_back(new IfcvtToken(BBI, ICTriangleFRev, FNeedSub, Dups));
87419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Enqueued = true;
87519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
87619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
87719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (ValidSimple(FalseBBI, Dups, Prediction.getCompl()) &&
87819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        MeetIfcvtSizeLimit(*FalseBBI.BB,
87919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           FalseBBI.NonPredSize + FalseBBI.ExtraCost,
88019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           FalseBBI.ExtraCost2, Prediction.getCompl()) &&
88119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        FeasibilityAnalysis(FalseBBI, RevCond)) {
88219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Tokens.push_back(new IfcvtToken(BBI, ICSimpleFalse, FNeedSub, Dups));
88319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Enqueued = true;
88419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
88519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
88619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
88719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.IsEnqueued = Enqueued;
88819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.IsBeingAnalyzed = false;
88919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.IsAnalyzed = true;
89019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return BBI;
89119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
89219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
89319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// AnalyzeBlocks - Analyze all blocks and find entries for all if-conversion
89419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// candidates.
89519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid IfConverter::AnalyzeBlocks(MachineFunction &MF,
89619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                std::vector<IfcvtToken*> &Tokens) {
89719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
89819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MachineBasicBlock *BB = I;
89919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AnalyzeBlock(BB, Tokens);
90019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
90119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
90219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Sort to favor more complex ifcvt scheme.
90319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::stable_sort(Tokens.begin(), Tokens.end(), IfcvtTokenCmp);
90419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
90519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
90619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// canFallThroughTo - Returns true either if ToBB is the next block after BB or
90719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// that all the intervening blocks are empty (given BB can fall through to its
90819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// next block).
90919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool canFallThroughTo(MachineBasicBlock *BB, MachineBasicBlock *ToBB) {
91019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineFunction::iterator PI = BB;
91119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineFunction::iterator I = llvm::next(PI);
91219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineFunction::iterator TI = ToBB;
91319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineFunction::iterator E = BB->getParent()->end();
91419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (I != TI) {
91519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Check isSuccessor to avoid case where the next block is empty, but
91619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // it's not a successor.
91719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (I == E || !I->empty() || !PI->isSuccessor(I))
91819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
91919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PI = I++;
92019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
92119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
92219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
92319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
92419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// InvalidatePreds - Invalidate predecessor BB info so it would be re-analyzed
92519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// to determine if it can be if-converted. If predecessor is already enqueued,
92619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// dequeue it!
92719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid IfConverter::InvalidatePreds(MachineBasicBlock *BB) {
92819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MachineBasicBlock::pred_iterator PI = BB->pred_begin(),
92919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         E = BB->pred_end(); PI != E; ++PI) {
93019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBInfo &PBBI = BBAnalysis[(*PI)->getNumber()];
93119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (PBBI.IsDone || PBBI.BB == BB)
93219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
93319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PBBI.IsAnalyzed = false;
93419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PBBI.IsEnqueued = false;
93519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
93619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
93719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
93819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// InsertUncondBranch - Inserts an unconditional branch from BB to ToBB.
93919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///
94019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic void InsertUncondBranch(MachineBasicBlock *BB, MachineBasicBlock *ToBB,
94119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               const TargetInstrInfo *TII) {
94219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DebugLoc dl;  // FIXME: this is nowhere
94319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<MachineOperand, 0> NoCond;
94419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  TII->InsertBranch(*BB, ToBB, NULL, NoCond, dl);
94519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
94619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
94719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// RemoveExtraEdges - Remove true / false edges if either / both are no longer
94819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// successors.
94919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid IfConverter::RemoveExtraEdges(BBInfo &BBI) {
95019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineBasicBlock *TBB = NULL, *FBB = NULL;
95119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<MachineOperand, 4> Cond;
95219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!TII->AnalyzeBranch(*BBI.BB, TBB, FBB, Cond))
95319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.BB->CorrectExtraCFGEdges(TBB, FBB, !Cond.empty());
95419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
95519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
95619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// InitPredRedefs / UpdatePredRedefs - Defs by predicated instructions are
95719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// modeled as read + write (sort like two-address instructions). These
95819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// routines track register liveness and add implicit uses to if-converted
95919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// instructions to conform to the model.
96019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic void InitPredRedefs(MachineBasicBlock *BB, SmallSet<unsigned,4> &Redefs,
96119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           const TargetRegisterInfo *TRI) {
96219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MachineBasicBlock::livein_iterator I = BB->livein_begin(),
96319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         E = BB->livein_end(); I != E; ++I) {
96419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned Reg = *I;
96519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Redefs.insert(Reg);
96619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (const unsigned *Subreg = TRI->getSubRegisters(Reg);
96719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         *Subreg; ++Subreg)
96819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Redefs.insert(*Subreg);
96919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
97019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
97119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
97219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic void UpdatePredRedefs(MachineInstr *MI, SmallSet<unsigned,4> &Redefs,
97319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             const TargetRegisterInfo *TRI,
97419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             bool AddImpUse = false) {
97519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<unsigned, 4> Defs;
97619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
97719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MachineOperand &MO = MI->getOperand(i);
97819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!MO.isReg())
97919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
98019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned Reg = MO.getReg();
98119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!Reg)
98219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
98319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (MO.isDef())
98419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Defs.push_back(Reg);
98519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else if (MO.isKill()) {
98619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Redefs.erase(Reg);
98719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (const unsigned *SR = TRI->getSubRegisters(Reg); *SR; ++SR)
98819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Redefs.erase(*SR);
98919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
99019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
99119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0, e = Defs.size(); i != e; ++i) {
99219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned Reg = Defs[i];
99319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Redefs.count(Reg)) {
99419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (AddImpUse)
99519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Treat predicated update as read + write.
99619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        MI->addOperand(MachineOperand::CreateReg(Reg, false/*IsDef*/,
99719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                true/*IsImp*/,false/*IsKill*/));
99819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else {
99919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Redefs.insert(Reg);
100019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (const unsigned *SR = TRI->getSubRegisters(Reg); *SR; ++SR)
100119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Redefs.insert(*SR);
100219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
100319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
100419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
100519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
100619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic void UpdatePredRedefs(MachineBasicBlock::iterator I,
100719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             MachineBasicBlock::iterator E,
100819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             SmallSet<unsigned,4> &Redefs,
100919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             const TargetRegisterInfo *TRI) {
101019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (I != E) {
101119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    UpdatePredRedefs(I, Redefs, TRI);
101219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ++I;
101319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
101419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
101519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
101619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// IfConvertSimple - If convert a simple (split, no rejoin) sub-CFG.
101719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///
101819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) {
101919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBInfo &TrueBBI  = BBAnalysis[BBI.TrueBB->getNumber()];
102019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
102119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBInfo *CvtBBI = &TrueBBI;
102219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBInfo *NextBBI = &FalseBBI;
102319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
102419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<MachineOperand, 4> Cond(BBI.BrCond.begin(), BBI.BrCond.end());
102519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Kind == ICSimpleFalse)
102619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::swap(CvtBBI, NextBBI);
102719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
102819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (CvtBBI->IsDone ||
102919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      (CvtBBI->CannotBeCopied && CvtBBI->BB->pred_size() > 1)) {
103019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Something has changed. It's no longer safe to predicate this block.
103119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.IsAnalyzed = false;
103219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CvtBBI->IsAnalyzed = false;
103319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
103419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
103519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
103619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Kind == ICSimpleFalse)
103719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (TII->ReverseBranchCondition(Cond))
103819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert(false && "Unable to reverse branch condition!");
103919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
104019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Initialize liveins to the first BB. These are potentiall redefined by
104119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // predicated instructions.
104219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallSet<unsigned, 4> Redefs;
104319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  InitPredRedefs(CvtBBI->BB, Redefs, TRI);
104419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  InitPredRedefs(NextBBI->BB, Redefs, TRI);
104519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
104619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (CvtBBI->BB->pred_size() > 1) {
104719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
104819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Copy instructions in the true block, predicate them, and add them to
104919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // the entry block.
105019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CopyAndPredicateBlock(BBI, *CvtBBI, Cond, Redefs);
105119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
105219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PredicateBlock(*CvtBBI, CvtBBI->BB->end(), Cond, Redefs);
105319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
105419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Merge converted block into entry block.
105519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
105619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MergeBlocks(BBI, *CvtBBI);
105719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
105819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
105919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool IterIfcvt = true;
106019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!canFallThroughTo(BBI.BB, NextBBI->BB)) {
106119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InsertUncondBranch(BBI.BB, NextBBI->BB, TII);
106219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.HasFallThrough = false;
106319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Now ifcvt'd block will look like this:
106419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // BB:
106519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // ...
106619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // t, f = cmp
106719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // if t op
106819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // b BBf
106919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //
107019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // We cannot further ifcvt this block because the unconditional branch
107119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // will have to be predicated on the new condition, that will not be
107219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // available if cmp executes.
107319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IterIfcvt = false;
107419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
107519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
107619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RemoveExtraEdges(BBI);
107719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
107819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Update block info. BB can be iteratively if-converted.
107919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!IterIfcvt)
108019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.IsDone = true;
108119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  InvalidatePreds(BBI.BB);
108219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CvtBBI->IsDone = true;
108319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
108419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // FIXME: Must maintain LiveIns.
108519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
108619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
108719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
108819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// IfConvertTriangle - If convert a triangle sub-CFG.
108919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///
109019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
109119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
109219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
109319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBInfo *CvtBBI = &TrueBBI;
109419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBInfo *NextBBI = &FalseBBI;
109519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DebugLoc dl;  // FIXME: this is nowhere
109619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
109719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<MachineOperand, 4> Cond(BBI.BrCond.begin(), BBI.BrCond.end());
109819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
109919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::swap(CvtBBI, NextBBI);
110019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
110119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (CvtBBI->IsDone ||
110219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      (CvtBBI->CannotBeCopied && CvtBBI->BB->pred_size() > 1)) {
110319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Something has changed. It's no longer safe to predicate this block.
110419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.IsAnalyzed = false;
110519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CvtBBI->IsAnalyzed = false;
110619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
110719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
110819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
110919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
111019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (TII->ReverseBranchCondition(Cond))
111119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert(false && "Unable to reverse branch condition!");
111219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
111319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Kind == ICTriangleRev || Kind == ICTriangleFRev) {
111419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (ReverseBranchCondition(*CvtBBI)) {
111519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // BB has been changed, modify its predecessors (except for this
111619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // one) so they don't get ifcvt'ed based on bad intel.
111719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (MachineBasicBlock::pred_iterator PI = CvtBBI->BB->pred_begin(),
111819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman             E = CvtBBI->BB->pred_end(); PI != E; ++PI) {
111919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        MachineBasicBlock *PBB = *PI;
112019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (PBB == BBI.BB)
112119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          continue;
112219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        BBInfo &PBBI = BBAnalysis[PBB->getNumber()];
112319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (PBBI.IsEnqueued) {
112419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          PBBI.IsAnalyzed = false;
112519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          PBBI.IsEnqueued = false;
112619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
112719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
112819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
112919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
113019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
113119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Initialize liveins to the first BB. These are potentially redefined by
113219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // predicated instructions.
113319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallSet<unsigned, 4> Redefs;
113419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  InitPredRedefs(CvtBBI->BB, Redefs, TRI);
113519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  InitPredRedefs(NextBBI->BB, Redefs, TRI);
113619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
113719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool HasEarlyExit = CvtBBI->FalseBB != NULL;
113819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (CvtBBI->BB->pred_size() > 1) {
113919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
114019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Copy instructions in the true block, predicate them, and add them to
114119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // the entry block.
114219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CopyAndPredicateBlock(BBI, *CvtBBI, Cond, Redefs, true);
114319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
114419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Predicate the 'true' block after removing its branch.
114519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CvtBBI->NonPredSize -= TII->RemoveBranch(*CvtBBI->BB);
114619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PredicateBlock(*CvtBBI, CvtBBI->BB->end(), Cond, Redefs);
114719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
114819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Now merge the entry of the triangle with the true block.
114919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
115019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MergeBlocks(BBI, *CvtBBI, false);
115119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
115219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
115319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If 'true' block has a 'false' successor, add an exit branch to it.
115419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (HasEarlyExit) {
115519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SmallVector<MachineOperand, 4> RevCond(CvtBBI->BrCond.begin(),
115619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                           CvtBBI->BrCond.end());
115719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (TII->ReverseBranchCondition(RevCond))
115819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert(false && "Unable to reverse branch condition!");
115919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    TII->InsertBranch(*BBI.BB, CvtBBI->FalseBB, NULL, RevCond, dl);
116019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.BB->addSuccessor(CvtBBI->FalseBB);
116119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
116219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
116319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Merge in the 'false' block if the 'false' block has no other
116419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // predecessors. Otherwise, add an unconditional branch to 'false'.
116519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool FalseBBDead = false;
116619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool IterIfcvt = true;
116719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool isFallThrough = canFallThroughTo(BBI.BB, NextBBI->BB);
116819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!isFallThrough) {
116919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Only merge them if the true block does not fallthrough to the false
117019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // block. By not merging them, we make it possible to iteratively
117119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // ifcvt the blocks.
117219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!HasEarlyExit &&
117319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        NextBBI->BB->pred_size() == 1 && !NextBBI->HasFallThrough) {
117419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MergeBlocks(BBI, *NextBBI);
117519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      FalseBBDead = true;
117619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else {
117719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      InsertUncondBranch(BBI.BB, NextBBI->BB, TII);
117819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      BBI.HasFallThrough = false;
117919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
118019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Mixed predicated and unpredicated code. This cannot be iteratively
118119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // predicated.
118219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IterIfcvt = false;
118319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
118419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
118519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RemoveExtraEdges(BBI);
118619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
118719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Update block info. BB can be iteratively if-converted.
118819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!IterIfcvt)
118919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.IsDone = true;
119019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  InvalidatePreds(BBI.BB);
119119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CvtBBI->IsDone = true;
119219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (FalseBBDead)
119319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    NextBBI->IsDone = true;
119419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
119519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // FIXME: Must maintain LiveIns.
119619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
119719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
119819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
119919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// IfConvertDiamond - If convert a diamond sub-CFG.
120019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///
120119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
120219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   unsigned NumDups1, unsigned NumDups2) {
120319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBInfo &TrueBBI  = BBAnalysis[BBI.TrueBB->getNumber()];
120419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
120519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineBasicBlock *TailBB = TrueBBI.TrueBB;
120619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // True block must fall through or end with an unanalyzable terminator.
120719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!TailBB) {
120819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (blockAlwaysFallThrough(TrueBBI))
120919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      TailBB = FalseBBI.TrueBB;
121019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert((TailBB || !TrueBBI.IsBrAnalyzable) && "Unexpected!");
121119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
121219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
121319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TrueBBI.IsDone || FalseBBI.IsDone ||
121419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      TrueBBI.BB->pred_size() > 1 ||
121519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      FalseBBI.BB->pred_size() > 1) {
121619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Something has changed. It's no longer safe to predicate these blocks.
121719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBI.IsAnalyzed = false;
121819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    TrueBBI.IsAnalyzed = false;
121919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FalseBBI.IsAnalyzed = false;
122019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
122119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
122219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
122319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Put the predicated instructions from the 'true' block before the
122419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // instructions from the 'false' block, unless the true block would clobber
122519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // the predicate, in which case, do the opposite.
122619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBInfo *BBI1 = &TrueBBI;
122719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBInfo *BBI2 = &FalseBBI;
122819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<MachineOperand, 4> RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
122919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TII->ReverseBranchCondition(RevCond))
123019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert(false && "Unable to reverse branch condition!");
123119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<MachineOperand, 4> *Cond1 = &BBI.BrCond;
123219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<MachineOperand, 4> *Cond2 = &RevCond;
123319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
123419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Figure out the more profitable ordering.
123519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool DoSwap = false;
123619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TrueBBI.ClobbersPred && !FalseBBI.ClobbersPred)
123719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    DoSwap = true;
123819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else if (TrueBBI.ClobbersPred == FalseBBI.ClobbersPred) {
123919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (TrueBBI.NonPredSize > FalseBBI.NonPredSize)
124019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      DoSwap = true;
124119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
124219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (DoSwap) {
124319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::swap(BBI1, BBI2);
124419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::swap(Cond1, Cond2);
124519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
124619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
124719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Remove the conditional branch from entry to the blocks.
124819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
124919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
125019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Initialize liveins to the first BB. These are potentially redefined by
125119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // predicated instructions.
125219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallSet<unsigned, 4> Redefs;
125319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  InitPredRedefs(BBI1->BB, Redefs, TRI);
125419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
125519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Remove the duplicated instructions at the beginnings of both paths.
125619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineBasicBlock::iterator DI1 = BBI1->BB->begin();
125719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineBasicBlock::iterator DI2 = BBI2->BB->begin();
125819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineBasicBlock::iterator DIE1 = BBI1->BB->end();
125919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineBasicBlock::iterator DIE2 = BBI2->BB->end();
126019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Skip dbg_value instructions
126119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (DI1 != DIE1 && DI1->isDebugValue())
126219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ++DI1;
126319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (DI2 != DIE2 && DI2->isDebugValue())
126419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ++DI2;
126519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI1->NonPredSize -= NumDups1;
126619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI2->NonPredSize -= NumDups1;
126719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
126819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Skip past the dups on each side separately since there may be
126919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // differing dbg_value entries.
127019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0; i < NumDups1; ++DI1) {
127119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!DI1->isDebugValue())
127219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ++i;
127319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
127419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (NumDups1 != 0) {
127519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ++DI2;
127619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!DI2->isDebugValue())
127719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      --NumDups1;
127819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
127919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
128019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  UpdatePredRedefs(BBI1->BB->begin(), DI1, Redefs, TRI);
128119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.BB->splice(BBI.BB->end(), BBI1->BB, BBI1->BB->begin(), DI1);
128219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI2->BB->erase(BBI2->BB->begin(), DI2);
128319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
128419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Predicate the 'true' block after removing its branch.
128519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI1->NonPredSize -= TII->RemoveBranch(*BBI1->BB);
128619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DI1 = BBI1->BB->end();
128719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0; i != NumDups2; ) {
128819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // NumDups2 only counted non-dbg_value instructions, so this won't
128919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // run off the head of the list.
129019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert (DI1 != BBI1->BB->begin());
129119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    --DI1;
129219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // skip dbg_value instructions
129319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!DI1->isDebugValue())
129419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ++i;
129519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
129619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI1->BB->erase(DI1, BBI1->BB->end());
129719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  PredicateBlock(*BBI1, BBI1->BB->end(), *Cond1, Redefs);
129819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
129919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Predicate the 'false' block.
130019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI2->NonPredSize -= TII->RemoveBranch(*BBI2->BB);
130119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DI2 = BBI2->BB->end();
130219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (NumDups2 != 0) {
130319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // NumDups2 only counted non-dbg_value instructions, so this won't
130419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // run off the head of the list.
130519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert (DI2 != BBI2->BB->begin());
130619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    --DI2;
130719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // skip dbg_value instructions
130819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!DI2->isDebugValue())
130919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      --NumDups2;
131019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
131119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  PredicateBlock(*BBI2, DI2, *Cond2, Redefs);
131219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
131319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Merge the true block into the entry of the diamond.
131419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MergeBlocks(BBI, *BBI1, TailBB == 0);
131519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MergeBlocks(BBI, *BBI2, TailBB == 0);
131619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
131719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If the if-converted block falls through or unconditionally branches into
131819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // the tail block, and the tail block does not have other predecessors, then
131919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // fold the tail block in as well. Otherwise, unless it falls through to the
132019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // tail, add a unconditional branch to it.
132119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TailBB) {
132219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBInfo TailBBI = BBAnalysis[TailBB->getNumber()];
132319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool CanMergeTail = !TailBBI.HasFallThrough;
132419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // There may still be a fall-through edge from BBI1 or BBI2 to TailBB;
132519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // check if there are any other predecessors besides those.
132619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned NumPreds = TailBB->pred_size();
132719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (NumPreds > 1)
132819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      CanMergeTail = false;
132919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else if (NumPreds == 1 && CanMergeTail) {
133019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MachineBasicBlock::pred_iterator PI = TailBB->pred_begin();
133119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (*PI != BBI1->BB && *PI != BBI2->BB)
133219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        CanMergeTail = false;
133319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
133419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (CanMergeTail) {
133519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MergeBlocks(BBI, TailBBI);
133619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      TailBBI.IsDone = true;
133719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else {
133819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      BBI.BB->addSuccessor(TailBB);
133919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      InsertUncondBranch(BBI.BB, TailBB, TII);
134019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      BBI.HasFallThrough = false;
134119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
134219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
134319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
134419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // RemoveExtraEdges won't work if the block has an unanalyzable branch,
134519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // which can happen here if TailBB is unanalyzable and is merged, so
134619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // explicitly remove BBI1 and BBI2 as successors.
134719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.BB->removeSuccessor(BBI1->BB);
134819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.BB->removeSuccessor(BBI2->BB);
134919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RemoveExtraEdges(BBI);
135019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
135119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Update block info.
135219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone = true;
135319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  InvalidatePreds(BBI.BB);
135419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
135519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // FIXME: Must maintain LiveIns.
135619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
135719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
135819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
135919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// PredicateBlock - Predicate instructions from the start of the block to the
136019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// specified end with the specified condition.
136119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid IfConverter::PredicateBlock(BBInfo &BBI,
136219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                 MachineBasicBlock::iterator E,
136319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                 SmallVectorImpl<MachineOperand> &Cond,
136419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                 SmallSet<unsigned, 4> &Redefs) {
136519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MachineBasicBlock::iterator I = BBI.BB->begin(); I != E; ++I) {
136619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (I->isDebugValue() || TII->isPredicated(I))
136719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
136819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!TII->PredicateInstruction(I, Cond)) {
136919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifndef NDEBUG
137019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      dbgs() << "Unable to predicate " << *I << "!\n";
137119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif
137219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      llvm_unreachable(0);
137319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
137419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
137519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // If the predicated instruction now redefines a register as the result of
137619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // if-conversion, add an implicit kill.
137719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    UpdatePredRedefs(I, Redefs, TRI, true);
137819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
137919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
138019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::copy(Cond.begin(), Cond.end(), std::back_inserter(BBI.Predicate));
138119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
138219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.IsAnalyzed = false;
138319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBI.NonPredSize = 0;
138419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
138519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ++NumIfConvBBs;
138619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
138719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
138819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// CopyAndPredicateBlock - Copy and predicate instructions from source BB to
138919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// the destination block. Skip end of block branches if IgnoreBr is true.
139019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
139119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                        SmallVectorImpl<MachineOperand> &Cond,
139219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                        SmallSet<unsigned, 4> &Redefs,
139319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                        bool IgnoreBr) {
139419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineFunction &MF = *ToBBI.BB->getParent();
139519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
139619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MachineBasicBlock::iterator I = FromBBI.BB->begin(),
139719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         E = FromBBI.BB->end(); I != E; ++I) {
139819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCInstrDesc &MCID = I->getDesc();
139919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Do not copy the end of the block branches.
140019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IgnoreBr && MCID.isBranch())
140119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
140219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
140319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MachineInstr *MI = MF.CloneMachineInstr(I);
140419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ToBBI.BB->insert(ToBBI.BB->end(), MI);
140519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ToBBI.NonPredSize++;
140619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned ExtraPredCost = 0;
140719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned NumCycles = TII->getInstrLatency(InstrItins, &*I, &ExtraPredCost);
140819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (NumCycles > 1)
140919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ToBBI.ExtraCost += NumCycles-1;
141019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ToBBI.ExtraCost2 += ExtraPredCost;
141119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
141219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!TII->isPredicated(I) && !MI->isDebugValue()) {
141319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!TII->PredicateInstruction(MI, Cond)) {
141419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifndef NDEBUG
141519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        dbgs() << "Unable to predicate " << *I << "!\n";
141619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif
141719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        llvm_unreachable(0);
141819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
141919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
142019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
142119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // If the predicated instruction now redefines a register as the result of
142219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // if-conversion, add an implicit kill.
142319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    UpdatePredRedefs(MI, Redefs, TRI, true);
142419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
142519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
142619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!IgnoreBr) {
142719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::vector<MachineBasicBlock *> Succs(FromBBI.BB->succ_begin(),
142819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                           FromBBI.BB->succ_end());
142919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MachineBasicBlock *NBB = getNextBlock(FromBBI.BB);
143019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MachineBasicBlock *FallThrough = FromBBI.HasFallThrough ? NBB : NULL;
143119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
143219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (unsigned i = 0, e = Succs.size(); i != e; ++i) {
143319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MachineBasicBlock *Succ = Succs[i];
143419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Fallthrough edge can't be transferred.
143519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Succ == FallThrough)
143619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        continue;
143719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ToBBI.BB->addSuccessor(Succ);
143819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
143919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
144019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
144119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::copy(FromBBI.Predicate.begin(), FromBBI.Predicate.end(),
144219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            std::back_inserter(ToBBI.Predicate));
144319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::copy(Cond.begin(), Cond.end(), std::back_inserter(ToBBI.Predicate));
144419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
144519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
144619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ToBBI.IsAnalyzed = false;
144719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
144819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ++NumDupBBs;
144919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
145019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
145119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// MergeBlocks - Move all instructions from FromBB to the end of ToBB.
145219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// This will leave FromBB as an empty block, so remove all of its
145319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// successor edges except for the fall-through edge.  If AddEdges is true,
145419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// i.e., when FromBBI's branch is being moved, add those successor edges to
145519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ToBBI.
145619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid IfConverter::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI, bool AddEdges) {
145719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ToBBI.BB->splice(ToBBI.BB->end(),
145819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   FromBBI.BB, FromBBI.BB->begin(), FromBBI.BB->end());
145919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
146019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::vector<MachineBasicBlock *> Succs(FromBBI.BB->succ_begin(),
146119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                         FromBBI.BB->succ_end());
146219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineBasicBlock *NBB = getNextBlock(FromBBI.BB);
146319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachineBasicBlock *FallThrough = FromBBI.HasFallThrough ? NBB : NULL;
146419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
146519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0, e = Succs.size(); i != e; ++i) {
146619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MachineBasicBlock *Succ = Succs[i];
146719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Fallthrough edge can't be transferred.
146819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Succ == FallThrough)
146919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
147019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FromBBI.BB->removeSuccessor(Succ);
147119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (AddEdges)
147219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ToBBI.BB->addSuccessor(Succ);
147319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
147419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
147519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Now FromBBI always falls through to the next block!
147619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (NBB && !FromBBI.BB->isSuccessor(NBB))
147719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FromBBI.BB->addSuccessor(NBB);
147819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
147919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::copy(FromBBI.Predicate.begin(), FromBBI.Predicate.end(),
148019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            std::back_inserter(ToBBI.Predicate));
148119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FromBBI.Predicate.clear();
148219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
148319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ToBBI.NonPredSize += FromBBI.NonPredSize;
148419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ToBBI.ExtraCost += FromBBI.ExtraCost;
148519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ToBBI.ExtraCost2 += FromBBI.ExtraCost2;
148619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FromBBI.NonPredSize = 0;
148719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FromBBI.ExtraCost = 0;
148819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FromBBI.ExtraCost2 = 0;
148919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
149019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
149119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ToBBI.HasFallThrough = FromBBI.HasFallThrough;
149219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ToBBI.IsAnalyzed = false;
149319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FromBBI.IsAnalyzed = false;
149419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
1495