2007-05-16 02:00:57 +00:00
|
|
|
//===-- IfConversion.cpp - Machine code if conversion pass. ---------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-29 20:36:04 +00:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2007-05-16 02:00:57 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file implements the machine instruction level if-conversion pass.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2007-06-01 00:12:12 +00:00
|
|
|
#define DEBUG_TYPE "ifcvt"
|
2007-05-16 02:00:57 +00:00
|
|
|
#include "llvm/CodeGen/Passes.h"
|
2012-12-03 16:50:05 +00:00
|
|
|
#include "BranchFolding.h"
|
|
|
|
#include "llvm/ADT/STLExtras.h"
|
|
|
|
#include "llvm/ADT/SmallSet.h"
|
|
|
|
#include "llvm/ADT/Statistic.h"
|
2011-08-03 22:53:41 +00:00
|
|
|
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
|
2007-05-16 02:00:57 +00:00
|
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
2012-12-20 18:08:06 +00:00
|
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
2012-12-03 16:50:05 +00:00
|
|
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
2012-06-08 21:53:50 +00:00
|
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
2013-09-30 15:28:56 +00:00
|
|
|
#include "llvm/CodeGen/TargetSchedule.h"
|
2013-10-11 19:04:37 +00:00
|
|
|
#include "llvm/CodeGen/LiveRegUnits.h"
|
2011-06-29 01:14:12 +00:00
|
|
|
#include "llvm/MC/MCInstrItineraries.h"
|
2007-06-08 19:10:51 +00:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
2007-05-16 02:00:57 +00:00
|
|
|
#include "llvm/Support/Debug.h"
|
2009-07-11 13:10:19 +00:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2012-12-03 16:50:05 +00:00
|
|
|
#include "llvm/Target/TargetInstrInfo.h"
|
|
|
|
#include "llvm/Target/TargetLowering.h"
|
|
|
|
#include "llvm/Target/TargetMachine.h"
|
|
|
|
#include "llvm/Target/TargetRegisterInfo.h"
|
2013-09-30 15:28:56 +00:00
|
|
|
#include "llvm/Target/TargetSubtargetInfo.h"
|
|
|
|
|
2007-05-16 02:00:57 +00:00
|
|
|
using namespace llvm;
|
|
|
|
|
2008-01-07 05:40:58 +00:00
|
|
|
// Hidden options for help debugging.
|
|
|
|
static cl::opt<int> IfCvtFnStart("ifcvt-fn-start", cl::init(-1), cl::Hidden);
|
|
|
|
static cl::opt<int> IfCvtFnStop("ifcvt-fn-stop", cl::init(-1), cl::Hidden);
|
|
|
|
static cl::opt<int> IfCvtLimit("ifcvt-limit", cl::init(-1), cl::Hidden);
|
2010-06-15 22:18:54 +00:00
|
|
|
static cl::opt<bool> DisableSimple("disable-ifcvt-simple",
|
2008-01-07 05:40:58 +00:00
|
|
|
cl::init(false), cl::Hidden);
|
2010-06-15 22:18:54 +00:00
|
|
|
static cl::opt<bool> DisableSimpleF("disable-ifcvt-simple-false",
|
2008-01-07 05:40:58 +00:00
|
|
|
cl::init(false), cl::Hidden);
|
2010-06-15 22:18:54 +00:00
|
|
|
static cl::opt<bool> DisableTriangle("disable-ifcvt-triangle",
|
2008-01-07 05:40:58 +00:00
|
|
|
cl::init(false), cl::Hidden);
|
2010-06-15 22:18:54 +00:00
|
|
|
static cl::opt<bool> DisableTriangleR("disable-ifcvt-triangle-rev",
|
2008-01-07 05:40:58 +00:00
|
|
|
cl::init(false), cl::Hidden);
|
2010-06-15 22:18:54 +00:00
|
|
|
static cl::opt<bool> DisableTriangleF("disable-ifcvt-triangle-false",
|
2008-01-07 05:40:58 +00:00
|
|
|
cl::init(false), cl::Hidden);
|
2010-06-15 22:18:54 +00:00
|
|
|
static cl::opt<bool> DisableTriangleFR("disable-ifcvt-triangle-false-rev",
|
2008-01-07 05:40:58 +00:00
|
|
|
cl::init(false), cl::Hidden);
|
2010-06-15 22:18:54 +00:00
|
|
|
static cl::opt<bool> DisableDiamond("disable-ifcvt-diamond",
|
2008-01-07 05:40:58 +00:00
|
|
|
cl::init(false), cl::Hidden);
|
2010-06-16 07:35:02 +00:00
|
|
|
static cl::opt<bool> IfCvtBranchFold("ifcvt-branch-fold",
|
|
|
|
cl::init(true), cl::Hidden);
|
2007-06-08 19:10:51 +00:00
|
|
|
|
2007-06-09 01:03:43 +00:00
|
|
|
STATISTIC(NumSimple, "Number of simple if-conversions performed");
|
|
|
|
STATISTIC(NumSimpleFalse, "Number of simple (F) if-conversions performed");
|
|
|
|
STATISTIC(NumTriangle, "Number of triangle if-conversions performed");
|
2007-06-12 23:54:05 +00:00
|
|
|
STATISTIC(NumTriangleRev, "Number of triangle (R) if-conversions performed");
|
2007-06-09 01:03:43 +00:00
|
|
|
STATISTIC(NumTriangleFalse,"Number of triangle (F) if-conversions performed");
|
|
|
|
STATISTIC(NumTriangleFRev, "Number of triangle (F/R) if-conversions performed");
|
|
|
|
STATISTIC(NumDiamonds, "Number of diamond if-conversions performed");
|
|
|
|
STATISTIC(NumIfConvBBs, "Number of if-converted blocks");
|
2007-06-15 07:36:12 +00:00
|
|
|
STATISTIC(NumDupBBs, "Number of duplicated blocks");
|
Add a if-conversion optimization that allows 'true' side of a diamond to be
unpredicated. That is, turn
subeq r0, r1, #1
addne r0, r1, #1
into
sub r0, r1, #1
addne r0, r1, #1
For targets where conditional instructions are always executed, this may be
beneficial. It may remove pseudo anti-dependency in out-of-order execution
CPUs. e.g.
op r1, ...
str r1, [r10] ; end-of-life of r1 as div result
cmp r0, #65
movne r1, #44 ; raw dependency on previous r1
moveq r1, #12
If movne is unpredicated, then
op r1, ...
str r1, [r10]
cmp r0, #65
mov r1, #44 ; r1 written unconditionally
moveq r1, #12
Both mov and moveq are no longer depdendent on the first instruction. This gives
the out-of-order execution engine more freedom to reorder them.
This has passed entire LLVM test suite. But it has not been enabled for any ARM
variant pending more performance evaluation.
rdar://8951196
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146914 91177308-0d34-0410-b5e6-96231b3b80d8
2011-12-19 22:01:30 +00:00
|
|
|
STATISTIC(NumUnpred, "Number of true blocks of diamonds unpredicated");
|
2007-05-16 02:00:57 +00:00
|
|
|
|
|
|
|
namespace {
|
2009-10-25 06:33:48 +00:00
|
|
|
class IfConverter : public MachineFunctionPass {
|
2007-06-16 09:34:52 +00:00
|
|
|
enum IfcvtKind {
|
2007-05-16 02:00:57 +00:00
|
|
|
ICNotClassfied, // BB data valid, but not classified.
|
2007-06-04 06:47:22 +00:00
|
|
|
ICSimpleFalse, // Same as ICSimple, but on the false path.
|
2007-06-16 09:34:52 +00:00
|
|
|
ICSimple, // BB is entry of an one split, no rejoin sub-CFG.
|
|
|
|
ICTriangleFRev, // Same as ICTriangleFalse, but false path rev condition.
|
2007-06-12 23:54:05 +00:00
|
|
|
ICTriangleRev, // Same as ICTriangle, but true path rev condition.
|
2007-06-09 01:03:43 +00:00
|
|
|
ICTriangleFalse, // Same as ICTriangle, but on the false path.
|
2007-06-16 09:34:52 +00:00
|
|
|
ICTriangle, // BB is entry of a triangle sub-CFG.
|
2007-06-11 22:26:22 +00:00
|
|
|
ICDiamond // BB is entry of a diamond sub-CFG.
|
2007-05-16 02:00:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// BBInfo - One per MachineBasicBlock, this is used to cache the result
|
|
|
|
/// if-conversion feasibility analysis. This includes results from
|
|
|
|
/// TargetInstrInfo::AnalyzeBranch() (i.e. TBB, FBB, and Cond), and its
|
2007-05-18 00:20:58 +00:00
|
|
|
/// classification, and common tail block of its successors (if it's a
|
2007-05-18 18:14:37 +00:00
|
|
|
/// diamond shape), its size, whether it's predicable, and whether any
|
|
|
|
/// instruction can clobber the 'would-be' predicate.
|
2007-05-23 07:23:16 +00:00
|
|
|
///
|
2007-06-11 22:26:22 +00:00
|
|
|
/// IsDone - True if BB is not to be considered for ifcvt.
|
|
|
|
/// IsBeingAnalyzed - True if BB is currently being analyzed.
|
|
|
|
/// IsAnalyzed - True if BB has been analyzed (info is still valid).
|
|
|
|
/// IsEnqueued - True if BB has been enqueued to be ifcvt'ed.
|
|
|
|
/// IsBrAnalyzable - True if AnalyzeBranch() returns false.
|
|
|
|
/// HasFallThrough - True if BB may fallthrough to the following BB.
|
|
|
|
/// IsUnpredicable - True if BB is known to be unpredicable.
|
2007-07-10 17:50:43 +00:00
|
|
|
/// ClobbersPred - True if BB could modify predicates (e.g. has
|
2007-06-06 10:16:17 +00:00
|
|
|
/// cmp, call, etc.)
|
2007-06-11 22:26:22 +00:00
|
|
|
/// NonPredSize - Number of non-predicated instructions.
|
2010-11-03 00:45:17 +00:00
|
|
|
/// ExtraCost - Extra cost for multi-cycle instructions.
|
|
|
|
/// ExtraCost2 - Some instructions are slower when predicated
|
2007-05-23 07:23:16 +00:00
|
|
|
/// BB - Corresponding MachineBasicBlock.
|
|
|
|
/// TrueBB / FalseBB- See AnalyzeBranch().
|
|
|
|
/// BrCond - Conditions for end of block conditional branches.
|
|
|
|
/// Predicate - Predicate used in the BB.
|
2007-05-16 02:00:57 +00:00
|
|
|
struct BBInfo {
|
2007-06-11 22:26:22 +00:00
|
|
|
bool IsDone : 1;
|
|
|
|
bool IsBeingAnalyzed : 1;
|
|
|
|
bool IsAnalyzed : 1;
|
|
|
|
bool IsEnqueued : 1;
|
|
|
|
bool IsBrAnalyzable : 1;
|
|
|
|
bool HasFallThrough : 1;
|
|
|
|
bool IsUnpredicable : 1;
|
2007-06-15 21:18:05 +00:00
|
|
|
bool CannotBeCopied : 1;
|
2007-06-11 22:26:22 +00:00
|
|
|
bool ClobbersPred : 1;
|
2007-05-23 07:23:16 +00:00
|
|
|
unsigned NonPredSize;
|
2010-10-26 00:02:21 +00:00
|
|
|
unsigned ExtraCost;
|
2010-11-03 00:45:17 +00:00
|
|
|
unsigned ExtraCost2;
|
2007-05-18 00:20:58 +00:00
|
|
|
MachineBasicBlock *BB;
|
|
|
|
MachineBasicBlock *TrueBB;
|
|
|
|
MachineBasicBlock *FalseBB;
|
2008-08-14 22:49:33 +00:00
|
|
|
SmallVector<MachineOperand, 4> BrCond;
|
|
|
|
SmallVector<MachineOperand, 4> Predicate;
|
2007-06-16 09:34:52 +00:00
|
|
|
BBInfo() : IsDone(false), IsBeingAnalyzed(false),
|
2007-06-11 22:26:22 +00:00
|
|
|
IsAnalyzed(false), IsEnqueued(false), IsBrAnalyzable(false),
|
|
|
|
HasFallThrough(false), IsUnpredicable(false),
|
2007-06-15 21:18:05 +00:00
|
|
|
CannotBeCopied(false), ClobbersPred(false), NonPredSize(0),
|
2010-11-03 00:45:17 +00:00
|
|
|
ExtraCost(0), ExtraCost2(0), BB(0), TrueBB(0), FalseBB(0) {}
|
2007-06-16 09:34:52 +00:00
|
|
|
};
|
|
|
|
|
2010-06-15 18:19:27 +00:00
|
|
|
/// IfcvtToken - Record information about pending if-conversions to attempt:
|
2007-06-16 09:34:52 +00:00
|
|
|
/// BBI - Corresponding BBInfo.
|
|
|
|
/// Kind - Type of block. See IfcvtKind.
|
2009-05-13 23:25:24 +00:00
|
|
|
/// NeedSubsumption - True if the to-be-predicated BB has already been
|
2007-06-16 09:34:52 +00:00
|
|
|
/// predicated.
|
2007-06-18 08:37:25 +00:00
|
|
|
/// NumDups - Number of instructions that would be duplicated due
|
|
|
|
/// to this if-conversion. (For diamonds, the number of
|
|
|
|
/// identical instructions at the beginnings of both
|
|
|
|
/// paths).
|
|
|
|
/// NumDups2 - For diamonds, the number of identical instructions
|
|
|
|
/// at the ends of both paths.
|
2007-06-16 09:34:52 +00:00
|
|
|
struct IfcvtToken {
|
|
|
|
BBInfo &BBI;
|
|
|
|
IfcvtKind Kind;
|
2009-05-13 23:25:24 +00:00
|
|
|
bool NeedSubsumption;
|
2007-06-18 08:37:25 +00:00
|
|
|
unsigned NumDups;
|
|
|
|
unsigned NumDups2;
|
|
|
|
IfcvtToken(BBInfo &b, IfcvtKind k, bool s, unsigned d, unsigned d2 = 0)
|
2009-05-13 23:25:24 +00:00
|
|
|
: BBI(b), Kind(k), NeedSubsumption(s), NumDups(d), NumDups2(d2) {}
|
2007-05-16 02:00:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// BBAnalysis - Results of if-conversion feasibility analysis indexed by
|
|
|
|
/// basic block number.
|
|
|
|
std::vector<BBInfo> BBAnalysis;
|
2013-09-30 15:28:56 +00:00
|
|
|
TargetSchedModel SchedModel;
|
2007-05-16 02:00:57 +00:00
|
|
|
|
2013-01-11 20:05:37 +00:00
|
|
|
const TargetLoweringBase *TLI;
|
2007-05-16 02:00:57 +00:00
|
|
|
const TargetInstrInfo *TII;
|
2010-06-16 07:35:02 +00:00
|
|
|
const TargetRegisterInfo *TRI;
|
2011-08-03 22:34:43 +00:00
|
|
|
const MachineBranchProbabilityInfo *MBPI;
|
2012-06-08 21:53:50 +00:00
|
|
|
MachineRegisterInfo *MRI;
|
2011-08-03 22:34:43 +00:00
|
|
|
|
2013-10-14 20:45:17 +00:00
|
|
|
LiveRegUnits Redefs;
|
|
|
|
LiveRegUnits DontKill;
|
|
|
|
|
2012-06-08 21:53:50 +00:00
|
|
|
bool PreRegAlloc;
|
2007-05-16 02:00:57 +00:00
|
|
|
bool MadeChange;
|
2009-06-24 23:41:44 +00:00
|
|
|
int FnNum;
|
2007-05-16 02:00:57 +00:00
|
|
|
public:
|
|
|
|
static char ID;
|
2010-10-19 17:21:58 +00:00
|
|
|
IfConverter() : MachineFunctionPass(ID), FnNum(-1) {
|
|
|
|
initializeIfConverterPass(*PassRegistry::getPassRegistry());
|
|
|
|
}
|
2011-08-03 22:34:43 +00:00
|
|
|
|
2010-09-28 20:42:15 +00:00
|
|
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
2011-08-03 22:34:43 +00:00
|
|
|
AU.addRequired<MachineBranchProbabilityInfo>();
|
2010-09-28 20:42:15 +00:00
|
|
|
MachineFunctionPass::getAnalysisUsage(AU);
|
|
|
|
}
|
2007-05-16 02:00:57 +00:00
|
|
|
|
|
|
|
virtual bool runOnMachineFunction(MachineFunction &MF);
|
|
|
|
|
|
|
|
private:
|
2007-06-04 06:47:22 +00:00
|
|
|
bool ReverseBranchCondition(BBInfo &BBI);
|
2010-10-01 22:45:50 +00:00
|
|
|
bool ValidSimple(BBInfo &TrueBBI, unsigned &Dups,
|
2011-07-10 02:58:07 +00:00
|
|
|
const BranchProbability &Prediction) const;
|
2007-06-08 09:36:04 +00:00
|
|
|
bool ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
|
2010-10-01 22:45:50 +00:00
|
|
|
bool FalseBranch, unsigned &Dups,
|
2011-07-10 02:58:07 +00:00
|
|
|
const BranchProbability &Prediction) const;
|
2007-06-18 08:37:25 +00:00
|
|
|
bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
|
|
|
|
unsigned &Dups1, unsigned &Dups2) const;
|
2007-06-08 09:36:04 +00:00
|
|
|
void ScanInstructions(BBInfo &BBI);
|
2007-06-16 09:34:52 +00:00
|
|
|
BBInfo &AnalyzeBlock(MachineBasicBlock *BB,
|
|
|
|
std::vector<IfcvtToken*> &Tokens);
|
2008-08-14 22:49:33 +00:00
|
|
|
bool FeasibilityAnalysis(BBInfo &BBI, SmallVectorImpl<MachineOperand> &Cond,
|
2007-06-08 09:36:04 +00:00
|
|
|
bool isTriangle = false, bool RevBranch = false);
|
2010-06-15 18:57:15 +00:00
|
|
|
void AnalyzeBlocks(MachineFunction &MF, std::vector<IfcvtToken*> &Tokens);
|
2007-06-18 08:37:25 +00:00
|
|
|
void InvalidatePreds(MachineBasicBlock *BB);
|
2007-06-08 22:01:07 +00:00
|
|
|
void RemoveExtraEdges(BBInfo &BBI);
|
2007-06-16 09:34:52 +00:00
|
|
|
bool IfConvertSimple(BBInfo &BBI, IfcvtKind Kind);
|
|
|
|
bool IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind);
|
2007-06-18 08:37:25 +00:00
|
|
|
bool IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
|
|
|
|
unsigned NumDups1, unsigned NumDups2);
|
2007-05-23 07:23:16 +00:00
|
|
|
void PredicateBlock(BBInfo &BBI,
|
2007-06-18 08:37:25 +00:00
|
|
|
MachineBasicBlock::iterator E,
|
2010-06-16 07:35:02 +00:00
|
|
|
SmallVectorImpl<MachineOperand> &Cond,
|
Add a if-conversion optimization that allows 'true' side of a diamond to be
unpredicated. That is, turn
subeq r0, r1, #1
addne r0, r1, #1
into
sub r0, r1, #1
addne r0, r1, #1
For targets where conditional instructions are always executed, this may be
beneficial. It may remove pseudo anti-dependency in out-of-order execution
CPUs. e.g.
op r1, ...
str r1, [r10] ; end-of-life of r1 as div result
cmp r0, #65
movne r1, #44 ; raw dependency on previous r1
moveq r1, #12
If movne is unpredicated, then
op r1, ...
str r1, [r10]
cmp r0, #65
mov r1, #44 ; r1 written unconditionally
moveq r1, #12
Both mov and moveq are no longer depdendent on the first instruction. This gives
the out-of-order execution engine more freedom to reorder them.
This has passed entire LLVM test suite. But it has not been enabled for any ARM
variant pending more performance evaluation.
rdar://8951196
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146914 91177308-0d34-0410-b5e6-96231b3b80d8
2011-12-19 22:01:30 +00:00
|
|
|
SmallSet<unsigned, 4> *LaterRedefs = 0);
|
2007-06-15 07:36:12 +00:00
|
|
|
void CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
|
2008-08-14 22:49:33 +00:00
|
|
|
SmallVectorImpl<MachineOperand> &Cond,
|
2007-06-15 07:36:12 +00:00
|
|
|
bool IgnoreBr = false);
|
Reapply my if-conversion cleanup from svn r106939 with fixes.
There are 2 changes relative to the previous version of the patch:
1) For the "simple" if-conversion case, there's no need to worry about
RemoveExtraEdges not handling an unanalyzable branch. Predicated terminators
are ignored in this context, so RemoveExtraEdges does the right thing.
This might break someday if we ever treat indirect branches (BRIND) as
predicable, but for now, I just removed this part of the patch, because
in the case where we do not add an unconditional branch, we rely on keeping
the fall-through edge to CvtBBI (which is empty after this transformation).
The change relative to the previous patch is:
@@ -1036,10 +1036,6 @@
IterIfcvt = false;
}
- // RemoveExtraEdges won't work if the block has an unanalyzable branch,
- // which is typically the case for IfConvertSimple, so explicitly remove
- // CvtBBI as a successor.
- BBI.BB->removeSuccessor(CvtBBI->BB);
RemoveExtraEdges(BBI);
// Update block info. BB can be iteratively if-converted.
2) My patch exposed a bug in the code for merging the tail of a "diamond",
which had previously never been exercised. The code was simply checking that
the tail had a single predecessor, but there was a case in
MultiSource/Benchmarks/VersaBench/dbms where that single predecessor was
neither edge of the diamond. I added the following change to check for
that:
@@ -1276,7 +1276,18 @@
// tail, add a unconditional branch to it.
if (TailBB) {
BBInfo TailBBI = BBAnalysis[TailBB->getNumber()];
- if (TailBB->pred_size() == 1 && !TailBBI.HasFallThrough) {
+ bool CanMergeTail = !TailBBI.HasFallThrough;
+ // There may still be a fall-through edge from BBI1 or BBI2 to TailBB;
+ // check if there are any other predecessors besides those.
+ unsigned NumPreds = TailBB->pred_size();
+ if (NumPreds > 1)
+ CanMergeTail = false;
+ else if (NumPreds == 1 && CanMergeTail) {
+ MachineBasicBlock::pred_iterator PI = TailBB->pred_begin();
+ if (*PI != BBI1->BB && *PI != BBI2->BB)
+ CanMergeTail = false;
+ }
+ if (CanMergeTail) {
MergeBlocks(BBI, TailBBI);
TailBBI.IsDone = true;
} else {
With these fixes, I was able to run all the SingleSource and MultiSource
tests successfully.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107110 91177308-0d34-0410-b5e6-96231b3b80d8
2010-06-29 00:55:23 +00:00
|
|
|
void MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI, bool AddEdges = true);
|
2007-06-01 00:12:12 +00:00
|
|
|
|
2010-11-03 00:45:17 +00:00
|
|
|
bool MeetIfcvtSizeLimit(MachineBasicBlock &BB,
|
|
|
|
unsigned Cycle, unsigned Extra,
|
2011-07-10 02:58:07 +00:00
|
|
|
const BranchProbability &Prediction) const {
|
2010-11-03 00:45:17 +00:00
|
|
|
return Cycle > 0 && TII->isProfitableToIfCvt(BB, Cycle, Extra,
|
2011-07-10 02:58:07 +00:00
|
|
|
Prediction);
|
2010-06-25 22:42:03 +00:00
|
|
|
}
|
|
|
|
|
2010-11-03 00:45:17 +00:00
|
|
|
bool MeetIfcvtSizeLimit(MachineBasicBlock &TBB,
|
|
|
|
unsigned TCycle, unsigned TExtra,
|
|
|
|
MachineBasicBlock &FBB,
|
|
|
|
unsigned FCycle, unsigned FExtra,
|
2011-07-10 02:58:07 +00:00
|
|
|
const BranchProbability &Prediction) const {
|
2010-11-03 00:45:17 +00:00
|
|
|
return TCycle > 0 && FCycle > 0 &&
|
|
|
|
TII->isProfitableToIfCvt(TBB, TCycle, TExtra, FBB, FCycle, FExtra,
|
2011-07-10 02:58:07 +00:00
|
|
|
Prediction);
|
2007-06-18 08:37:25 +00:00
|
|
|
}
|
|
|
|
|
2007-06-07 02:12:15 +00:00
|
|
|
// blockAlwaysFallThrough - Block ends without a terminator.
|
|
|
|
bool blockAlwaysFallThrough(BBInfo &BBI) const {
|
2007-06-11 22:26:22 +00:00
|
|
|
return BBI.IsBrAnalyzable && BBI.TrueBB == NULL;
|
2007-06-06 10:16:17 +00:00
|
|
|
}
|
|
|
|
|
2007-06-16 09:34:52 +00:00
|
|
|
// IfcvtTokenCmp - Used to sort if-conversion candidates.
|
|
|
|
static bool IfcvtTokenCmp(IfcvtToken *C1, IfcvtToken *C2) {
|
2007-06-18 08:37:25 +00:00
|
|
|
int Incr1 = (C1->Kind == ICDiamond)
|
|
|
|
? -(int)(C1->NumDups + C1->NumDups2) : (int)C1->NumDups;
|
|
|
|
int Incr2 = (C2->Kind == ICDiamond)
|
|
|
|
? -(int)(C2->NumDups + C2->NumDups2) : (int)C2->NumDups;
|
|
|
|
if (Incr1 > Incr2)
|
2007-06-16 09:34:52 +00:00
|
|
|
return true;
|
2007-06-18 08:37:25 +00:00
|
|
|
else if (Incr1 == Incr2) {
|
2009-05-13 23:25:24 +00:00
|
|
|
// Favors subsumption.
|
|
|
|
if (C1->NeedSubsumption == false && C2->NeedSubsumption == true)
|
2007-06-16 09:34:52 +00:00
|
|
|
return true;
|
2009-05-13 23:25:24 +00:00
|
|
|
else if (C1->NeedSubsumption == C2->NeedSubsumption) {
|
2007-06-16 09:34:52 +00:00
|
|
|
// Favors diamond over triangle, etc.
|
|
|
|
if ((unsigned)C1->Kind < (unsigned)C2->Kind)
|
|
|
|
return true;
|
|
|
|
else if (C1->Kind == C2->Kind)
|
|
|
|
return C1->BBI.BB->getNumber() < C2->BBI.BB->getNumber();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
2007-06-01 00:12:12 +00:00
|
|
|
}
|
2007-05-16 02:00:57 +00:00
|
|
|
};
|
2007-06-16 09:34:52 +00:00
|
|
|
|
2007-05-16 02:00:57 +00:00
|
|
|
char IfConverter::ID = 0;
|
|
|
|
}
|
|
|
|
|
2012-02-08 21:23:13 +00:00
|
|
|
char &llvm::IfConverterID = IfConverter::ID;
|
|
|
|
|
2010-10-12 19:48:12 +00:00
|
|
|
INITIALIZE_PASS_BEGIN(IfConverter, "if-converter", "If Converter", false, false)
|
2011-08-03 22:34:43 +00:00
|
|
|
INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
|
2010-10-12 19:48:12 +00:00
|
|
|
INITIALIZE_PASS_END(IfConverter, "if-converter", "If Converter", false, false)
|
2009-10-28 20:46:46 +00:00
|
|
|
|
2007-05-16 02:00:57 +00:00
|
|
|
bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
|
2007-05-18 00:20:58 +00:00
|
|
|
TLI = MF.getTarget().getTargetLowering();
|
2007-05-16 02:00:57 +00:00
|
|
|
TII = MF.getTarget().getInstrInfo();
|
2010-06-16 07:35:02 +00:00
|
|
|
TRI = MF.getTarget().getRegisterInfo();
|
2011-08-03 22:34:43 +00:00
|
|
|
MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
|
2012-06-08 21:53:50 +00:00
|
|
|
MRI = &MF.getRegInfo();
|
2013-09-30 15:28:56 +00:00
|
|
|
|
|
|
|
const TargetSubtargetInfo &ST =
|
|
|
|
MF.getTarget().getSubtarget<TargetSubtargetInfo>();
|
|
|
|
SchedModel.init(*ST.getSchedModel(), &ST, TII);
|
|
|
|
|
2007-05-16 02:00:57 +00:00
|
|
|
if (!TII) return false;
|
|
|
|
|
2012-06-08 21:53:50 +00:00
|
|
|
PreRegAlloc = MRI->isSSA();
|
|
|
|
|
|
|
|
bool BFChange = false;
|
|
|
|
if (!PreRegAlloc) {
|
|
|
|
// Tail merge tend to expose more if-conversion opportunities.
|
|
|
|
BranchFolder BF(true, false);
|
|
|
|
BFChange = BF.OptimizeFunction(MF, TII,
|
2010-06-18 23:09:54 +00:00
|
|
|
MF.getTarget().getRegisterInfo(),
|
|
|
|
getAnalysisIfAvailable<MachineModuleInfo>());
|
2012-06-08 21:53:50 +00:00
|
|
|
}
|
2010-06-18 23:09:54 +00:00
|
|
|
|
2010-01-04 22:02:01 +00:00
|
|
|
DEBUG(dbgs() << "\nIfcvt: function (" << ++FnNum << ") \'"
|
2012-08-22 06:07:19 +00:00
|
|
|
<< MF.getName() << "\'");
|
2007-06-08 19:10:51 +00:00
|
|
|
|
|
|
|
if (FnNum < IfCvtFnStart || (IfCvtFnStop != -1 && FnNum > IfCvtFnStop)) {
|
2010-01-04 22:02:01 +00:00
|
|
|
DEBUG(dbgs() << " skipped\n");
|
2007-06-08 19:10:51 +00:00
|
|
|
return false;
|
|
|
|
}
|
2010-01-04 22:02:01 +00:00
|
|
|
DEBUG(dbgs() << "\n");
|
2007-06-01 00:12:12 +00:00
|
|
|
|
2007-05-16 02:00:57 +00:00
|
|
|
MF.RenumberBlocks();
|
2007-06-01 00:12:12 +00:00
|
|
|
BBAnalysis.resize(MF.getNumBlockIDs());
|
2007-05-16 02:00:57 +00:00
|
|
|
|
2007-06-16 09:34:52 +00:00
|
|
|
std::vector<IfcvtToken*> Tokens;
|
2007-05-18 01:55:58 +00:00
|
|
|
MadeChange = false;
|
2007-06-15 07:36:12 +00:00
|
|
|
unsigned NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle +
|
|
|
|
NumTriangleRev + NumTriangleFalse + NumTriangleFRev + NumDiamonds;
|
|
|
|
while (IfCvtLimit == -1 || (int)NumIfCvts < IfCvtLimit) {
|
2009-05-13 23:25:24 +00:00
|
|
|
// Do an initial analysis for each basic block and find all the potential
|
|
|
|
// candidates to perform if-conversion.
|
2010-06-15 18:57:15 +00:00
|
|
|
bool Change = false;
|
|
|
|
AnalyzeBlocks(MF, Tokens);
|
2007-06-16 09:34:52 +00:00
|
|
|
while (!Tokens.empty()) {
|
|
|
|
IfcvtToken *Token = Tokens.back();
|
|
|
|
Tokens.pop_back();
|
|
|
|
BBInfo &BBI = Token->BBI;
|
|
|
|
IfcvtKind Kind = Token->Kind;
|
2008-11-04 13:02:59 +00:00
|
|
|
unsigned NumDups = Token->NumDups;
|
2008-11-04 18:05:30 +00:00
|
|
|
unsigned NumDups2 = Token->NumDups2;
|
2008-11-04 13:02:59 +00:00
|
|
|
|
|
|
|
delete Token;
|
2007-06-04 06:47:22 +00:00
|
|
|
|
2007-06-11 22:26:22 +00:00
|
|
|
// If the block has been evicted out of the queue or it has already been
|
|
|
|
// marked dead (due to it being predicated), then skip it.
|
2007-06-16 09:34:52 +00:00
|
|
|
if (BBI.IsDone)
|
|
|
|
BBI.IsEnqueued = false;
|
|
|
|
if (!BBI.IsEnqueued)
|
2007-06-11 22:26:22 +00:00
|
|
|
continue;
|
2007-06-16 09:34:52 +00:00
|
|
|
|
2007-06-14 20:28:52 +00:00
|
|
|
BBI.IsEnqueued = false;
|
2007-06-11 22:26:22 +00:00
|
|
|
|
2007-06-04 06:47:22 +00:00
|
|
|
bool RetVal = false;
|
2007-06-16 09:34:52 +00:00
|
|
|
switch (Kind) {
|
2012-02-05 08:31:47 +00:00
|
|
|
default: llvm_unreachable("Unexpected!");
|
2007-06-04 06:47:22 +00:00
|
|
|
case ICSimple:
|
2007-06-06 01:12:44 +00:00
|
|
|
case ICSimpleFalse: {
|
2007-06-16 09:34:52 +00:00
|
|
|
bool isFalse = Kind == ICSimpleFalse;
|
2007-06-09 01:03:43 +00:00
|
|
|
if ((isFalse && DisableSimpleF) || (!isFalse && DisableSimple)) break;
|
2010-06-15 22:18:54 +00:00
|
|
|
DEBUG(dbgs() << "Ifcvt (Simple" << (Kind == ICSimpleFalse ?
|
|
|
|
" false" : "")
|
2009-08-22 20:11:17 +00:00
|
|
|
<< "): BB#" << BBI.BB->getNumber() << " ("
|
|
|
|
<< ((Kind == ICSimpleFalse)
|
|
|
|
? BBI.FalseBB->getNumber()
|
|
|
|
: BBI.TrueBB->getNumber()) << ") ");
|
2007-06-16 09:34:52 +00:00
|
|
|
RetVal = IfConvertSimple(BBI, Kind);
|
2010-01-04 22:02:01 +00:00
|
|
|
DEBUG(dbgs() << (RetVal ? "succeeded!" : "failed!") << "\n");
|
2008-02-20 11:10:28 +00:00
|
|
|
if (RetVal) {
|
2010-06-22 15:08:57 +00:00
|
|
|
if (isFalse) ++NumSimpleFalse;
|
|
|
|
else ++NumSimple;
|
2008-02-20 11:10:28 +00:00
|
|
|
}
|
2007-06-04 06:47:22 +00:00
|
|
|
break;
|
2007-06-06 01:12:44 +00:00
|
|
|
}
|
2007-05-23 07:23:16 +00:00
|
|
|
case ICTriangle:
|
2007-06-12 23:54:05 +00:00
|
|
|
case ICTriangleRev:
|
2007-06-09 01:03:43 +00:00
|
|
|
case ICTriangleFalse:
|
2007-06-10 00:19:17 +00:00
|
|
|
case ICTriangleFRev: {
|
2007-06-16 09:34:52 +00:00
|
|
|
bool isFalse = Kind == ICTriangleFalse;
|
|
|
|
bool isRev = (Kind == ICTriangleRev || Kind == ICTriangleFRev);
|
2007-06-12 23:54:05 +00:00
|
|
|
if (DisableTriangle && !isFalse && !isRev) break;
|
|
|
|
if (DisableTriangleR && !isFalse && isRev) break;
|
|
|
|
if (DisableTriangleF && isFalse && !isRev) break;
|
|
|
|
if (DisableTriangleFR && isFalse && isRev) break;
|
2010-01-04 22:02:01 +00:00
|
|
|
DEBUG(dbgs() << "Ifcvt (Triangle");
|
2007-06-09 01:03:43 +00:00
|
|
|
if (isFalse)
|
2010-01-04 22:02:01 +00:00
|
|
|
DEBUG(dbgs() << " false");
|
2007-06-12 23:54:05 +00:00
|
|
|
if (isRev)
|
2010-01-04 22:02:01 +00:00
|
|
|
DEBUG(dbgs() << " rev");
|
|
|
|
DEBUG(dbgs() << "): BB#" << BBI.BB->getNumber() << " (T:"
|
2009-08-22 20:11:17 +00:00
|
|
|
<< BBI.TrueBB->getNumber() << ",F:"
|
|
|
|
<< BBI.FalseBB->getNumber() << ") ");
|
2007-06-16 09:34:52 +00:00
|
|
|
RetVal = IfConvertTriangle(BBI, Kind);
|
2010-01-04 22:02:01 +00:00
|
|
|
DEBUG(dbgs() << (RetVal ? "succeeded!" : "failed!") << "\n");
|
2007-06-09 01:03:43 +00:00
|
|
|
if (RetVal) {
|
2007-06-12 23:54:05 +00:00
|
|
|
if (isFalse) {
|
2010-06-22 15:08:57 +00:00
|
|
|
if (isRev) ++NumTriangleFRev;
|
|
|
|
else ++NumTriangleFalse;
|
2007-06-12 23:54:05 +00:00
|
|
|
} else {
|
2010-06-22 15:08:57 +00:00
|
|
|
if (isRev) ++NumTriangleRev;
|
|
|
|
else ++NumTriangle;
|
2007-06-12 23:54:05 +00:00
|
|
|
}
|
2007-06-09 01:03:43 +00:00
|
|
|
}
|
2007-05-23 07:23:16 +00:00
|
|
|
break;
|
2007-06-10 00:19:17 +00:00
|
|
|
}
|
2007-06-16 09:34:52 +00:00
|
|
|
case ICDiamond: {
|
2007-06-08 19:10:51 +00:00
|
|
|
if (DisableDiamond) break;
|
2010-01-04 22:02:01 +00:00
|
|
|
DEBUG(dbgs() << "Ifcvt (Diamond): BB#" << BBI.BB->getNumber() << " (T:"
|
2009-08-22 20:11:17 +00:00
|
|
|
<< BBI.TrueBB->getNumber() << ",F:"
|
|
|
|
<< BBI.FalseBB->getNumber() << ") ");
|
2008-11-04 13:02:59 +00:00
|
|
|
RetVal = IfConvertDiamond(BBI, Kind, NumDups, NumDups2);
|
2010-01-04 22:02:01 +00:00
|
|
|
DEBUG(dbgs() << (RetVal ? "succeeded!" : "failed!") << "\n");
|
2010-06-22 15:08:57 +00:00
|
|
|
if (RetVal) ++NumDiamonds;
|
2007-05-23 07:23:16 +00:00
|
|
|
break;
|
|
|
|
}
|
2007-06-16 09:34:52 +00:00
|
|
|
}
|
|
|
|
|
2007-06-04 06:47:22 +00:00
|
|
|
Change |= RetVal;
|
2007-06-08 19:10:51 +00:00
|
|
|
|
2007-06-15 07:36:12 +00:00
|
|
|
NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle + NumTriangleRev +
|
|
|
|
NumTriangleFalse + NumTriangleFRev + NumDiamonds;
|
|
|
|
if (IfCvtLimit != -1 && (int)NumIfCvts >= IfCvtLimit)
|
2007-06-08 19:10:51 +00:00
|
|
|
break;
|
2007-05-16 02:00:57 +00:00
|
|
|
}
|
2007-05-23 07:23:16 +00:00
|
|
|
|
|
|
|
if (!Change)
|
|
|
|
break;
|
2007-06-04 06:47:22 +00:00
|
|
|
MadeChange |= Change;
|
2007-05-16 02:00:57 +00:00
|
|
|
}
|
2007-05-18 01:55:58 +00:00
|
|
|
|
2007-06-16 09:34:52 +00:00
|
|
|
// Delete tokens in case of early exit.
|
|
|
|
while (!Tokens.empty()) {
|
|
|
|
IfcvtToken *Token = Tokens.back();
|
|
|
|
Tokens.pop_back();
|
|
|
|
delete Token;
|
|
|
|
}
|
|
|
|
|
|
|
|
Tokens.clear();
|
2007-05-18 01:55:58 +00:00
|
|
|
BBAnalysis.clear();
|
|
|
|
|
2010-06-18 22:17:13 +00:00
|
|
|
if (MadeChange && IfCvtBranchFold) {
|
2011-05-12 00:56:58 +00:00
|
|
|
BranchFolder BF(false, false);
|
2009-09-04 07:47:40 +00:00
|
|
|
BF.OptimizeFunction(MF, TII,
|
|
|
|
MF.getTarget().getRegisterInfo(),
|
|
|
|
getAnalysisIfAvailable<MachineModuleInfo>());
|
|
|
|
}
|
|
|
|
|
2010-06-18 23:09:54 +00:00
|
|
|
MadeChange |= BFChange;
|
2007-05-16 02:00:57 +00:00
|
|
|
return MadeChange;
|
|
|
|
}
|
|
|
|
|
2007-06-16 09:34:52 +00:00
|
|
|
/// findFalseBlock - BB has a fallthrough. Find its 'false' successor given
|
|
|
|
/// its 'true' successor.
|
2007-05-16 02:00:57 +00:00
|
|
|
static MachineBasicBlock *findFalseBlock(MachineBasicBlock *BB,
|
2007-05-18 00:20:58 +00:00
|
|
|
MachineBasicBlock *TrueBB) {
|
2007-05-16 02:00:57 +00:00
|
|
|
for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(),
|
|
|
|
E = BB->succ_end(); SI != E; ++SI) {
|
|
|
|
MachineBasicBlock *SuccBB = *SI;
|
2007-05-18 00:20:58 +00:00
|
|
|
if (SuccBB != TrueBB)
|
2007-05-16 02:00:57 +00:00
|
|
|
return SuccBB;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-06-16 09:34:52 +00:00
|
|
|
/// ReverseBranchCondition - Reverse the condition of the end of the block
|
2009-05-13 23:25:24 +00:00
|
|
|
/// branch. Swap block's 'true' and 'false' successors.
|
2007-06-04 06:47:22 +00:00
|
|
|
bool IfConverter::ReverseBranchCondition(BBInfo &BBI) {
|
2010-06-17 22:43:56 +00:00
|
|
|
DebugLoc dl; // FIXME: this is nowhere
|
2007-06-04 06:47:22 +00:00
|
|
|
if (!TII->ReverseBranchCondition(BBI.BrCond)) {
|
|
|
|
TII->RemoveBranch(*BBI.BB);
|
2010-06-17 22:43:56 +00:00
|
|
|
TII->InsertBranch(*BBI.BB, BBI.FalseBB, BBI.TrueBB, BBI.BrCond, dl);
|
2007-06-04 06:47:22 +00:00
|
|
|
std::swap(BBI.TrueBB, BBI.FalseBB);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2007-06-09 01:03:43 +00:00
|
|
|
/// getNextBlock - Returns the next block in the function blocks ordering. If
|
|
|
|
/// it is the end, returns NULL.
|
|
|
|
static inline MachineBasicBlock *getNextBlock(MachineBasicBlock *BB) {
|
|
|
|
MachineFunction::iterator I = BB;
|
|
|
|
MachineFunction::iterator E = BB->getParent()->end();
|
|
|
|
if (++I == E)
|
|
|
|
return NULL;
|
|
|
|
return I;
|
|
|
|
}
|
|
|
|
|
2007-06-08 09:36:04 +00:00
|
|
|
/// ValidSimple - Returns true if the 'true' block (along with its
|
2007-06-16 09:34:52 +00:00
|
|
|
/// predecessor) forms a valid simple shape for ifcvt. It also returns the
|
|
|
|
/// number of instructions that the ifcvt would need to duplicate if performed
|
|
|
|
/// in Dups.
|
2010-09-28 20:42:15 +00:00
|
|
|
bool IfConverter::ValidSimple(BBInfo &TrueBBI, unsigned &Dups,
|
2011-07-10 02:58:07 +00:00
|
|
|
const BranchProbability &Prediction) const {
|
2007-06-16 09:34:52 +00:00
|
|
|
Dups = 0;
|
2007-06-18 08:37:25 +00:00
|
|
|
if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
|
2007-06-11 22:26:22 +00:00
|
|
|
return false;
|
|
|
|
|
2007-06-19 21:45:13 +00:00
|
|
|
if (TrueBBI.IsBrAnalyzable)
|
|
|
|
return false;
|
|
|
|
|
2007-06-15 21:18:05 +00:00
|
|
|
if (TrueBBI.BB->pred_size() > 1) {
|
|
|
|
if (TrueBBI.CannotBeCopied ||
|
2010-09-28 20:42:15 +00:00
|
|
|
!TII->isProfitableToDupForIfCvt(*TrueBBI.BB, TrueBBI.NonPredSize,
|
2011-07-10 02:58:07 +00:00
|
|
|
Prediction))
|
2007-06-15 07:36:12 +00:00
|
|
|
return false;
|
2007-06-16 09:34:52 +00:00
|
|
|
Dups = TrueBBI.NonPredSize;
|
2007-06-15 07:36:12 +00:00
|
|
|
}
|
|
|
|
|
2007-06-19 21:45:13 +00:00
|
|
|
return true;
|
2007-06-06 10:16:17 +00:00
|
|
|
}
|
|
|
|
|
2007-06-08 09:36:04 +00:00
|
|
|
/// ValidTriangle - Returns true if the 'true' and 'false' blocks (along
|
2007-06-07 02:12:15 +00:00
|
|
|
/// with their common predecessor) forms a valid triangle shape for ifcvt.
|
2007-06-16 09:34:52 +00:00
|
|
|
/// If 'FalseBranch' is true, it checks if 'true' block's false branch
|
2010-06-15 22:18:54 +00:00
|
|
|
/// branches to the 'false' block rather than the other way around. It also
|
2007-06-16 09:34:52 +00:00
|
|
|
/// returns the number of instructions that the ifcvt would need to duplicate
|
|
|
|
/// if performed in 'Dups'.
|
2007-06-08 09:36:04 +00:00
|
|
|
bool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
|
2010-10-01 22:45:50 +00:00
|
|
|
bool FalseBranch, unsigned &Dups,
|
2011-07-10 02:58:07 +00:00
|
|
|
const BranchProbability &Prediction) const {
|
2007-06-16 09:34:52 +00:00
|
|
|
Dups = 0;
|
2007-06-18 08:37:25 +00:00
|
|
|
if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
|
2007-06-11 22:26:22 +00:00
|
|
|
return false;
|
|
|
|
|
2007-06-15 21:18:05 +00:00
|
|
|
if (TrueBBI.BB->pred_size() > 1) {
|
|
|
|
if (TrueBBI.CannotBeCopied)
|
|
|
|
return false;
|
|
|
|
|
2007-06-15 07:36:12 +00:00
|
|
|
unsigned Size = TrueBBI.NonPredSize;
|
2007-06-16 09:34:52 +00:00
|
|
|
if (TrueBBI.IsBrAnalyzable) {
|
2008-01-29 13:02:09 +00:00
|
|
|
if (TrueBBI.TrueBB && TrueBBI.BrCond.empty())
|
2009-05-13 23:25:24 +00:00
|
|
|
// Ends with an unconditional branch. It will be removed.
|
2007-06-16 09:34:52 +00:00
|
|
|
--Size;
|
|
|
|
else {
|
|
|
|
MachineBasicBlock *FExit = FalseBranch
|
|
|
|
? TrueBBI.TrueBB : TrueBBI.FalseBB;
|
|
|
|
if (FExit)
|
|
|
|
// Require a conditional branch
|
|
|
|
++Size;
|
|
|
|
}
|
|
|
|
}
|
2011-07-10 02:58:07 +00:00
|
|
|
if (!TII->isProfitableToDupForIfCvt(*TrueBBI.BB, Size, Prediction))
|
2007-06-15 07:36:12 +00:00
|
|
|
return false;
|
2007-06-16 09:34:52 +00:00
|
|
|
Dups = Size;
|
2007-06-15 07:36:12 +00:00
|
|
|
}
|
2007-06-07 02:12:15 +00:00
|
|
|
|
2007-06-08 09:36:04 +00:00
|
|
|
MachineBasicBlock *TExit = FalseBranch ? TrueBBI.FalseBB : TrueBBI.TrueBB;
|
|
|
|
if (!TExit && blockAlwaysFallThrough(TrueBBI)) {
|
2007-06-07 02:12:15 +00:00
|
|
|
MachineFunction::iterator I = TrueBBI.BB;
|
|
|
|
if (++I == TrueBBI.BB->getParent()->end())
|
|
|
|
return false;
|
2007-06-08 09:36:04 +00:00
|
|
|
TExit = I;
|
2007-06-07 02:12:15 +00:00
|
|
|
}
|
2007-06-08 09:36:04 +00:00
|
|
|
return TExit && TExit == FalseBBI.BB;
|
2007-06-07 02:12:15 +00:00
|
|
|
}
|
|
|
|
|
2007-06-08 09:36:04 +00:00
|
|
|
/// ValidDiamond - Returns true if the 'true' and 'false' blocks (along
|
2007-06-07 02:12:15 +00:00
|
|
|
/// with their common predecessor) forms a valid diamond shape for ifcvt.
|
2007-06-18 08:37:25 +00:00
|
|
|
bool IfConverter::ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
|
|
|
|
unsigned &Dups1, unsigned &Dups2) const {
|
|
|
|
Dups1 = Dups2 = 0;
|
|
|
|
if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
|
|
|
|
FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)
|
2007-06-11 22:26:22 +00:00
|
|
|
return false;
|
|
|
|
|
2007-06-09 01:03:43 +00:00
|
|
|
MachineBasicBlock *TT = TrueBBI.TrueBB;
|
|
|
|
MachineBasicBlock *FT = FalseBBI.TrueBB;
|
|
|
|
|
|
|
|
if (!TT && blockAlwaysFallThrough(TrueBBI))
|
|
|
|
TT = getNextBlock(TrueBBI.BB);
|
|
|
|
if (!FT && blockAlwaysFallThrough(FalseBBI))
|
|
|
|
FT = getNextBlock(FalseBBI.BB);
|
|
|
|
if (TT != FT)
|
|
|
|
return false;
|
2007-06-11 22:26:22 +00:00
|
|
|
if (TT == NULL && (TrueBBI.IsBrAnalyzable || FalseBBI.IsBrAnalyzable))
|
2007-06-09 01:03:43 +00:00
|
|
|
return false;
|
2007-06-18 22:44:57 +00:00
|
|
|
if (TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// FIXME: Allow true block to have an early exit?
|
|
|
|
if (TrueBBI.FalseBB || FalseBBI.FalseBB ||
|
|
|
|
(TrueBBI.ClobbersPred && FalseBBI.ClobbersPred))
|
2007-06-18 08:37:25 +00:00
|
|
|
return false;
|
|
|
|
|
2010-10-26 00:02:24 +00:00
|
|
|
// Count duplicate instructions at the beginning of the true and false blocks.
|
|
|
|
MachineBasicBlock::iterator TIB = TrueBBI.BB->begin();
|
|
|
|
MachineBasicBlock::iterator FIB = FalseBBI.BB->begin();
|
2010-06-07 21:28:55 +00:00
|
|
|
MachineBasicBlock::iterator TIE = TrueBBI.BB->end();
|
|
|
|
MachineBasicBlock::iterator FIE = FalseBBI.BB->end();
|
2010-10-26 00:02:24 +00:00
|
|
|
while (TIB != TIE && FIB != FIE) {
|
2010-06-18 21:52:57 +00:00
|
|
|
// Skip dbg_value instructions. These do not count.
|
2010-10-26 00:02:24 +00:00
|
|
|
if (TIB->isDebugValue()) {
|
|
|
|
while (TIB != TIE && TIB->isDebugValue())
|
|
|
|
++TIB;
|
|
|
|
if (TIB == TIE)
|
2010-06-18 21:52:57 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-10-26 00:02:24 +00:00
|
|
|
if (FIB->isDebugValue()) {
|
|
|
|
while (FIB != FIE && FIB->isDebugValue())
|
|
|
|
++FIB;
|
|
|
|
if (FIB == FIE)
|
2010-06-18 21:52:57 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-10-26 00:02:24 +00:00
|
|
|
if (!TIB->isIdenticalTo(FIB))
|
2007-06-18 08:37:25 +00:00
|
|
|
break;
|
|
|
|
++Dups1;
|
2010-10-26 00:02:24 +00:00
|
|
|
++TIB;
|
|
|
|
++FIB;
|
2007-06-18 08:37:25 +00:00
|
|
|
}
|
|
|
|
|
2010-10-26 00:02:24 +00:00
|
|
|
// Now, in preparation for counting duplicate instructions at the ends of the
|
|
|
|
// blocks, move the end iterators up past any branch instructions.
|
|
|
|
while (TIE != TIB) {
|
|
|
|
--TIE;
|
2011-12-07 07:15:52 +00:00
|
|
|
if (!TIE->isBranch())
|
2010-10-26 00:02:24 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
while (FIE != FIB) {
|
|
|
|
--FIE;
|
2011-12-07 07:15:52 +00:00
|
|
|
if (!FIE->isBranch())
|
2010-10-26 00:02:24 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If Dups1 includes all of a block, then don't count duplicate
|
|
|
|
// instructions at the end of the blocks.
|
|
|
|
if (TIB == TIE || FIB == FIE)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Count duplicate instructions at the ends of the blocks.
|
|
|
|
while (TIE != TIB && FIE != FIB) {
|
2010-06-18 21:52:57 +00:00
|
|
|
// Skip dbg_value instructions. These do not count.
|
2010-10-26 00:02:24 +00:00
|
|
|
if (TIE->isDebugValue()) {
|
|
|
|
while (TIE != TIB && TIE->isDebugValue())
|
|
|
|
--TIE;
|
|
|
|
if (TIE == TIB)
|
2010-06-18 21:52:57 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-10-26 00:02:24 +00:00
|
|
|
if (FIE->isDebugValue()) {
|
|
|
|
while (FIE != FIB && FIE->isDebugValue())
|
|
|
|
--FIE;
|
|
|
|
if (FIE == FIB)
|
2010-06-18 21:52:57 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-10-26 00:02:24 +00:00
|
|
|
if (!TIE->isIdenticalTo(FIE))
|
2007-06-18 08:37:25 +00:00
|
|
|
break;
|
|
|
|
++Dups2;
|
2010-10-26 00:02:24 +00:00
|
|
|
--TIE;
|
|
|
|
--FIE;
|
2007-06-18 08:37:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2007-06-07 02:12:15 +00:00
|
|
|
}
|
|
|
|
|
2007-06-11 22:26:22 +00:00
|
|
|
/// ScanInstructions - Scan all the instructions in the block to determine if
|
|
|
|
/// the block is predicable. In most cases, that means all the instructions
|
2008-01-07 01:56:04 +00:00
|
|
|
/// in the block are isPredicable(). Also checks if the block contains any
|
2007-06-11 22:26:22 +00:00
|
|
|
/// instruction which can clobber a predicate (e.g. condition code register).
|
|
|
|
/// If so, the block is not predicable unless it's the last instruction.
|
|
|
|
void IfConverter::ScanInstructions(BBInfo &BBI) {
|
|
|
|
if (BBI.IsDone)
|
|
|
|
return;
|
|
|
|
|
2012-06-08 21:53:50 +00:00
|
|
|
bool AlreadyPredicated = !BBI.Predicate.empty();
|
2007-06-11 22:26:22 +00:00
|
|
|
// First analyze the end of BB branches.
|
2007-06-14 21:26:08 +00:00
|
|
|
BBI.TrueBB = BBI.FalseBB = NULL;
|
2007-06-11 22:26:22 +00:00
|
|
|
BBI.BrCond.clear();
|
|
|
|
BBI.IsBrAnalyzable =
|
|
|
|
!TII->AnalyzeBranch(*BBI.BB, BBI.TrueBB, BBI.FalseBB, BBI.BrCond);
|
|
|
|
BBI.HasFallThrough = BBI.IsBrAnalyzable && BBI.FalseBB == NULL;
|
|
|
|
|
|
|
|
if (BBI.BrCond.size()) {
|
|
|
|
// No false branch. This BB must end with a conditional branch and a
|
|
|
|
// fallthrough.
|
|
|
|
if (!BBI.FalseBB)
|
2010-06-15 22:18:54 +00:00
|
|
|
BBI.FalseBB = findFalseBlock(BBI.BB, BBI.TrueBB);
|
2009-06-15 21:24:34 +00:00
|
|
|
if (!BBI.FalseBB) {
|
|
|
|
// Malformed bcc? True and false blocks are the same?
|
|
|
|
BBI.IsUnpredicable = true;
|
|
|
|
return;
|
|
|
|
}
|
2007-06-11 22:26:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Then scan all the instructions.
|
|
|
|
BBI.NonPredSize = 0;
|
2010-10-26 00:02:21 +00:00
|
|
|
BBI.ExtraCost = 0;
|
2010-11-03 00:45:17 +00:00
|
|
|
BBI.ExtraCost2 = 0;
|
2007-06-11 22:26:22 +00:00
|
|
|
BBI.ClobbersPred = false;
|
|
|
|
for (MachineBasicBlock::iterator I = BBI.BB->begin(), E = BBI.BB->end();
|
|
|
|
I != E; ++I) {
|
2010-06-04 23:01:26 +00:00
|
|
|
if (I->isDebugValue())
|
|
|
|
continue;
|
|
|
|
|
2011-12-07 07:15:52 +00:00
|
|
|
if (I->isNotDuplicable())
|
2007-06-15 21:18:05 +00:00
|
|
|
BBI.CannotBeCopied = true;
|
|
|
|
|
2007-06-11 22:26:22 +00:00
|
|
|
bool isPredicated = TII->isPredicated(I);
|
2011-12-07 07:15:52 +00:00
|
|
|
bool isCondBr = BBI.IsBrAnalyzable && I->isConditionalBranch();
|
2007-06-11 22:26:22 +00:00
|
|
|
|
2013-09-09 14:21:49 +00:00
|
|
|
// A conditional branch is not predicable, but it may be eliminated.
|
|
|
|
if (isCondBr)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!isPredicated) {
|
|
|
|
BBI.NonPredSize++;
|
2013-09-30 15:28:56 +00:00
|
|
|
unsigned ExtraPredCost = TII->getPredicationCost(&*I);
|
|
|
|
unsigned NumCycles = SchedModel.computeInstrLatency(&*I, false);
|
2013-09-09 14:21:49 +00:00
|
|
|
if (NumCycles > 1)
|
|
|
|
BBI.ExtraCost += NumCycles-1;
|
|
|
|
BBI.ExtraCost2 += ExtraPredCost;
|
|
|
|
} else if (!AlreadyPredicated) {
|
|
|
|
// FIXME: This instruction is already predicated before the
|
|
|
|
// if-conversion pass. It's probably something like a conditional move.
|
|
|
|
// Mark this block unpredicable for now.
|
|
|
|
BBI.IsUnpredicable = true;
|
|
|
|
return;
|
2007-07-06 23:24:39 +00:00
|
|
|
}
|
2007-06-11 22:26:22 +00:00
|
|
|
|
|
|
|
if (BBI.ClobbersPred && !isPredicated) {
|
|
|
|
// Predicate modification instruction should end the block (except for
|
|
|
|
// already predicated instructions and end of block branches).
|
|
|
|
// Predicate may have been modified, the subsequent (currently)
|
2007-07-06 23:24:39 +00:00
|
|
|
// unpredicated instructions cannot be correctly predicated.
|
2007-06-11 22:26:22 +00:00
|
|
|
BBI.IsUnpredicable = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-07-10 17:50:43 +00:00
|
|
|
// FIXME: Make use of PredDefs? e.g. ADDC, SUBC sets predicates but are
|
|
|
|
// still potentially predicable.
|
|
|
|
std::vector<MachineOperand> PredDefs;
|
|
|
|
if (TII->DefinesPredicate(I, PredDefs))
|
2007-06-11 22:26:22 +00:00
|
|
|
BBI.ClobbersPred = true;
|
|
|
|
|
2009-11-21 06:20:26 +00:00
|
|
|
if (!TII->isPredicable(I)) {
|
2007-06-11 22:26:22 +00:00
|
|
|
BBI.IsUnpredicable = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// FeasibilityAnalysis - Determine if the block is a suitable candidate to be
|
|
|
|
/// predicated by the specified predicate.
|
|
|
|
bool IfConverter::FeasibilityAnalysis(BBInfo &BBI,
|
2008-08-14 22:49:33 +00:00
|
|
|
SmallVectorImpl<MachineOperand> &Pred,
|
2007-06-11 22:26:22 +00:00
|
|
|
bool isTriangle, bool RevBranch) {
|
2007-06-16 09:34:52 +00:00
|
|
|
// If the block is dead or unpredicable, then it cannot be predicated.
|
|
|
|
if (BBI.IsDone || BBI.IsUnpredicable)
|
2007-06-11 22:26:22 +00:00
|
|
|
return false;
|
|
|
|
|
2013-07-24 20:20:37 +00:00
|
|
|
// If it is already predicated, check if the new predicate subsumes
|
|
|
|
// its predicate.
|
|
|
|
if (BBI.Predicate.size() && !TII->SubsumesPredicate(Pred, BBI.Predicate))
|
2007-06-11 22:26:22 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
if (BBI.BrCond.size()) {
|
|
|
|
if (!isTriangle)
|
|
|
|
return false;
|
|
|
|
|
2009-05-13 23:25:24 +00:00
|
|
|
// Test predicate subsumption.
|
2008-08-14 22:49:33 +00:00
|
|
|
SmallVector<MachineOperand, 4> RevPred(Pred.begin(), Pred.end());
|
|
|
|
SmallVector<MachineOperand, 4> Cond(BBI.BrCond.begin(), BBI.BrCond.end());
|
2007-06-11 22:26:22 +00:00
|
|
|
if (RevBranch) {
|
|
|
|
if (TII->ReverseBranchCondition(Cond))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (TII->ReverseBranchCondition(RevPred) ||
|
|
|
|
!TII->SubsumesPredicate(Cond, RevPred))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2007-06-08 09:36:04 +00:00
|
|
|
/// AnalyzeBlock - Analyze the structure of the sub-CFG starting from
|
2007-05-18 18:14:37 +00:00
|
|
|
/// the specified block. Record its successors and whether it looks like an
|
|
|
|
/// if-conversion candidate.
|
2007-06-16 09:34:52 +00:00
|
|
|
IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB,
|
|
|
|
std::vector<IfcvtToken*> &Tokens) {
|
2007-05-16 02:00:57 +00:00
|
|
|
BBInfo &BBI = BBAnalysis[BB->getNumber()];
|
|
|
|
|
2007-06-11 22:26:22 +00:00
|
|
|
if (BBI.IsAnalyzed || BBI.IsBeingAnalyzed)
|
|
|
|
return BBI;
|
2007-05-18 00:20:58 +00:00
|
|
|
|
2007-06-11 22:26:22 +00:00
|
|
|
BBI.BB = BB;
|
|
|
|
BBI.IsBeingAnalyzed = true;
|
2007-05-25 00:59:01 +00:00
|
|
|
|
2007-06-11 22:26:22 +00:00
|
|
|
ScanInstructions(BBI);
|
|
|
|
|
2011-07-10 02:00:16 +00:00
|
|
|
// Unanalyzable or ends with fallthrough or unconditional branch, or if is not
|
|
|
|
// considered for ifcvt anymore.
|
|
|
|
if (!BBI.IsBrAnalyzable || BBI.BrCond.empty() || BBI.IsDone) {
|
2007-06-11 22:26:22 +00:00
|
|
|
BBI.IsBeingAnalyzed = false;
|
|
|
|
BBI.IsAnalyzed = true;
|
|
|
|
return BBI;
|
|
|
|
}
|
2007-05-16 21:54:37 +00:00
|
|
|
|
2007-06-11 22:26:22 +00:00
|
|
|
// Do not ifcvt if either path is a back edge to the entry block.
|
|
|
|
if (BBI.TrueBB == BB || BBI.FalseBB == BB) {
|
|
|
|
BBI.IsBeingAnalyzed = false;
|
|
|
|
BBI.IsAnalyzed = true;
|
|
|
|
return BBI;
|
|
|
|
}
|
2007-05-18 00:20:58 +00:00
|
|
|
|
2009-06-15 21:24:34 +00:00
|
|
|
// Do not ifcvt if true and false fallthrough blocks are the same.
|
|
|
|
if (!BBI.FalseBB) {
|
|
|
|
BBI.IsBeingAnalyzed = false;
|
|
|
|
BBI.IsAnalyzed = true;
|
|
|
|
return BBI;
|
|
|
|
}
|
|
|
|
|
2007-06-16 09:34:52 +00:00
|
|
|
BBInfo &TrueBBI = AnalyzeBlock(BBI.TrueBB, Tokens);
|
|
|
|
BBInfo &FalseBBI = AnalyzeBlock(BBI.FalseBB, Tokens);
|
2007-06-06 10:16:17 +00:00
|
|
|
|
2007-06-11 22:26:22 +00:00
|
|
|
if (TrueBBI.IsDone && FalseBBI.IsDone) {
|
|
|
|
BBI.IsBeingAnalyzed = false;
|
|
|
|
BBI.IsAnalyzed = true;
|
|
|
|
return BBI;
|
2007-06-06 10:16:17 +00:00
|
|
|
}
|
|
|
|
|
2008-08-14 22:49:33 +00:00
|
|
|
SmallVector<MachineOperand, 4> RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
|
2007-06-04 06:47:22 +00:00
|
|
|
bool CanRevCond = !TII->ReverseBranchCondition(RevCond);
|
2007-06-08 09:36:04 +00:00
|
|
|
|
2007-06-16 09:34:52 +00:00
|
|
|
unsigned Dups = 0;
|
2007-06-18 08:37:25 +00:00
|
|
|
unsigned Dups2 = 0;
|
2012-06-08 21:53:50 +00:00
|
|
|
bool TNeedSub = !TrueBBI.Predicate.empty();
|
|
|
|
bool FNeedSub = !FalseBBI.Predicate.empty();
|
2007-06-16 09:34:52 +00:00
|
|
|
bool Enqueued = false;
|
2011-08-03 22:34:43 +00:00
|
|
|
|
|
|
|
BranchProbability Prediction = MBPI->getEdgeProbability(BB, TrueBBI.BB);
|
|
|
|
|
2007-06-18 08:37:25 +00:00
|
|
|
if (CanRevCond && ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2) &&
|
2010-10-26 00:02:21 +00:00
|
|
|
MeetIfcvtSizeLimit(*TrueBBI.BB, (TrueBBI.NonPredSize - (Dups + Dups2) +
|
2010-11-03 00:45:17 +00:00
|
|
|
TrueBBI.ExtraCost), TrueBBI.ExtraCost2,
|
2010-10-26 00:02:21 +00:00
|
|
|
*FalseBBI.BB, (FalseBBI.NonPredSize - (Dups + Dups2) +
|
2010-11-03 00:45:17 +00:00
|
|
|
FalseBBI.ExtraCost),FalseBBI.ExtraCost2,
|
2011-07-10 02:58:07 +00:00
|
|
|
Prediction) &&
|
2007-06-08 09:36:04 +00:00
|
|
|
FeasibilityAnalysis(TrueBBI, BBI.BrCond) &&
|
|
|
|
FeasibilityAnalysis(FalseBBI, RevCond)) {
|
2007-05-16 02:00:57 +00:00
|
|
|
// Diamond:
|
|
|
|
// EBB
|
|
|
|
// / \_
|
|
|
|
// | |
|
|
|
|
// TBB FBB
|
|
|
|
// \ /
|
2007-05-18 00:20:58 +00:00
|
|
|
// TailBB
|
2007-06-05 23:46:14 +00:00
|
|
|
// Note TailBB can be empty.
|
2007-06-18 08:37:25 +00:00
|
|
|
Tokens.push_back(new IfcvtToken(BBI, ICDiamond, TNeedSub|FNeedSub, Dups,
|
|
|
|
Dups2));
|
2007-06-16 09:34:52 +00:00
|
|
|
Enqueued = true;
|
|
|
|
}
|
|
|
|
|
2011-07-10 02:58:07 +00:00
|
|
|
if (ValidTriangle(TrueBBI, FalseBBI, false, Dups, Prediction) &&
|
2010-10-26 00:02:21 +00:00
|
|
|
MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
|
2011-07-10 02:58:07 +00:00
|
|
|
TrueBBI.ExtraCost2, Prediction) &&
|
2007-06-16 09:34:52 +00:00
|
|
|
FeasibilityAnalysis(TrueBBI, BBI.BrCond, true)) {
|
|
|
|
// Triangle:
|
|
|
|
// EBB
|
|
|
|
// | \_
|
|
|
|
// | |
|
|
|
|
// | TBB
|
|
|
|
// | /
|
|
|
|
// FBB
|
|
|
|
Tokens.push_back(new IfcvtToken(BBI, ICTriangle, TNeedSub, Dups));
|
|
|
|
Enqueued = true;
|
|
|
|
}
|
2010-06-15 22:18:54 +00:00
|
|
|
|
2011-07-10 02:58:07 +00:00
|
|
|
if (ValidTriangle(TrueBBI, FalseBBI, true, Dups, Prediction) &&
|
2010-10-26 00:02:21 +00:00
|
|
|
MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
|
2011-07-10 02:58:07 +00:00
|
|
|
TrueBBI.ExtraCost2, Prediction) &&
|
2007-06-16 09:34:52 +00:00
|
|
|
FeasibilityAnalysis(TrueBBI, BBI.BrCond, true, true)) {
|
|
|
|
Tokens.push_back(new IfcvtToken(BBI, ICTriangleRev, TNeedSub, Dups));
|
|
|
|
Enqueued = true;
|
|
|
|
}
|
|
|
|
|
2011-07-10 02:58:07 +00:00
|
|
|
if (ValidSimple(TrueBBI, Dups, Prediction) &&
|
2010-10-26 00:02:21 +00:00
|
|
|
MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
|
2011-07-10 02:58:07 +00:00
|
|
|
TrueBBI.ExtraCost2, Prediction) &&
|
2007-06-16 09:34:52 +00:00
|
|
|
FeasibilityAnalysis(TrueBBI, BBI.BrCond)) {
|
|
|
|
// Simple (split, no rejoin):
|
|
|
|
// EBB
|
|
|
|
// | \_
|
|
|
|
// | |
|
|
|
|
// | TBB---> exit
|
2010-06-15 22:18:54 +00:00
|
|
|
// |
|
2007-06-16 09:34:52 +00:00
|
|
|
// FBB
|
|
|
|
Tokens.push_back(new IfcvtToken(BBI, ICSimple, TNeedSub, Dups));
|
|
|
|
Enqueued = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CanRevCond) {
|
|
|
|
// Try the other path...
|
2010-10-01 22:45:50 +00:00
|
|
|
if (ValidTriangle(FalseBBI, TrueBBI, false, Dups,
|
2011-07-10 02:58:07 +00:00
|
|
|
Prediction.getCompl()) &&
|
2010-10-26 00:02:21 +00:00
|
|
|
MeetIfcvtSizeLimit(*FalseBBI.BB,
|
|
|
|
FalseBBI.NonPredSize + FalseBBI.ExtraCost,
|
2011-07-10 02:58:07 +00:00
|
|
|
FalseBBI.ExtraCost2, Prediction.getCompl()) &&
|
2007-06-16 09:34:52 +00:00
|
|
|
FeasibilityAnalysis(FalseBBI, RevCond, true)) {
|
|
|
|
Tokens.push_back(new IfcvtToken(BBI, ICTriangleFalse, FNeedSub, Dups));
|
|
|
|
Enqueued = true;
|
|
|
|
}
|
|
|
|
|
2010-10-01 22:45:50 +00:00
|
|
|
if (ValidTriangle(FalseBBI, TrueBBI, true, Dups,
|
2011-07-10 02:58:07 +00:00
|
|
|
Prediction.getCompl()) &&
|
2010-10-26 00:02:21 +00:00
|
|
|
MeetIfcvtSizeLimit(*FalseBBI.BB,
|
|
|
|
FalseBBI.NonPredSize + FalseBBI.ExtraCost,
|
2011-07-10 02:58:07 +00:00
|
|
|
FalseBBI.ExtraCost2, Prediction.getCompl()) &&
|
2007-06-16 09:34:52 +00:00
|
|
|
FeasibilityAnalysis(FalseBBI, RevCond, true, true)) {
|
|
|
|
Tokens.push_back(new IfcvtToken(BBI, ICTriangleFRev, FNeedSub, Dups));
|
|
|
|
Enqueued = true;
|
|
|
|
}
|
|
|
|
|
2011-07-10 02:58:07 +00:00
|
|
|
if (ValidSimple(FalseBBI, Dups, Prediction.getCompl()) &&
|
2010-10-26 00:02:21 +00:00
|
|
|
MeetIfcvtSizeLimit(*FalseBBI.BB,
|
|
|
|
FalseBBI.NonPredSize + FalseBBI.ExtraCost,
|
2011-07-10 02:58:07 +00:00
|
|
|
FalseBBI.ExtraCost2, Prediction.getCompl()) &&
|
2007-06-16 09:34:52 +00:00
|
|
|
FeasibilityAnalysis(FalseBBI, RevCond)) {
|
|
|
|
Tokens.push_back(new IfcvtToken(BBI, ICSimpleFalse, FNeedSub, Dups));
|
|
|
|
Enqueued = true;
|
2007-06-04 06:47:22 +00:00
|
|
|
}
|
2007-05-16 02:00:57 +00:00
|
|
|
}
|
2007-06-04 06:47:22 +00:00
|
|
|
|
2007-06-16 09:34:52 +00:00
|
|
|
BBI.IsEnqueued = Enqueued;
|
2007-06-11 22:26:22 +00:00
|
|
|
BBI.IsBeingAnalyzed = false;
|
|
|
|
BBI.IsAnalyzed = true;
|
|
|
|
return BBI;
|
2007-05-18 18:14:37 +00:00
|
|
|
}
|
|
|
|
|
2007-05-30 19:49:19 +00:00
|
|
|
/// AnalyzeBlocks - Analyze all blocks and find entries for all if-conversion
|
2010-06-15 18:57:15 +00:00
|
|
|
/// candidates.
|
|
|
|
void IfConverter::AnalyzeBlocks(MachineFunction &MF,
|
2007-06-16 09:34:52 +00:00
|
|
|
std::vector<IfcvtToken*> &Tokens) {
|
2011-04-27 19:32:43 +00:00
|
|
|
for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
|
|
|
|
MachineBasicBlock *BB = I;
|
|
|
|
AnalyzeBlock(BB, Tokens);
|
2007-05-16 02:00:57 +00:00
|
|
|
}
|
2007-05-30 19:49:19 +00:00
|
|
|
|
2007-06-01 00:12:12 +00:00
|
|
|
// Sort to favor more complex ifcvt scheme.
|
2007-06-16 09:34:52 +00:00
|
|
|
std::stable_sort(Tokens.begin(), Tokens.end(), IfcvtTokenCmp);
|
2007-05-16 02:00:57 +00:00
|
|
|
}
|
|
|
|
|
2007-06-08 22:01:07 +00:00
|
|
|
/// canFallThroughTo - Returns true either if ToBB is the next block after BB or
|
|
|
|
/// that all the intervening blocks are empty (given BB can fall through to its
|
|
|
|
/// next block).
|
|
|
|
static bool canFallThroughTo(MachineBasicBlock *BB, MachineBasicBlock *ToBB) {
|
2010-06-16 07:35:02 +00:00
|
|
|
MachineFunction::iterator PI = BB;
|
|
|
|
MachineFunction::iterator I = llvm::next(PI);
|
2007-06-05 07:05:25 +00:00
|
|
|
MachineFunction::iterator TI = ToBB;
|
|
|
|
MachineFunction::iterator E = BB->getParent()->end();
|
2010-06-16 07:35:02 +00:00
|
|
|
while (I != TI) {
|
|
|
|
// Check isSuccessor to avoid case where the next block is empty, but
|
|
|
|
// it's not a successor.
|
|
|
|
if (I == E || !I->empty() || !PI->isSuccessor(I))
|
2007-06-04 06:47:22 +00:00
|
|
|
return false;
|
2010-06-16 07:35:02 +00:00
|
|
|
PI = I++;
|
|
|
|
}
|
2007-06-04 06:47:22 +00:00
|
|
|
return true;
|
2007-05-21 22:22:58 +00:00
|
|
|
}
|
|
|
|
|
2007-06-18 08:37:25 +00:00
|
|
|
/// InvalidatePreds - Invalidate predecessor BB info so it would be re-analyzed
|
|
|
|
/// to determine if it can be if-converted. If predecessor is already enqueued,
|
|
|
|
/// dequeue it!
|
|
|
|
void IfConverter::InvalidatePreds(MachineBasicBlock *BB) {
|
2007-05-23 07:23:16 +00:00
|
|
|
for (MachineBasicBlock::pred_iterator PI = BB->pred_begin(),
|
|
|
|
E = BB->pred_end(); PI != E; ++PI) {
|
|
|
|
BBInfo &PBBI = BBAnalysis[(*PI)->getNumber()];
|
2007-06-14 23:34:09 +00:00
|
|
|
if (PBBI.IsDone || PBBI.BB == BB)
|
2007-06-14 23:13:19 +00:00
|
|
|
continue;
|
2007-06-14 23:34:09 +00:00
|
|
|
PBBI.IsAnalyzed = false;
|
|
|
|
PBBI.IsEnqueued = false;
|
2007-05-23 07:23:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-05-29 22:31:16 +00:00
|
|
|
/// InsertUncondBranch - Inserts an unconditional branch from BB to ToBB.
|
|
|
|
///
|
|
|
|
static void InsertUncondBranch(MachineBasicBlock *BB, MachineBasicBlock *ToBB,
|
|
|
|
const TargetInstrInfo *TII) {
|
2010-06-17 22:43:56 +00:00
|
|
|
DebugLoc dl; // FIXME: this is nowhere
|
2008-08-22 16:07:55 +00:00
|
|
|
SmallVector<MachineOperand, 0> NoCond;
|
2010-06-17 22:43:56 +00:00
|
|
|
TII->InsertBranch(*BB, ToBB, NULL, NoCond, dl);
|
2007-05-29 22:31:16 +00:00
|
|
|
}
|
|
|
|
|
2007-06-08 22:01:07 +00:00
|
|
|
/// RemoveExtraEdges - Remove true / false edges if either / both are no longer
|
|
|
|
/// successors.
|
|
|
|
void IfConverter::RemoveExtraEdges(BBInfo &BBI) {
|
|
|
|
MachineBasicBlock *TBB = NULL, *FBB = NULL;
|
2008-08-14 22:49:33 +00:00
|
|
|
SmallVector<MachineOperand, 4> Cond;
|
2007-06-18 22:44:57 +00:00
|
|
|
if (!TII->AnalyzeBranch(*BBI.BB, TBB, FBB, Cond))
|
|
|
|
BBI.BB->CorrectExtraCFGEdges(TBB, FBB, !Cond.empty());
|
2007-06-08 22:01:07 +00:00
|
|
|
}
|
|
|
|
|
2013-10-11 19:04:37 +00:00
|
|
|
/// Behaves like LiveRegUnits::StepForward() but also adds implicit uses to all
|
|
|
|
/// values defined in MI which are not live/used by MI.
|
|
|
|
static void UpdatePredRedefs(MachineInstr *MI, LiveRegUnits &Redefs,
|
|
|
|
const TargetRegisterInfo *TRI) {
|
|
|
|
for (ConstMIBundleOperands Ops(MI); Ops.isValid(); ++Ops) {
|
|
|
|
if (!Ops->isReg() || !Ops->isKill())
|
2010-06-16 07:35:02 +00:00
|
|
|
continue;
|
2013-10-11 19:04:37 +00:00
|
|
|
unsigned Reg = Ops->getReg();
|
|
|
|
if (Reg == 0)
|
2010-06-16 07:35:02 +00:00
|
|
|
continue;
|
2013-10-14 20:45:09 +00:00
|
|
|
Redefs.removeReg(Reg, *TRI);
|
2010-06-16 07:35:02 +00:00
|
|
|
}
|
2013-10-11 19:04:37 +00:00
|
|
|
for (MIBundleOperands Ops(MI); Ops.isValid(); ++Ops) {
|
|
|
|
if (!Ops->isReg() || !Ops->isDef())
|
|
|
|
continue;
|
|
|
|
unsigned Reg = Ops->getReg();
|
2013-10-14 20:45:09 +00:00
|
|
|
if (Reg == 0 || Redefs.contains(Reg, *TRI))
|
2013-10-11 19:04:37 +00:00
|
|
|
continue;
|
2013-10-14 20:45:09 +00:00
|
|
|
Redefs.addReg(Reg, *TRI);
|
2013-10-11 19:04:37 +00:00
|
|
|
|
|
|
|
MachineOperand &Op = *Ops;
|
|
|
|
MachineInstr *MI = Op.getParent();
|
|
|
|
MachineInstrBuilder MIB(*MI->getParent()->getParent(), MI);
|
|
|
|
MIB.addReg(Reg, RegState::Implicit | RegState::Undef);
|
2010-06-16 07:35:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-11 19:04:37 +00:00
|
|
|
/**
|
|
|
|
* Remove kill flags from operands with a registers in the @p DontKill set.
|
|
|
|
*/
|
|
|
|
static void RemoveKills(MachineInstr &MI, const LiveRegUnits &DontKill,
|
|
|
|
const MCRegisterInfo &MCRI) {
|
|
|
|
for (MIBundleOperands O(&MI); O.isValid(); ++O) {
|
|
|
|
if (!O->isReg() || !O->isKill())
|
|
|
|
continue;
|
2013-10-14 20:45:09 +00:00
|
|
|
if (DontKill.contains(O->getReg(), MCRI))
|
2013-10-11 19:04:37 +00:00
|
|
|
O->setIsKill(false);
|
2010-06-16 07:35:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-11 19:04:37 +00:00
|
|
|
/**
|
|
|
|
* Walks a range of machine instructions and removes kill flags for registers
|
|
|
|
* in the @p DontKill set.
|
|
|
|
*/
|
|
|
|
static void RemoveKills(MachineBasicBlock::iterator I,
|
|
|
|
MachineBasicBlock::iterator E,
|
|
|
|
const LiveRegUnits &DontKill,
|
|
|
|
const MCRegisterInfo &MCRI) {
|
|
|
|
for ( ; I != E; ++I)
|
|
|
|
RemoveKills(*I, DontKill, MCRI);
|
|
|
|
}
|
|
|
|
|
2007-06-04 06:47:22 +00:00
|
|
|
/// IfConvertSimple - If convert a simple (split, no rejoin) sub-CFG.
|
2007-05-21 22:22:58 +00:00
|
|
|
///
|
2007-06-16 09:34:52 +00:00
|
|
|
bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) {
|
2007-05-21 22:22:58 +00:00
|
|
|
BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
|
|
|
|
BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
|
|
|
|
BBInfo *CvtBBI = &TrueBBI;
|
|
|
|
BBInfo *NextBBI = &FalseBBI;
|
2007-05-23 07:23:16 +00:00
|
|
|
|
2008-08-14 22:49:33 +00:00
|
|
|
SmallVector<MachineOperand, 4> Cond(BBI.BrCond.begin(), BBI.BrCond.end());
|
2007-06-16 09:34:52 +00:00
|
|
|
if (Kind == ICSimpleFalse)
|
2007-06-01 20:29:21 +00:00
|
|
|
std::swap(CvtBBI, NextBBI);
|
2007-06-15 21:18:05 +00:00
|
|
|
|
2007-06-18 08:37:25 +00:00
|
|
|
if (CvtBBI->IsDone ||
|
|
|
|
(CvtBBI->CannotBeCopied && CvtBBI->BB->pred_size() > 1)) {
|
2007-06-15 21:18:05 +00:00
|
|
|
// Something has changed. It's no longer safe to predicate this block.
|
|
|
|
BBI.IsAnalyzed = false;
|
|
|
|
CvtBBI->IsAnalyzed = false;
|
|
|
|
return false;
|
2007-06-01 20:29:21 +00:00
|
|
|
}
|
2007-05-23 07:23:16 +00:00
|
|
|
|
2013-05-05 18:03:49 +00:00
|
|
|
if (CvtBBI->BB->hasAddressTaken())
|
|
|
|
// Conservatively abort if-conversion if BB's address is taken.
|
|
|
|
return false;
|
|
|
|
|
2007-06-16 09:34:52 +00:00
|
|
|
if (Kind == ICSimpleFalse)
|
Optimized FCMP_OEQ and FCMP_UNE for x86.
Where previously LLVM might emit code like this:
ucomisd %xmm1, %xmm0
setne %al
setp %cl
orb %al, %cl
jne .LBB4_2
it now emits this:
ucomisd %xmm1, %xmm0
jne .LBB4_2
jp .LBB4_2
It has fewer instructions and uses fewer registers, but it does
have more branches. And in the case that this code is followed by
a non-fallthrough edge, it may be followed by a jmp instruction,
resulting in three branch instructions in sequence. Some effort
is made to avoid this situation.
To achieve this, X86ISelLowering.cpp now recognizes FCMP_OEQ and
FCMP_UNE in lowered form, and replace them with code that emits
two branches, except in the case where it would require converting
a fall-through edge to an explicit branch.
Also, X86InstrInfo.cpp's branch analysis and transform code now
knows now to handle blocks with multiple conditional branches. It
uses loops instead of having fixed checks for up to two
instructions. It can now analyze and transform code generated
from FCMP_OEQ and FCMP_UNE.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@57873 91177308-0d34-0410-b5e6-96231b3b80d8
2008-10-21 03:29:32 +00:00
|
|
|
if (TII->ReverseBranchCondition(Cond))
|
2012-02-05 08:31:47 +00:00
|
|
|
llvm_unreachable("Unable to reverse branch condition!");
|
2007-06-15 21:18:05 +00:00
|
|
|
|
2010-06-19 05:33:57 +00:00
|
|
|
// Initialize liveins to the first BB. These are potentiall redefined by
|
2010-06-16 07:35:02 +00:00
|
|
|
// predicated instructions.
|
2013-10-14 20:45:17 +00:00
|
|
|
Redefs.init(TRI);
|
2013-10-14 20:45:09 +00:00
|
|
|
Redefs.addLiveIns(*(CvtBBI->BB), *TRI);
|
|
|
|
Redefs.addLiveIns(*(NextBBI->BB), *TRI);
|
2013-10-11 19:04:37 +00:00
|
|
|
|
|
|
|
// Compute a set of registers which must not be killed by instructions in
|
|
|
|
// BB1: This is everything live-in to BB2.
|
2013-10-14 20:45:17 +00:00
|
|
|
DontKill.init(TRI);
|
2013-10-14 20:45:09 +00:00
|
|
|
DontKill.addLiveIns(*(NextBBI->BB), *TRI);
|
2010-06-16 07:35:02 +00:00
|
|
|
|
2007-06-15 07:36:12 +00:00
|
|
|
if (CvtBBI->BB->pred_size() > 1) {
|
|
|
|
BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
|
2009-05-13 23:25:24 +00:00
|
|
|
// Copy instructions in the true block, predicate them, and add them to
|
2007-06-15 07:36:12 +00:00
|
|
|
// the entry block.
|
2013-10-14 20:45:17 +00:00
|
|
|
CopyAndPredicateBlock(BBI, *CvtBBI, Cond);
|
2013-04-10 22:05:25 +00:00
|
|
|
|
|
|
|
// RemoveExtraEdges won't work if the block has an unanalyzable branch, so
|
|
|
|
// explicitly remove CvtBBI as a successor.
|
|
|
|
BBI.BB->removeSuccessor(CvtBBI->BB);
|
2007-06-15 07:36:12 +00:00
|
|
|
} else {
|
2013-10-11 19:04:37 +00:00
|
|
|
RemoveKills(CvtBBI->BB->begin(), CvtBBI->BB->end(), DontKill, *TRI);
|
2013-10-14 20:45:17 +00:00
|
|
|
PredicateBlock(*CvtBBI, CvtBBI->BB->end(), Cond);
|
2007-05-21 22:22:58 +00:00
|
|
|
|
2007-06-15 07:36:12 +00:00
|
|
|
// Merge converted block into entry block.
|
|
|
|
BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
|
|
|
|
MergeBlocks(BBI, *CvtBBI);
|
|
|
|
}
|
2007-06-07 02:12:15 +00:00
|
|
|
|
2007-06-06 02:08:52 +00:00
|
|
|
bool IterIfcvt = true;
|
2007-06-08 22:01:07 +00:00
|
|
|
if (!canFallThroughTo(BBI.BB, NextBBI->BB)) {
|
2007-05-29 22:31:16 +00:00
|
|
|
InsertUncondBranch(BBI.BB, NextBBI->BB, TII);
|
2007-06-09 01:03:43 +00:00
|
|
|
BBI.HasFallThrough = false;
|
2007-06-08 09:36:04 +00:00
|
|
|
// Now ifcvt'd block will look like this:
|
|
|
|
// BB:
|
|
|
|
// ...
|
|
|
|
// t, f = cmp
|
|
|
|
// if t op
|
|
|
|
// b BBf
|
|
|
|
//
|
|
|
|
// We cannot further ifcvt this block because the unconditional branch
|
|
|
|
// will have to be predicated on the new condition, that will not be
|
|
|
|
// available if cmp executes.
|
|
|
|
IterIfcvt = false;
|
2007-06-06 02:08:52 +00:00
|
|
|
}
|
2007-05-23 07:23:16 +00:00
|
|
|
|
2007-06-08 22:01:07 +00:00
|
|
|
RemoveExtraEdges(BBI);
|
|
|
|
|
2007-05-23 07:23:16 +00:00
|
|
|
// Update block info. BB can be iteratively if-converted.
|
2007-06-11 22:26:22 +00:00
|
|
|
if (!IterIfcvt)
|
|
|
|
BBI.IsDone = true;
|
2007-06-18 08:37:25 +00:00
|
|
|
InvalidatePreds(BBI.BB);
|
2007-06-11 22:26:22 +00:00
|
|
|
CvtBBI->IsDone = true;
|
2007-05-21 22:22:58 +00:00
|
|
|
|
|
|
|
// FIXME: Must maintain LiveIns.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2007-05-16 21:54:37 +00:00
|
|
|
/// IfConvertTriangle - If convert a triangle sub-CFG.
|
|
|
|
///
|
2007-06-16 09:34:52 +00:00
|
|
|
bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
|
2007-05-23 07:23:16 +00:00
|
|
|
BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
|
2007-06-09 01:03:43 +00:00
|
|
|
BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
|
|
|
|
BBInfo *CvtBBI = &TrueBBI;
|
|
|
|
BBInfo *NextBBI = &FalseBBI;
|
2010-06-17 22:43:56 +00:00
|
|
|
DebugLoc dl; // FIXME: this is nowhere
|
2007-06-09 01:03:43 +00:00
|
|
|
|
2008-08-14 22:49:33 +00:00
|
|
|
SmallVector<MachineOperand, 4> Cond(BBI.BrCond.begin(), BBI.BrCond.end());
|
2007-06-16 09:34:52 +00:00
|
|
|
if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
|
2007-06-09 01:03:43 +00:00
|
|
|
std::swap(CvtBBI, NextBBI);
|
2007-06-15 21:18:05 +00:00
|
|
|
|
2007-06-18 08:37:25 +00:00
|
|
|
if (CvtBBI->IsDone ||
|
|
|
|
(CvtBBI->CannotBeCopied && CvtBBI->BB->pred_size() > 1)) {
|
2007-06-15 21:18:05 +00:00
|
|
|
// Something has changed. It's no longer safe to predicate this block.
|
|
|
|
BBI.IsAnalyzed = false;
|
|
|
|
CvtBBI->IsAnalyzed = false;
|
|
|
|
return false;
|
2007-06-09 01:03:43 +00:00
|
|
|
}
|
2007-06-15 21:18:05 +00:00
|
|
|
|
2013-05-05 18:03:49 +00:00
|
|
|
if (CvtBBI->BB->hasAddressTaken())
|
|
|
|
// Conservatively abort if-conversion if BB's address is taken.
|
|
|
|
return false;
|
|
|
|
|
2007-06-16 09:34:52 +00:00
|
|
|
if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
|
Optimized FCMP_OEQ and FCMP_UNE for x86.
Where previously LLVM might emit code like this:
ucomisd %xmm1, %xmm0
setne %al
setp %cl
orb %al, %cl
jne .LBB4_2
it now emits this:
ucomisd %xmm1, %xmm0
jne .LBB4_2
jp .LBB4_2
It has fewer instructions and uses fewer registers, but it does
have more branches. And in the case that this code is followed by
a non-fallthrough edge, it may be followed by a jmp instruction,
resulting in three branch instructions in sequence. Some effort
is made to avoid this situation.
To achieve this, X86ISelLowering.cpp now recognizes FCMP_OEQ and
FCMP_UNE in lowered form, and replace them with code that emits
two branches, except in the case where it would require converting
a fall-through edge to an explicit branch.
Also, X86InstrInfo.cpp's branch analysis and transform code now
knows now to handle blocks with multiple conditional branches. It
uses loops instead of having fixed checks for up to two
instructions. It can now analyze and transform code generated
from FCMP_OEQ and FCMP_UNE.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@57873 91177308-0d34-0410-b5e6-96231b3b80d8
2008-10-21 03:29:32 +00:00
|
|
|
if (TII->ReverseBranchCondition(Cond))
|
2012-02-05 08:31:47 +00:00
|
|
|
llvm_unreachable("Unable to reverse branch condition!");
|
2007-06-15 21:18:05 +00:00
|
|
|
|
2007-06-16 09:34:52 +00:00
|
|
|
if (Kind == ICTriangleRev || Kind == ICTriangleFRev) {
|
Optimized FCMP_OEQ and FCMP_UNE for x86.
Where previously LLVM might emit code like this:
ucomisd %xmm1, %xmm0
setne %al
setp %cl
orb %al, %cl
jne .LBB4_2
it now emits this:
ucomisd %xmm1, %xmm0
jne .LBB4_2
jp .LBB4_2
It has fewer instructions and uses fewer registers, but it does
have more branches. And in the case that this code is followed by
a non-fallthrough edge, it may be followed by a jmp instruction,
resulting in three branch instructions in sequence. Some effort
is made to avoid this situation.
To achieve this, X86ISelLowering.cpp now recognizes FCMP_OEQ and
FCMP_UNE in lowered form, and replace them with code that emits
two branches, except in the case where it would require converting
a fall-through edge to an explicit branch.
Also, X86InstrInfo.cpp's branch analysis and transform code now
knows now to handle blocks with multiple conditional branches. It
uses loops instead of having fixed checks for up to two
instructions. It can now analyze and transform code generated
from FCMP_OEQ and FCMP_UNE.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@57873 91177308-0d34-0410-b5e6-96231b3b80d8
2008-10-21 03:29:32 +00:00
|
|
|
if (ReverseBranchCondition(*CvtBBI)) {
|
|
|
|
// BB has been changed, modify its predecessors (except for this
|
|
|
|
// one) so they don't get ifcvt'ed based on bad intel.
|
|
|
|
for (MachineBasicBlock::pred_iterator PI = CvtBBI->BB->pred_begin(),
|
|
|
|
E = CvtBBI->BB->pred_end(); PI != E; ++PI) {
|
|
|
|
MachineBasicBlock *PBB = *PI;
|
|
|
|
if (PBB == BBI.BB)
|
|
|
|
continue;
|
|
|
|
BBInfo &PBBI = BBAnalysis[PBB->getNumber()];
|
|
|
|
if (PBBI.IsEnqueued) {
|
|
|
|
PBBI.IsAnalyzed = false;
|
|
|
|
PBBI.IsEnqueued = false;
|
|
|
|
}
|
2007-06-14 23:34:09 +00:00
|
|
|
}
|
2007-06-12 23:54:05 +00:00
|
|
|
}
|
|
|
|
}
|
2007-06-01 07:41:07 +00:00
|
|
|
|
2010-06-19 05:33:57 +00:00
|
|
|
// Initialize liveins to the first BB. These are potentially redefined by
|
2010-06-16 07:35:02 +00:00
|
|
|
// predicated instructions.
|
2013-10-14 20:45:17 +00:00
|
|
|
Redefs.init(TRI);
|
2013-10-14 20:45:09 +00:00
|
|
|
Redefs.addLiveIns(*(CvtBBI->BB), *TRI);
|
|
|
|
Redefs.addLiveIns(*(NextBBI->BB), *TRI);
|
2010-06-16 07:35:02 +00:00
|
|
|
|
2013-10-14 20:45:17 +00:00
|
|
|
DontKill.clear();
|
|
|
|
|
2007-06-15 07:36:12 +00:00
|
|
|
bool HasEarlyExit = CvtBBI->FalseBB != NULL;
|
Reapply my if-conversion cleanup from svn r106939 with fixes.
There are 2 changes relative to the previous version of the patch:
1) For the "simple" if-conversion case, there's no need to worry about
RemoveExtraEdges not handling an unanalyzable branch. Predicated terminators
are ignored in this context, so RemoveExtraEdges does the right thing.
This might break someday if we ever treat indirect branches (BRIND) as
predicable, but for now, I just removed this part of the patch, because
in the case where we do not add an unconditional branch, we rely on keeping
the fall-through edge to CvtBBI (which is empty after this transformation).
The change relative to the previous patch is:
@@ -1036,10 +1036,6 @@
IterIfcvt = false;
}
- // RemoveExtraEdges won't work if the block has an unanalyzable branch,
- // which is typically the case for IfConvertSimple, so explicitly remove
- // CvtBBI as a successor.
- BBI.BB->removeSuccessor(CvtBBI->BB);
RemoveExtraEdges(BBI);
// Update block info. BB can be iteratively if-converted.
2) My patch exposed a bug in the code for merging the tail of a "diamond",
which had previously never been exercised. The code was simply checking that
the tail had a single predecessor, but there was a case in
MultiSource/Benchmarks/VersaBench/dbms where that single predecessor was
neither edge of the diamond. I added the following change to check for
that:
@@ -1276,7 +1276,18 @@
// tail, add a unconditional branch to it.
if (TailBB) {
BBInfo TailBBI = BBAnalysis[TailBB->getNumber()];
- if (TailBB->pred_size() == 1 && !TailBBI.HasFallThrough) {
+ bool CanMergeTail = !TailBBI.HasFallThrough;
+ // There may still be a fall-through edge from BBI1 or BBI2 to TailBB;
+ // check if there are any other predecessors besides those.
+ unsigned NumPreds = TailBB->pred_size();
+ if (NumPreds > 1)
+ CanMergeTail = false;
+ else if (NumPreds == 1 && CanMergeTail) {
+ MachineBasicBlock::pred_iterator PI = TailBB->pred_begin();
+ if (*PI != BBI1->BB && *PI != BBI2->BB)
+ CanMergeTail = false;
+ }
+ if (CanMergeTail) {
MergeBlocks(BBI, TailBBI);
TailBBI.IsDone = true;
} else {
With these fixes, I was able to run all the SingleSource and MultiSource
tests successfully.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107110 91177308-0d34-0410-b5e6-96231b3b80d8
2010-06-29 00:55:23 +00:00
|
|
|
if (CvtBBI->BB->pred_size() > 1) {
|
2007-06-15 07:36:12 +00:00
|
|
|
BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
|
2009-05-13 23:25:24 +00:00
|
|
|
// Copy instructions in the true block, predicate them, and add them to
|
2007-06-15 07:36:12 +00:00
|
|
|
// the entry block.
|
2013-10-14 20:45:17 +00:00
|
|
|
CopyAndPredicateBlock(BBI, *CvtBBI, Cond, true);
|
2013-04-10 22:05:25 +00:00
|
|
|
|
|
|
|
// RemoveExtraEdges won't work if the block has an unanalyzable branch, so
|
|
|
|
// explicitly remove CvtBBI as a successor.
|
|
|
|
BBI.BB->removeSuccessor(CvtBBI->BB);
|
2007-06-15 07:36:12 +00:00
|
|
|
} else {
|
|
|
|
// Predicate the 'true' block after removing its branch.
|
|
|
|
CvtBBI->NonPredSize -= TII->RemoveBranch(*CvtBBI->BB);
|
2013-10-14 20:45:17 +00:00
|
|
|
PredicateBlock(*CvtBBI, CvtBBI->BB->end(), Cond);
|
2007-05-16 02:00:57 +00:00
|
|
|
|
2007-06-18 22:44:57 +00:00
|
|
|
// Now merge the entry of the triangle with the true block.
|
|
|
|
BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
|
Reapply my if-conversion cleanup from svn r106939 with fixes.
There are 2 changes relative to the previous version of the patch:
1) For the "simple" if-conversion case, there's no need to worry about
RemoveExtraEdges not handling an unanalyzable branch. Predicated terminators
are ignored in this context, so RemoveExtraEdges does the right thing.
This might break someday if we ever treat indirect branches (BRIND) as
predicable, but for now, I just removed this part of the patch, because
in the case where we do not add an unconditional branch, we rely on keeping
the fall-through edge to CvtBBI (which is empty after this transformation).
The change relative to the previous patch is:
@@ -1036,10 +1036,6 @@
IterIfcvt = false;
}
- // RemoveExtraEdges won't work if the block has an unanalyzable branch,
- // which is typically the case for IfConvertSimple, so explicitly remove
- // CvtBBI as a successor.
- BBI.BB->removeSuccessor(CvtBBI->BB);
RemoveExtraEdges(BBI);
// Update block info. BB can be iteratively if-converted.
2) My patch exposed a bug in the code for merging the tail of a "diamond",
which had previously never been exercised. The code was simply checking that
the tail had a single predecessor, but there was a case in
MultiSource/Benchmarks/VersaBench/dbms where that single predecessor was
neither edge of the diamond. I added the following change to check for
that:
@@ -1276,7 +1276,18 @@
// tail, add a unconditional branch to it.
if (TailBB) {
BBInfo TailBBI = BBAnalysis[TailBB->getNumber()];
- if (TailBB->pred_size() == 1 && !TailBBI.HasFallThrough) {
+ bool CanMergeTail = !TailBBI.HasFallThrough;
+ // There may still be a fall-through edge from BBI1 or BBI2 to TailBB;
+ // check if there are any other predecessors besides those.
+ unsigned NumPreds = TailBB->pred_size();
+ if (NumPreds > 1)
+ CanMergeTail = false;
+ else if (NumPreds == 1 && CanMergeTail) {
+ MachineBasicBlock::pred_iterator PI = TailBB->pred_begin();
+ if (*PI != BBI1->BB && *PI != BBI2->BB)
+ CanMergeTail = false;
+ }
+ if (CanMergeTail) {
MergeBlocks(BBI, TailBBI);
TailBBI.IsDone = true;
} else {
With these fixes, I was able to run all the SingleSource and MultiSource
tests successfully.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107110 91177308-0d34-0410-b5e6-96231b3b80d8
2010-06-29 00:55:23 +00:00
|
|
|
MergeBlocks(BBI, *CvtBBI, false);
|
2007-06-18 22:44:57 +00:00
|
|
|
}
|
|
|
|
|
2007-06-04 06:47:22 +00:00
|
|
|
// If 'true' block has a 'false' successor, add an exit branch to it.
|
2007-06-05 01:31:40 +00:00
|
|
|
if (HasEarlyExit) {
|
2008-08-14 22:49:33 +00:00
|
|
|
SmallVector<MachineOperand, 4> RevCond(CvtBBI->BrCond.begin(),
|
|
|
|
CvtBBI->BrCond.end());
|
2007-06-01 07:41:07 +00:00
|
|
|
if (TII->ReverseBranchCondition(RevCond))
|
2012-02-05 08:31:47 +00:00
|
|
|
llvm_unreachable("Unable to reverse branch condition!");
|
2010-06-17 22:43:56 +00:00
|
|
|
TII->InsertBranch(*BBI.BB, CvtBBI->FalseBB, NULL, RevCond, dl);
|
2007-06-18 22:44:57 +00:00
|
|
|
BBI.BB->addSuccessor(CvtBBI->FalseBB);
|
2007-06-15 07:36:12 +00:00
|
|
|
}
|
2007-06-08 09:36:04 +00:00
|
|
|
|
|
|
|
// Merge in the 'false' block if the 'false' block has no other
|
2009-05-13 23:25:24 +00:00
|
|
|
// predecessors. Otherwise, add an unconditional branch to 'false'.
|
2007-06-05 00:07:37 +00:00
|
|
|
bool FalseBBDead = false;
|
2007-06-06 02:08:52 +00:00
|
|
|
bool IterIfcvt = true;
|
2007-06-09 01:03:43 +00:00
|
|
|
bool isFallThrough = canFallThroughTo(BBI.BB, NextBBI->BB);
|
2007-06-07 08:13:00 +00:00
|
|
|
if (!isFallThrough) {
|
|
|
|
// Only merge them if the true block does not fallthrough to the false
|
|
|
|
// block. By not merging them, we make it possible to iteratively
|
|
|
|
// ifcvt the blocks.
|
2007-06-18 08:37:25 +00:00
|
|
|
if (!HasEarlyExit &&
|
2013-05-05 18:03:49 +00:00
|
|
|
NextBBI->BB->pred_size() == 1 && !NextBBI->HasFallThrough &&
|
|
|
|
!NextBBI->BB->hasAddressTaken()) {
|
2007-06-09 01:03:43 +00:00
|
|
|
MergeBlocks(BBI, *NextBBI);
|
2007-06-07 08:13:00 +00:00
|
|
|
FalseBBDead = true;
|
|
|
|
} else {
|
2007-06-09 01:03:43 +00:00
|
|
|
InsertUncondBranch(BBI.BB, NextBBI->BB, TII);
|
|
|
|
BBI.HasFallThrough = false;
|
2007-06-07 08:13:00 +00:00
|
|
|
}
|
2007-06-08 09:36:04 +00:00
|
|
|
// Mixed predicated and unpredicated code. This cannot be iteratively
|
|
|
|
// predicated.
|
|
|
|
IterIfcvt = false;
|
2007-06-06 02:08:52 +00:00
|
|
|
}
|
2007-05-16 02:00:57 +00:00
|
|
|
|
2007-06-08 22:01:07 +00:00
|
|
|
RemoveExtraEdges(BBI);
|
2007-05-18 00:20:58 +00:00
|
|
|
|
2007-05-23 07:23:16 +00:00
|
|
|
// Update block info. BB can be iteratively if-converted.
|
2010-06-15 22:18:54 +00:00
|
|
|
if (!IterIfcvt)
|
2007-06-11 22:26:22 +00:00
|
|
|
BBI.IsDone = true;
|
2007-06-18 08:37:25 +00:00
|
|
|
InvalidatePreds(BBI.BB);
|
2007-06-11 22:26:22 +00:00
|
|
|
CvtBBI->IsDone = true;
|
2007-06-05 00:07:37 +00:00
|
|
|
if (FalseBBDead)
|
2007-06-11 22:26:22 +00:00
|
|
|
NextBBI->IsDone = true;
|
2007-05-16 02:00:57 +00:00
|
|
|
|
2007-05-21 22:22:58 +00:00
|
|
|
// FIXME: Must maintain LiveIns.
|
|
|
|
return true;
|
2007-05-16 02:00:57 +00:00
|
|
|
}
|
|
|
|
|
2007-05-16 21:54:37 +00:00
|
|
|
/// IfConvertDiamond - If convert a diamond sub-CFG.
|
|
|
|
///
|
2007-06-18 08:37:25 +00:00
|
|
|
bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
|
|
|
|
unsigned NumDups1, unsigned NumDups2) {
|
2007-06-04 06:47:22 +00:00
|
|
|
BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
|
2007-05-18 18:14:37 +00:00
|
|
|
BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
|
2007-06-16 09:34:52 +00:00
|
|
|
MachineBasicBlock *TailBB = TrueBBI.TrueBB;
|
2009-05-13 23:25:24 +00:00
|
|
|
// True block must fall through or end with an unanalyzable terminator.
|
2007-06-16 09:34:52 +00:00
|
|
|
if (!TailBB) {
|
2007-06-18 08:37:25 +00:00
|
|
|
if (blockAlwaysFallThrough(TrueBBI))
|
|
|
|
TailBB = FalseBBI.TrueBB;
|
|
|
|
assert((TailBB || !TrueBBI.IsBrAnalyzable) && "Unexpected!");
|
2007-05-21 22:22:58 +00:00
|
|
|
}
|
2007-05-16 02:00:57 +00:00
|
|
|
|
2007-06-18 08:37:25 +00:00
|
|
|
if (TrueBBI.IsDone || FalseBBI.IsDone ||
|
|
|
|
TrueBBI.BB->pred_size() > 1 ||
|
|
|
|
FalseBBI.BB->pred_size() > 1) {
|
|
|
|
// Something has changed. It's no longer safe to predicate these blocks.
|
|
|
|
BBI.IsAnalyzed = false;
|
|
|
|
TrueBBI.IsAnalyzed = false;
|
|
|
|
FalseBBI.IsAnalyzed = false;
|
|
|
|
return false;
|
2007-05-21 22:22:58 +00:00
|
|
|
}
|
2007-06-18 08:37:25 +00:00
|
|
|
|
2013-05-05 18:03:49 +00:00
|
|
|
if (TrueBBI.BB->hasAddressTaken() || FalseBBI.BB->hasAddressTaken())
|
|
|
|
// Conservatively abort if-conversion if either BB has its address taken.
|
|
|
|
return false;
|
|
|
|
|
Reapply my if-conversion cleanup from svn r106939 with fixes.
There are 2 changes relative to the previous version of the patch:
1) For the "simple" if-conversion case, there's no need to worry about
RemoveExtraEdges not handling an unanalyzable branch. Predicated terminators
are ignored in this context, so RemoveExtraEdges does the right thing.
This might break someday if we ever treat indirect branches (BRIND) as
predicable, but for now, I just removed this part of the patch, because
in the case where we do not add an unconditional branch, we rely on keeping
the fall-through edge to CvtBBI (which is empty after this transformation).
The change relative to the previous patch is:
@@ -1036,10 +1036,6 @@
IterIfcvt = false;
}
- // RemoveExtraEdges won't work if the block has an unanalyzable branch,
- // which is typically the case for IfConvertSimple, so explicitly remove
- // CvtBBI as a successor.
- BBI.BB->removeSuccessor(CvtBBI->BB);
RemoveExtraEdges(BBI);
// Update block info. BB can be iteratively if-converted.
2) My patch exposed a bug in the code for merging the tail of a "diamond",
which had previously never been exercised. The code was simply checking that
the tail had a single predecessor, but there was a case in
MultiSource/Benchmarks/VersaBench/dbms where that single predecessor was
neither edge of the diamond. I added the following change to check for
that:
@@ -1276,7 +1276,18 @@
// tail, add a unconditional branch to it.
if (TailBB) {
BBInfo TailBBI = BBAnalysis[TailBB->getNumber()];
- if (TailBB->pred_size() == 1 && !TailBBI.HasFallThrough) {
+ bool CanMergeTail = !TailBBI.HasFallThrough;
+ // There may still be a fall-through edge from BBI1 or BBI2 to TailBB;
+ // check if there are any other predecessors besides those.
+ unsigned NumPreds = TailBB->pred_size();
+ if (NumPreds > 1)
+ CanMergeTail = false;
+ else if (NumPreds == 1 && CanMergeTail) {
+ MachineBasicBlock::pred_iterator PI = TailBB->pred_begin();
+ if (*PI != BBI1->BB && *PI != BBI2->BB)
+ CanMergeTail = false;
+ }
+ if (CanMergeTail) {
MergeBlocks(BBI, TailBBI);
TailBBI.IsDone = true;
} else {
With these fixes, I was able to run all the SingleSource and MultiSource
tests successfully.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107110 91177308-0d34-0410-b5e6-96231b3b80d8
2010-06-29 00:55:23 +00:00
|
|
|
// Put the predicated instructions from the 'true' block before the
|
|
|
|
// instructions from the 'false' block, unless the true block would clobber
|
|
|
|
// the predicate, in which case, do the opposite.
|
2007-06-05 23:46:14 +00:00
|
|
|
BBInfo *BBI1 = &TrueBBI;
|
|
|
|
BBInfo *BBI2 = &FalseBBI;
|
2008-08-14 22:49:33 +00:00
|
|
|
SmallVector<MachineOperand, 4> RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
|
Optimized FCMP_OEQ and FCMP_UNE for x86.
Where previously LLVM might emit code like this:
ucomisd %xmm1, %xmm0
setne %al
setp %cl
orb %al, %cl
jne .LBB4_2
it now emits this:
ucomisd %xmm1, %xmm0
jne .LBB4_2
jp .LBB4_2
It has fewer instructions and uses fewer registers, but it does
have more branches. And in the case that this code is followed by
a non-fallthrough edge, it may be followed by a jmp instruction,
resulting in three branch instructions in sequence. Some effort
is made to avoid this situation.
To achieve this, X86ISelLowering.cpp now recognizes FCMP_OEQ and
FCMP_UNE in lowered form, and replace them with code that emits
two branches, except in the case where it would require converting
a fall-through edge to an explicit branch.
Also, X86InstrInfo.cpp's branch analysis and transform code now
knows now to handle blocks with multiple conditional branches. It
uses loops instead of having fixed checks for up to two
instructions. It can now analyze and transform code generated
from FCMP_OEQ and FCMP_UNE.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@57873 91177308-0d34-0410-b5e6-96231b3b80d8
2008-10-21 03:29:32 +00:00
|
|
|
if (TII->ReverseBranchCondition(RevCond))
|
2012-02-05 08:31:47 +00:00
|
|
|
llvm_unreachable("Unable to reverse branch condition!");
|
2008-08-14 22:49:33 +00:00
|
|
|
SmallVector<MachineOperand, 4> *Cond1 = &BBI.BrCond;
|
|
|
|
SmallVector<MachineOperand, 4> *Cond2 = &RevCond;
|
2007-06-16 09:34:52 +00:00
|
|
|
|
|
|
|
// Figure out the more profitable ordering.
|
|
|
|
bool DoSwap = false;
|
|
|
|
if (TrueBBI.ClobbersPred && !FalseBBI.ClobbersPred)
|
|
|
|
DoSwap = true;
|
|
|
|
else if (TrueBBI.ClobbersPred == FalseBBI.ClobbersPred) {
|
2007-06-18 22:44:57 +00:00
|
|
|
if (TrueBBI.NonPredSize > FalseBBI.NonPredSize)
|
2007-06-16 09:34:52 +00:00
|
|
|
DoSwap = true;
|
|
|
|
}
|
|
|
|
if (DoSwap) {
|
2007-06-06 00:57:55 +00:00
|
|
|
std::swap(BBI1, BBI2);
|
|
|
|
std::swap(Cond1, Cond2);
|
|
|
|
}
|
2007-06-05 23:46:14 +00:00
|
|
|
|
2007-06-18 08:37:25 +00:00
|
|
|
// Remove the conditional branch from entry to the blocks.
|
|
|
|
BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
|
|
|
|
|
2010-06-25 22:02:28 +00:00
|
|
|
// Initialize liveins to the first BB. These are potentially redefined by
|
2010-06-16 07:35:02 +00:00
|
|
|
// predicated instructions.
|
2013-10-14 20:45:17 +00:00
|
|
|
Redefs.init(TRI);
|
2013-10-14 20:45:09 +00:00
|
|
|
Redefs.addLiveIns(*(BBI1->BB), *TRI);
|
2010-06-16 07:35:02 +00:00
|
|
|
|
2007-06-18 08:37:25 +00:00
|
|
|
// Remove the duplicated instructions at the beginnings of both paths.
|
|
|
|
MachineBasicBlock::iterator DI1 = BBI1->BB->begin();
|
|
|
|
MachineBasicBlock::iterator DI2 = BBI2->BB->begin();
|
2010-06-14 21:30:32 +00:00
|
|
|
MachineBasicBlock::iterator DIE1 = BBI1->BB->end();
|
|
|
|
MachineBasicBlock::iterator DIE2 = BBI2->BB->end();
|
|
|
|
// Skip dbg_value instructions
|
|
|
|
while (DI1 != DIE1 && DI1->isDebugValue())
|
|
|
|
++DI1;
|
|
|
|
while (DI2 != DIE2 && DI2->isDebugValue())
|
|
|
|
++DI2;
|
2007-06-18 08:37:25 +00:00
|
|
|
BBI1->NonPredSize -= NumDups1;
|
|
|
|
BBI2->NonPredSize -= NumDups1;
|
2010-06-28 20:26:00 +00:00
|
|
|
|
|
|
|
// Skip past the dups on each side separately since there may be
|
|
|
|
// differing dbg_value entries.
|
|
|
|
for (unsigned i = 0; i < NumDups1; ++DI1) {
|
|
|
|
if (!DI1->isDebugValue())
|
|
|
|
++i;
|
|
|
|
}
|
2010-06-25 23:05:46 +00:00
|
|
|
while (NumDups1 != 0) {
|
2007-06-18 08:37:25 +00:00
|
|
|
++DI2;
|
2010-06-28 20:26:00 +00:00
|
|
|
if (!DI2->isDebugValue())
|
|
|
|
--NumDups1;
|
2007-06-18 08:37:25 +00:00
|
|
|
}
|
2010-06-16 07:35:02 +00:00
|
|
|
|
2013-10-11 19:04:37 +00:00
|
|
|
// Compute a set of registers which must not be killed by instructions in BB1:
|
|
|
|
// This is everything used+live in BB2 after the duplicated instructions. We
|
|
|
|
// can compute this set by simulating liveness backwards from the end of BB2.
|
2013-10-14 20:45:17 +00:00
|
|
|
DontKill.init(TRI);
|
2013-10-11 19:49:09 +00:00
|
|
|
for (MachineBasicBlock::reverse_iterator I = BBI2->BB->rbegin(),
|
|
|
|
E = MachineBasicBlock::reverse_iterator(DI2); I != E; ++I) {
|
2013-10-14 20:45:09 +00:00
|
|
|
DontKill.stepBackward(*I, *TRI);
|
2013-10-11 19:04:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (MachineBasicBlock::const_iterator I = BBI1->BB->begin(), E = DI1; I != E;
|
|
|
|
++I) {
|
2013-10-14 20:45:09 +00:00
|
|
|
Redefs.stepForward(*I, *TRI);
|
2013-10-11 19:04:37 +00:00
|
|
|
}
|
2007-06-18 08:37:25 +00:00
|
|
|
BBI.BB->splice(BBI.BB->end(), BBI1->BB, BBI1->BB->begin(), DI1);
|
|
|
|
BBI2->BB->erase(BBI2->BB->begin(), DI2);
|
|
|
|
|
Add a if-conversion optimization that allows 'true' side of a diamond to be
unpredicated. That is, turn
subeq r0, r1, #1
addne r0, r1, #1
into
sub r0, r1, #1
addne r0, r1, #1
For targets where conditional instructions are always executed, this may be
beneficial. It may remove pseudo anti-dependency in out-of-order execution
CPUs. e.g.
op r1, ...
str r1, [r10] ; end-of-life of r1 as div result
cmp r0, #65
movne r1, #44 ; raw dependency on previous r1
moveq r1, #12
If movne is unpredicated, then
op r1, ...
str r1, [r10]
cmp r0, #65
mov r1, #44 ; r1 written unconditionally
moveq r1, #12
Both mov and moveq are no longer depdendent on the first instruction. This gives
the out-of-order execution engine more freedom to reorder them.
This has passed entire LLVM test suite. But it has not been enabled for any ARM
variant pending more performance evaluation.
rdar://8951196
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146914 91177308-0d34-0410-b5e6-96231b3b80d8
2011-12-19 22:01:30 +00:00
|
|
|
// Remove branch from 'true' block and remove duplicated instructions.
|
2007-06-05 23:46:14 +00:00
|
|
|
BBI1->NonPredSize -= TII->RemoveBranch(*BBI1->BB);
|
2007-06-18 08:37:25 +00:00
|
|
|
DI1 = BBI1->BB->end();
|
2010-06-14 21:30:32 +00:00
|
|
|
for (unsigned i = 0; i != NumDups2; ) {
|
|
|
|
// NumDups2 only counted non-dbg_value instructions, so this won't
|
|
|
|
// run off the head of the list.
|
|
|
|
assert (DI1 != BBI1->BB->begin());
|
2007-06-18 08:37:25 +00:00
|
|
|
--DI1;
|
2010-06-14 21:30:32 +00:00
|
|
|
// skip dbg_value instructions
|
|
|
|
if (!DI1->isDebugValue())
|
|
|
|
++i;
|
|
|
|
}
|
2007-06-18 08:37:25 +00:00
|
|
|
BBI1->BB->erase(DI1, BBI1->BB->end());
|
2007-06-05 23:46:14 +00:00
|
|
|
|
2013-10-11 19:04:37 +00:00
|
|
|
// Kill flags in the true block for registers living into the false block
|
|
|
|
// must be removed.
|
|
|
|
RemoveKills(BBI1->BB->begin(), BBI1->BB->end(), DontKill, *TRI);
|
|
|
|
|
Add a if-conversion optimization that allows 'true' side of a diamond to be
unpredicated. That is, turn
subeq r0, r1, #1
addne r0, r1, #1
into
sub r0, r1, #1
addne r0, r1, #1
For targets where conditional instructions are always executed, this may be
beneficial. It may remove pseudo anti-dependency in out-of-order execution
CPUs. e.g.
op r1, ...
str r1, [r10] ; end-of-life of r1 as div result
cmp r0, #65
movne r1, #44 ; raw dependency on previous r1
moveq r1, #12
If movne is unpredicated, then
op r1, ...
str r1, [r10]
cmp r0, #65
mov r1, #44 ; r1 written unconditionally
moveq r1, #12
Both mov and moveq are no longer depdendent on the first instruction. This gives
the out-of-order execution engine more freedom to reorder them.
This has passed entire LLVM test suite. But it has not been enabled for any ARM
variant pending more performance evaluation.
rdar://8951196
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146914 91177308-0d34-0410-b5e6-96231b3b80d8
2011-12-19 22:01:30 +00:00
|
|
|
// Remove 'false' block branch and find the last instruction to predicate.
|
2007-06-18 08:37:25 +00:00
|
|
|
BBI2->NonPredSize -= TII->RemoveBranch(*BBI2->BB);
|
|
|
|
DI2 = BBI2->BB->end();
|
|
|
|
while (NumDups2 != 0) {
|
2010-06-14 21:30:32 +00:00
|
|
|
// NumDups2 only counted non-dbg_value instructions, so this won't
|
|
|
|
// run off the head of the list.
|
|
|
|
assert (DI2 != BBI2->BB->begin());
|
2007-06-18 08:37:25 +00:00
|
|
|
--DI2;
|
2010-06-14 21:30:32 +00:00
|
|
|
// skip dbg_value instructions
|
|
|
|
if (!DI2->isDebugValue())
|
|
|
|
--NumDups2;
|
2007-06-18 08:37:25 +00:00
|
|
|
}
|
Add a if-conversion optimization that allows 'true' side of a diamond to be
unpredicated. That is, turn
subeq r0, r1, #1
addne r0, r1, #1
into
sub r0, r1, #1
addne r0, r1, #1
For targets where conditional instructions are always executed, this may be
beneficial. It may remove pseudo anti-dependency in out-of-order execution
CPUs. e.g.
op r1, ...
str r1, [r10] ; end-of-life of r1 as div result
cmp r0, #65
movne r1, #44 ; raw dependency on previous r1
moveq r1, #12
If movne is unpredicated, then
op r1, ...
str r1, [r10]
cmp r0, #65
mov r1, #44 ; r1 written unconditionally
moveq r1, #12
Both mov and moveq are no longer depdendent on the first instruction. This gives
the out-of-order execution engine more freedom to reorder them.
This has passed entire LLVM test suite. But it has not been enabled for any ARM
variant pending more performance evaluation.
rdar://8951196
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146914 91177308-0d34-0410-b5e6-96231b3b80d8
2011-12-19 22:01:30 +00:00
|
|
|
|
|
|
|
// Remember which registers would later be defined by the false block.
|
|
|
|
// This allows us not to predicate instructions in the true block that would
|
|
|
|
// later be re-defined. That is, rather than
|
|
|
|
// subeq r0, r1, #1
|
|
|
|
// addne r0, r1, #1
|
|
|
|
// generate:
|
|
|
|
// sub r0, r1, #1
|
|
|
|
// addne r0, r1, #1
|
|
|
|
SmallSet<unsigned, 4> RedefsByFalse;
|
|
|
|
SmallSet<unsigned, 4> ExtUses;
|
|
|
|
if (TII->isProfitableToUnpredicate(*BBI1->BB, *BBI2->BB)) {
|
|
|
|
for (MachineBasicBlock::iterator FI = BBI2->BB->begin(); FI != DI2; ++FI) {
|
|
|
|
if (FI->isDebugValue())
|
|
|
|
continue;
|
|
|
|
SmallVector<unsigned, 4> Defs;
|
|
|
|
for (unsigned i = 0, e = FI->getNumOperands(); i != e; ++i) {
|
|
|
|
const MachineOperand &MO = FI->getOperand(i);
|
|
|
|
if (!MO.isReg())
|
|
|
|
continue;
|
|
|
|
unsigned Reg = MO.getReg();
|
|
|
|
if (!Reg)
|
|
|
|
continue;
|
|
|
|
if (MO.isDef()) {
|
|
|
|
Defs.push_back(Reg);
|
|
|
|
} else if (!RedefsByFalse.count(Reg)) {
|
|
|
|
// These are defined before ctrl flow reach the 'false' instructions.
|
|
|
|
// They cannot be modified by the 'true' instructions.
|
2013-05-22 23:17:36 +00:00
|
|
|
for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true);
|
|
|
|
SubRegs.isValid(); ++SubRegs)
|
2012-06-01 23:28:30 +00:00
|
|
|
ExtUses.insert(*SubRegs);
|
Add a if-conversion optimization that allows 'true' side of a diamond to be
unpredicated. That is, turn
subeq r0, r1, #1
addne r0, r1, #1
into
sub r0, r1, #1
addne r0, r1, #1
For targets where conditional instructions are always executed, this may be
beneficial. It may remove pseudo anti-dependency in out-of-order execution
CPUs. e.g.
op r1, ...
str r1, [r10] ; end-of-life of r1 as div result
cmp r0, #65
movne r1, #44 ; raw dependency on previous r1
moveq r1, #12
If movne is unpredicated, then
op r1, ...
str r1, [r10]
cmp r0, #65
mov r1, #44 ; r1 written unconditionally
moveq r1, #12
Both mov and moveq are no longer depdendent on the first instruction. This gives
the out-of-order execution engine more freedom to reorder them.
This has passed entire LLVM test suite. But it has not been enabled for any ARM
variant pending more performance evaluation.
rdar://8951196
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146914 91177308-0d34-0410-b5e6-96231b3b80d8
2011-12-19 22:01:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (unsigned i = 0, e = Defs.size(); i != e; ++i) {
|
|
|
|
unsigned Reg = Defs[i];
|
|
|
|
if (!ExtUses.count(Reg)) {
|
2013-05-22 23:17:36 +00:00
|
|
|
for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true);
|
|
|
|
SubRegs.isValid(); ++SubRegs)
|
2012-06-01 23:28:30 +00:00
|
|
|
RedefsByFalse.insert(*SubRegs);
|
Add a if-conversion optimization that allows 'true' side of a diamond to be
unpredicated. That is, turn
subeq r0, r1, #1
addne r0, r1, #1
into
sub r0, r1, #1
addne r0, r1, #1
For targets where conditional instructions are always executed, this may be
beneficial. It may remove pseudo anti-dependency in out-of-order execution
CPUs. e.g.
op r1, ...
str r1, [r10] ; end-of-life of r1 as div result
cmp r0, #65
movne r1, #44 ; raw dependency on previous r1
moveq r1, #12
If movne is unpredicated, then
op r1, ...
str r1, [r10]
cmp r0, #65
mov r1, #44 ; r1 written unconditionally
moveq r1, #12
Both mov and moveq are no longer depdendent on the first instruction. This gives
the out-of-order execution engine more freedom to reorder them.
This has passed entire LLVM test suite. But it has not been enabled for any ARM
variant pending more performance evaluation.
rdar://8951196
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146914 91177308-0d34-0410-b5e6-96231b3b80d8
2011-12-19 22:01:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Predicate the 'true' block.
|
2013-10-14 20:45:17 +00:00
|
|
|
PredicateBlock(*BBI1, BBI1->BB->end(), *Cond1, &RedefsByFalse);
|
Add a if-conversion optimization that allows 'true' side of a diamond to be
unpredicated. That is, turn
subeq r0, r1, #1
addne r0, r1, #1
into
sub r0, r1, #1
addne r0, r1, #1
For targets where conditional instructions are always executed, this may be
beneficial. It may remove pseudo anti-dependency in out-of-order execution
CPUs. e.g.
op r1, ...
str r1, [r10] ; end-of-life of r1 as div result
cmp r0, #65
movne r1, #44 ; raw dependency on previous r1
moveq r1, #12
If movne is unpredicated, then
op r1, ...
str r1, [r10]
cmp r0, #65
mov r1, #44 ; r1 written unconditionally
moveq r1, #12
Both mov and moveq are no longer depdendent on the first instruction. This gives
the out-of-order execution engine more freedom to reorder them.
This has passed entire LLVM test suite. But it has not been enabled for any ARM
variant pending more performance evaluation.
rdar://8951196
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146914 91177308-0d34-0410-b5e6-96231b3b80d8
2011-12-19 22:01:30 +00:00
|
|
|
|
|
|
|
// Predicate the 'false' block.
|
2013-10-14 20:45:17 +00:00
|
|
|
PredicateBlock(*BBI2, DI2, *Cond2);
|
2007-06-05 23:46:14 +00:00
|
|
|
|
2007-06-18 22:44:57 +00:00
|
|
|
// Merge the true block into the entry of the diamond.
|
Reapply my if-conversion cleanup from svn r106939 with fixes.
There are 2 changes relative to the previous version of the patch:
1) For the "simple" if-conversion case, there's no need to worry about
RemoveExtraEdges not handling an unanalyzable branch. Predicated terminators
are ignored in this context, so RemoveExtraEdges does the right thing.
This might break someday if we ever treat indirect branches (BRIND) as
predicable, but for now, I just removed this part of the patch, because
in the case where we do not add an unconditional branch, we rely on keeping
the fall-through edge to CvtBBI (which is empty after this transformation).
The change relative to the previous patch is:
@@ -1036,10 +1036,6 @@
IterIfcvt = false;
}
- // RemoveExtraEdges won't work if the block has an unanalyzable branch,
- // which is typically the case for IfConvertSimple, so explicitly remove
- // CvtBBI as a successor.
- BBI.BB->removeSuccessor(CvtBBI->BB);
RemoveExtraEdges(BBI);
// Update block info. BB can be iteratively if-converted.
2) My patch exposed a bug in the code for merging the tail of a "diamond",
which had previously never been exercised. The code was simply checking that
the tail had a single predecessor, but there was a case in
MultiSource/Benchmarks/VersaBench/dbms where that single predecessor was
neither edge of the diamond. I added the following change to check for
that:
@@ -1276,7 +1276,18 @@
// tail, add a unconditional branch to it.
if (TailBB) {
BBInfo TailBBI = BBAnalysis[TailBB->getNumber()];
- if (TailBB->pred_size() == 1 && !TailBBI.HasFallThrough) {
+ bool CanMergeTail = !TailBBI.HasFallThrough;
+ // There may still be a fall-through edge from BBI1 or BBI2 to TailBB;
+ // check if there are any other predecessors besides those.
+ unsigned NumPreds = TailBB->pred_size();
+ if (NumPreds > 1)
+ CanMergeTail = false;
+ else if (NumPreds == 1 && CanMergeTail) {
+ MachineBasicBlock::pred_iterator PI = TailBB->pred_begin();
+ if (*PI != BBI1->BB && *PI != BBI2->BB)
+ CanMergeTail = false;
+ }
+ if (CanMergeTail) {
MergeBlocks(BBI, TailBBI);
TailBBI.IsDone = true;
} else {
With these fixes, I was able to run all the SingleSource and MultiSource
tests successfully.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107110 91177308-0d34-0410-b5e6-96231b3b80d8
2010-06-29 00:55:23 +00:00
|
|
|
MergeBlocks(BBI, *BBI1, TailBB == 0);
|
|
|
|
MergeBlocks(BBI, *BBI2, TailBB == 0);
|
2007-06-06 00:57:55 +00:00
|
|
|
|
2009-05-13 23:25:24 +00:00
|
|
|
// If the if-converted block falls through or unconditionally branches into
|
|
|
|
// the tail block, and the tail block does not have other predecessors, then
|
2007-06-18 08:37:25 +00:00
|
|
|
// fold the tail block in as well. Otherwise, unless it falls through to the
|
|
|
|
// tail, add a unconditional branch to it.
|
|
|
|
if (TailBB) {
|
2011-11-04 23:49:14 +00:00
|
|
|
BBInfo &TailBBI = BBAnalysis[TailBB->getNumber()];
|
2013-05-05 18:03:49 +00:00
|
|
|
bool CanMergeTail = !TailBBI.HasFallThrough &&
|
|
|
|
!TailBBI.BB->hasAddressTaken();
|
Reapply my if-conversion cleanup from svn r106939 with fixes.
There are 2 changes relative to the previous version of the patch:
1) For the "simple" if-conversion case, there's no need to worry about
RemoveExtraEdges not handling an unanalyzable branch. Predicated terminators
are ignored in this context, so RemoveExtraEdges does the right thing.
This might break someday if we ever treat indirect branches (BRIND) as
predicable, but for now, I just removed this part of the patch, because
in the case where we do not add an unconditional branch, we rely on keeping
the fall-through edge to CvtBBI (which is empty after this transformation).
The change relative to the previous patch is:
@@ -1036,10 +1036,6 @@
IterIfcvt = false;
}
- // RemoveExtraEdges won't work if the block has an unanalyzable branch,
- // which is typically the case for IfConvertSimple, so explicitly remove
- // CvtBBI as a successor.
- BBI.BB->removeSuccessor(CvtBBI->BB);
RemoveExtraEdges(BBI);
// Update block info. BB can be iteratively if-converted.
2) My patch exposed a bug in the code for merging the tail of a "diamond",
which had previously never been exercised. The code was simply checking that
the tail had a single predecessor, but there was a case in
MultiSource/Benchmarks/VersaBench/dbms where that single predecessor was
neither edge of the diamond. I added the following change to check for
that:
@@ -1276,7 +1276,18 @@
// tail, add a unconditional branch to it.
if (TailBB) {
BBInfo TailBBI = BBAnalysis[TailBB->getNumber()];
- if (TailBB->pred_size() == 1 && !TailBBI.HasFallThrough) {
+ bool CanMergeTail = !TailBBI.HasFallThrough;
+ // There may still be a fall-through edge from BBI1 or BBI2 to TailBB;
+ // check if there are any other predecessors besides those.
+ unsigned NumPreds = TailBB->pred_size();
+ if (NumPreds > 1)
+ CanMergeTail = false;
+ else if (NumPreds == 1 && CanMergeTail) {
+ MachineBasicBlock::pred_iterator PI = TailBB->pred_begin();
+ if (*PI != BBI1->BB && *PI != BBI2->BB)
+ CanMergeTail = false;
+ }
+ if (CanMergeTail) {
MergeBlocks(BBI, TailBBI);
TailBBI.IsDone = true;
} else {
With these fixes, I was able to run all the SingleSource and MultiSource
tests successfully.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107110 91177308-0d34-0410-b5e6-96231b3b80d8
2010-06-29 00:55:23 +00:00
|
|
|
// There may still be a fall-through edge from BBI1 or BBI2 to TailBB;
|
|
|
|
// check if there are any other predecessors besides those.
|
|
|
|
unsigned NumPreds = TailBB->pred_size();
|
|
|
|
if (NumPreds > 1)
|
|
|
|
CanMergeTail = false;
|
|
|
|
else if (NumPreds == 1 && CanMergeTail) {
|
|
|
|
MachineBasicBlock::pred_iterator PI = TailBB->pred_begin();
|
|
|
|
if (*PI != BBI1->BB && *PI != BBI2->BB)
|
|
|
|
CanMergeTail = false;
|
|
|
|
}
|
|
|
|
if (CanMergeTail) {
|
2007-06-18 22:44:57 +00:00
|
|
|
MergeBlocks(BBI, TailBBI);
|
2007-06-18 08:37:25 +00:00
|
|
|
TailBBI.IsDone = true;
|
|
|
|
} else {
|
Reapply my if-conversion cleanup from svn r106939 with fixes.
There are 2 changes relative to the previous version of the patch:
1) For the "simple" if-conversion case, there's no need to worry about
RemoveExtraEdges not handling an unanalyzable branch. Predicated terminators
are ignored in this context, so RemoveExtraEdges does the right thing.
This might break someday if we ever treat indirect branches (BRIND) as
predicable, but for now, I just removed this part of the patch, because
in the case where we do not add an unconditional branch, we rely on keeping
the fall-through edge to CvtBBI (which is empty after this transformation).
The change relative to the previous patch is:
@@ -1036,10 +1036,6 @@
IterIfcvt = false;
}
- // RemoveExtraEdges won't work if the block has an unanalyzable branch,
- // which is typically the case for IfConvertSimple, so explicitly remove
- // CvtBBI as a successor.
- BBI.BB->removeSuccessor(CvtBBI->BB);
RemoveExtraEdges(BBI);
// Update block info. BB can be iteratively if-converted.
2) My patch exposed a bug in the code for merging the tail of a "diamond",
which had previously never been exercised. The code was simply checking that
the tail had a single predecessor, but there was a case in
MultiSource/Benchmarks/VersaBench/dbms where that single predecessor was
neither edge of the diamond. I added the following change to check for
that:
@@ -1276,7 +1276,18 @@
// tail, add a unconditional branch to it.
if (TailBB) {
BBInfo TailBBI = BBAnalysis[TailBB->getNumber()];
- if (TailBB->pred_size() == 1 && !TailBBI.HasFallThrough) {
+ bool CanMergeTail = !TailBBI.HasFallThrough;
+ // There may still be a fall-through edge from BBI1 or BBI2 to TailBB;
+ // check if there are any other predecessors besides those.
+ unsigned NumPreds = TailBB->pred_size();
+ if (NumPreds > 1)
+ CanMergeTail = false;
+ else if (NumPreds == 1 && CanMergeTail) {
+ MachineBasicBlock::pred_iterator PI = TailBB->pred_begin();
+ if (*PI != BBI1->BB && *PI != BBI2->BB)
+ CanMergeTail = false;
+ }
+ if (CanMergeTail) {
MergeBlocks(BBI, TailBBI);
TailBBI.IsDone = true;
} else {
With these fixes, I was able to run all the SingleSource and MultiSource
tests successfully.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107110 91177308-0d34-0410-b5e6-96231b3b80d8
2010-06-29 00:55:23 +00:00
|
|
|
BBI.BB->addSuccessor(TailBB);
|
2007-06-18 22:44:57 +00:00
|
|
|
InsertUncondBranch(BBI.BB, TailBB, TII);
|
|
|
|
BBI.HasFallThrough = false;
|
2007-06-18 08:37:25 +00:00
|
|
|
}
|
2007-05-21 22:22:58 +00:00
|
|
|
}
|
2007-05-18 00:20:58 +00:00
|
|
|
|
Reapply my if-conversion cleanup from svn r106939 with fixes.
There are 2 changes relative to the previous version of the patch:
1) For the "simple" if-conversion case, there's no need to worry about
RemoveExtraEdges not handling an unanalyzable branch. Predicated terminators
are ignored in this context, so RemoveExtraEdges does the right thing.
This might break someday if we ever treat indirect branches (BRIND) as
predicable, but for now, I just removed this part of the patch, because
in the case where we do not add an unconditional branch, we rely on keeping
the fall-through edge to CvtBBI (which is empty after this transformation).
The change relative to the previous patch is:
@@ -1036,10 +1036,6 @@
IterIfcvt = false;
}
- // RemoveExtraEdges won't work if the block has an unanalyzable branch,
- // which is typically the case for IfConvertSimple, so explicitly remove
- // CvtBBI as a successor.
- BBI.BB->removeSuccessor(CvtBBI->BB);
RemoveExtraEdges(BBI);
// Update block info. BB can be iteratively if-converted.
2) My patch exposed a bug in the code for merging the tail of a "diamond",
which had previously never been exercised. The code was simply checking that
the tail had a single predecessor, but there was a case in
MultiSource/Benchmarks/VersaBench/dbms where that single predecessor was
neither edge of the diamond. I added the following change to check for
that:
@@ -1276,7 +1276,18 @@
// tail, add a unconditional branch to it.
if (TailBB) {
BBInfo TailBBI = BBAnalysis[TailBB->getNumber()];
- if (TailBB->pred_size() == 1 && !TailBBI.HasFallThrough) {
+ bool CanMergeTail = !TailBBI.HasFallThrough;
+ // There may still be a fall-through edge from BBI1 or BBI2 to TailBB;
+ // check if there are any other predecessors besides those.
+ unsigned NumPreds = TailBB->pred_size();
+ if (NumPreds > 1)
+ CanMergeTail = false;
+ else if (NumPreds == 1 && CanMergeTail) {
+ MachineBasicBlock::pred_iterator PI = TailBB->pred_begin();
+ if (*PI != BBI1->BB && *PI != BBI2->BB)
+ CanMergeTail = false;
+ }
+ if (CanMergeTail) {
MergeBlocks(BBI, TailBBI);
TailBBI.IsDone = true;
} else {
With these fixes, I was able to run all the SingleSource and MultiSource
tests successfully.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107110 91177308-0d34-0410-b5e6-96231b3b80d8
2010-06-29 00:55:23 +00:00
|
|
|
// RemoveExtraEdges won't work if the block has an unanalyzable branch,
|
|
|
|
// which can happen here if TailBB is unanalyzable and is merged, so
|
|
|
|
// explicitly remove BBI1 and BBI2 as successors.
|
|
|
|
BBI.BB->removeSuccessor(BBI1->BB);
|
|
|
|
BBI.BB->removeSuccessor(BBI2->BB);
|
2007-06-08 22:01:07 +00:00
|
|
|
RemoveExtraEdges(BBI);
|
|
|
|
|
2007-06-05 23:46:14 +00:00
|
|
|
// Update block info.
|
2007-06-11 22:26:22 +00:00
|
|
|
BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone = true;
|
2007-06-18 08:37:25 +00:00
|
|
|
InvalidatePreds(BBI.BB);
|
2007-05-16 02:00:57 +00:00
|
|
|
|
2007-05-21 22:22:58 +00:00
|
|
|
// FIXME: Must maintain LiveIns.
|
|
|
|
return true;
|
2007-05-16 02:00:57 +00:00
|
|
|
}
|
|
|
|
|
Add a if-conversion optimization that allows 'true' side of a diamond to be
unpredicated. That is, turn
subeq r0, r1, #1
addne r0, r1, #1
into
sub r0, r1, #1
addne r0, r1, #1
For targets where conditional instructions are always executed, this may be
beneficial. It may remove pseudo anti-dependency in out-of-order execution
CPUs. e.g.
op r1, ...
str r1, [r10] ; end-of-life of r1 as div result
cmp r0, #65
movne r1, #44 ; raw dependency on previous r1
moveq r1, #12
If movne is unpredicated, then
op r1, ...
str r1, [r10]
cmp r0, #65
mov r1, #44 ; r1 written unconditionally
moveq r1, #12
Both mov and moveq are no longer depdendent on the first instruction. This gives
the out-of-order execution engine more freedom to reorder them.
This has passed entire LLVM test suite. But it has not been enabled for any ARM
variant pending more performance evaluation.
rdar://8951196
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146914 91177308-0d34-0410-b5e6-96231b3b80d8
2011-12-19 22:01:30 +00:00
|
|
|
static bool MaySpeculate(const MachineInstr *MI,
|
|
|
|
SmallSet<unsigned, 4> &LaterRedefs,
|
|
|
|
const TargetInstrInfo *TII) {
|
|
|
|
bool SawStore = true;
|
|
|
|
if (!MI->isSafeToMove(TII, 0, SawStore))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
|
|
|
const MachineOperand &MO = MI->getOperand(i);
|
|
|
|
if (!MO.isReg())
|
|
|
|
continue;
|
|
|
|
unsigned Reg = MO.getReg();
|
|
|
|
if (!Reg)
|
|
|
|
continue;
|
|
|
|
if (MO.isDef() && !LaterRedefs.count(Reg))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2007-06-18 08:37:25 +00:00
|
|
|
/// PredicateBlock - Predicate instructions from the start of the block to the
|
|
|
|
/// specified end with the specified condition.
|
2007-05-23 07:23:16 +00:00
|
|
|
void IfConverter::PredicateBlock(BBInfo &BBI,
|
2007-06-18 08:37:25 +00:00
|
|
|
MachineBasicBlock::iterator E,
|
2010-06-16 07:35:02 +00:00
|
|
|
SmallVectorImpl<MachineOperand> &Cond,
|
Add a if-conversion optimization that allows 'true' side of a diamond to be
unpredicated. That is, turn
subeq r0, r1, #1
addne r0, r1, #1
into
sub r0, r1, #1
addne r0, r1, #1
For targets where conditional instructions are always executed, this may be
beneficial. It may remove pseudo anti-dependency in out-of-order execution
CPUs. e.g.
op r1, ...
str r1, [r10] ; end-of-life of r1 as div result
cmp r0, #65
movne r1, #44 ; raw dependency on previous r1
moveq r1, #12
If movne is unpredicated, then
op r1, ...
str r1, [r10]
cmp r0, #65
mov r1, #44 ; r1 written unconditionally
moveq r1, #12
Both mov and moveq are no longer depdendent on the first instruction. This gives
the out-of-order execution engine more freedom to reorder them.
This has passed entire LLVM test suite. But it has not been enabled for any ARM
variant pending more performance evaluation.
rdar://8951196
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146914 91177308-0d34-0410-b5e6-96231b3b80d8
2011-12-19 22:01:30 +00:00
|
|
|
SmallSet<unsigned, 4> *LaterRedefs) {
|
|
|
|
bool AnyUnpred = false;
|
|
|
|
bool MaySpec = LaterRedefs != 0;
|
2007-06-18 08:37:25 +00:00
|
|
|
for (MachineBasicBlock::iterator I = BBI.BB->begin(); I != E; ++I) {
|
2010-06-04 23:01:26 +00:00
|
|
|
if (I->isDebugValue() || TII->isPredicated(I))
|
2007-05-16 02:00:57 +00:00
|
|
|
continue;
|
Add a if-conversion optimization that allows 'true' side of a diamond to be
unpredicated. That is, turn
subeq r0, r1, #1
addne r0, r1, #1
into
sub r0, r1, #1
addne r0, r1, #1
For targets where conditional instructions are always executed, this may be
beneficial. It may remove pseudo anti-dependency in out-of-order execution
CPUs. e.g.
op r1, ...
str r1, [r10] ; end-of-life of r1 as div result
cmp r0, #65
movne r1, #44 ; raw dependency on previous r1
moveq r1, #12
If movne is unpredicated, then
op r1, ...
str r1, [r10]
cmp r0, #65
mov r1, #44 ; r1 written unconditionally
moveq r1, #12
Both mov and moveq are no longer depdendent on the first instruction. This gives
the out-of-order execution engine more freedom to reorder them.
This has passed entire LLVM test suite. But it has not been enabled for any ARM
variant pending more performance evaluation.
rdar://8951196
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146914 91177308-0d34-0410-b5e6-96231b3b80d8
2011-12-19 22:01:30 +00:00
|
|
|
// It may be possible not to predicate an instruction if it's the 'true'
|
|
|
|
// side of a diamond and the 'false' side may re-define the instruction's
|
|
|
|
// defs.
|
|
|
|
if (MaySpec && MaySpeculate(I, *LaterRedefs, TII)) {
|
|
|
|
AnyUnpred = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// If any instruction is predicated, then every instruction after it must
|
|
|
|
// be predicated.
|
|
|
|
MaySpec = false;
|
2007-06-04 06:47:22 +00:00
|
|
|
if (!TII->PredicateInstruction(I, Cond)) {
|
2009-07-12 20:07:01 +00:00
|
|
|
#ifndef NDEBUG
|
2010-01-04 22:02:01 +00:00
|
|
|
dbgs() << "Unable to predicate " << *I << "!\n";
|
2009-07-12 20:07:01 +00:00
|
|
|
#endif
|
2009-07-14 16:55:14 +00:00
|
|
|
llvm_unreachable(0);
|
2007-05-16 21:54:37 +00:00
|
|
|
}
|
2010-06-16 07:35:02 +00:00
|
|
|
|
2010-06-19 05:33:57 +00:00
|
|
|
// If the predicated instruction now redefines a register as the result of
|
2010-06-16 07:35:02 +00:00
|
|
|
// if-conversion, add an implicit kill.
|
2013-10-11 19:04:37 +00:00
|
|
|
UpdatePredRedefs(I, Redefs, TRI);
|
2007-05-16 02:00:57 +00:00
|
|
|
}
|
2007-05-23 07:23:16 +00:00
|
|
|
|
2007-06-15 07:36:12 +00:00
|
|
|
std::copy(Cond.begin(), Cond.end(), std::back_inserter(BBI.Predicate));
|
|
|
|
|
2007-06-14 20:28:52 +00:00
|
|
|
BBI.IsAnalyzed = false;
|
2007-05-23 07:23:16 +00:00
|
|
|
BBI.NonPredSize = 0;
|
2007-06-08 19:17:12 +00:00
|
|
|
|
2010-06-22 15:08:57 +00:00
|
|
|
++NumIfConvBBs;
|
Add a if-conversion optimization that allows 'true' side of a diamond to be
unpredicated. That is, turn
subeq r0, r1, #1
addne r0, r1, #1
into
sub r0, r1, #1
addne r0, r1, #1
For targets where conditional instructions are always executed, this may be
beneficial. It may remove pseudo anti-dependency in out-of-order execution
CPUs. e.g.
op r1, ...
str r1, [r10] ; end-of-life of r1 as div result
cmp r0, #65
movne r1, #44 ; raw dependency on previous r1
moveq r1, #12
If movne is unpredicated, then
op r1, ...
str r1, [r10]
cmp r0, #65
mov r1, #44 ; r1 written unconditionally
moveq r1, #12
Both mov and moveq are no longer depdendent on the first instruction. This gives
the out-of-order execution engine more freedom to reorder them.
This has passed entire LLVM test suite. But it has not been enabled for any ARM
variant pending more performance evaluation.
rdar://8951196
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146914 91177308-0d34-0410-b5e6-96231b3b80d8
2011-12-19 22:01:30 +00:00
|
|
|
if (AnyUnpred)
|
|
|
|
++NumUnpred;
|
2007-06-04 06:47:22 +00:00
|
|
|
}
|
|
|
|
|
2007-06-15 07:36:12 +00:00
|
|
|
/// CopyAndPredicateBlock - Copy and predicate instructions from source BB to
|
|
|
|
/// the destination block. Skip end of block branches if IgnoreBr is true.
|
|
|
|
void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
|
2008-08-14 22:49:33 +00:00
|
|
|
SmallVectorImpl<MachineOperand> &Cond,
|
2007-06-15 07:36:12 +00:00
|
|
|
bool IgnoreBr) {
|
2008-07-07 23:14:23 +00:00
|
|
|
MachineFunction &MF = *ToBBI.BB->getParent();
|
|
|
|
|
2007-06-15 07:36:12 +00:00
|
|
|
for (MachineBasicBlock::iterator I = FromBBI.BB->begin(),
|
|
|
|
E = FromBBI.BB->end(); I != E; ++I) {
|
|
|
|
// Do not copy the end of the block branches.
|
2011-12-07 07:15:52 +00:00
|
|
|
if (IgnoreBr && I->isBranch())
|
2007-06-15 07:36:12 +00:00
|
|
|
break;
|
|
|
|
|
2008-07-07 23:14:23 +00:00
|
|
|
MachineInstr *MI = MF.CloneMachineInstr(I);
|
2007-06-15 07:36:12 +00:00
|
|
|
ToBBI.BB->insert(ToBBI.BB->end(), MI);
|
2010-10-26 00:02:21 +00:00
|
|
|
ToBBI.NonPredSize++;
|
2013-09-30 15:28:56 +00:00
|
|
|
unsigned ExtraPredCost = TII->getPredicationCost(&*I);
|
|
|
|
unsigned NumCycles = SchedModel.computeInstrLatency(&*I, false);
|
2010-11-03 00:45:17 +00:00
|
|
|
if (NumCycles > 1)
|
|
|
|
ToBBI.ExtraCost += NumCycles-1;
|
|
|
|
ToBBI.ExtraCost2 += ExtraPredCost;
|
2007-06-15 07:36:12 +00:00
|
|
|
|
Fix PR7372: Conditional branches (at least on ARM) are treated as predicated,
so when IfConverter::CopyAndPredicateBlock checks to see if it should ignore
an instruction because it is a branch, it should not check if the branch is
predicated.
This case (when IgnoreBr is true) is only relevant from IfConvertTriangle,
where new branches are inserted after the block has been copied and predicated.
If the original branch is not removed, we end up with multiple conditional
branches (possibly conflicting) at the end of the block. Aside from any
immediate errors resulting from that, this confuses the AnalyzeBranch functions
so that the branches are not analyzable. That in turn causes the IfConverter to
think that the "Simple" pattern can be applied, and things go downhill fast
because the "Simple" pattern does _not_ apply if the block can fall through.
This is pretty fragile. If there are other degenerate cases where AnalyzeBranch
fails, but where the block may still fall through, the IfConverter should not
perform its "Simple" if-conversion. But, I don't know how to do that with the
current AnalyzeBranch interface, so for now, the best thing seems to be to
avoid creating branches that AnalyzeBranch cannot handle.
Evan, please review!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@106291 91177308-0d34-0410-b5e6-96231b3b80d8
2010-06-18 17:07:23 +00:00
|
|
|
if (!TII->isPredicated(I) && !MI->isDebugValue()) {
|
2007-06-15 07:36:12 +00:00
|
|
|
if (!TII->PredicateInstruction(MI, Cond)) {
|
2009-07-12 20:07:01 +00:00
|
|
|
#ifndef NDEBUG
|
2010-01-04 22:02:01 +00:00
|
|
|
dbgs() << "Unable to predicate " << *I << "!\n";
|
2009-07-12 20:07:01 +00:00
|
|
|
#endif
|
2009-07-14 16:55:14 +00:00
|
|
|
llvm_unreachable(0);
|
2007-06-15 07:36:12 +00:00
|
|
|
}
|
2010-06-16 07:35:02 +00:00
|
|
|
}
|
|
|
|
|
2010-06-19 05:33:57 +00:00
|
|
|
// If the predicated instruction now redefines a register as the result of
|
2010-06-16 07:35:02 +00:00
|
|
|
// if-conversion, add an implicit kill.
|
2013-10-11 19:04:37 +00:00
|
|
|
UpdatePredRedefs(MI, Redefs, TRI);
|
|
|
|
|
|
|
|
// Some kill flags may not be correct anymore.
|
2013-10-14 20:45:17 +00:00
|
|
|
if (!DontKill.empty())
|
|
|
|
RemoveKills(*MI, DontKill, *TRI);
|
2007-06-15 07:36:12 +00:00
|
|
|
}
|
|
|
|
|
Reapply my if-conversion cleanup from svn r106939 with fixes.
There are 2 changes relative to the previous version of the patch:
1) For the "simple" if-conversion case, there's no need to worry about
RemoveExtraEdges not handling an unanalyzable branch. Predicated terminators
are ignored in this context, so RemoveExtraEdges does the right thing.
This might break someday if we ever treat indirect branches (BRIND) as
predicable, but for now, I just removed this part of the patch, because
in the case where we do not add an unconditional branch, we rely on keeping
the fall-through edge to CvtBBI (which is empty after this transformation).
The change relative to the previous patch is:
@@ -1036,10 +1036,6 @@
IterIfcvt = false;
}
- // RemoveExtraEdges won't work if the block has an unanalyzable branch,
- // which is typically the case for IfConvertSimple, so explicitly remove
- // CvtBBI as a successor.
- BBI.BB->removeSuccessor(CvtBBI->BB);
RemoveExtraEdges(BBI);
// Update block info. BB can be iteratively if-converted.
2) My patch exposed a bug in the code for merging the tail of a "diamond",
which had previously never been exercised. The code was simply checking that
the tail had a single predecessor, but there was a case in
MultiSource/Benchmarks/VersaBench/dbms where that single predecessor was
neither edge of the diamond. I added the following change to check for
that:
@@ -1276,7 +1276,18 @@
// tail, add a unconditional branch to it.
if (TailBB) {
BBInfo TailBBI = BBAnalysis[TailBB->getNumber()];
- if (TailBB->pred_size() == 1 && !TailBBI.HasFallThrough) {
+ bool CanMergeTail = !TailBBI.HasFallThrough;
+ // There may still be a fall-through edge from BBI1 or BBI2 to TailBB;
+ // check if there are any other predecessors besides those.
+ unsigned NumPreds = TailBB->pred_size();
+ if (NumPreds > 1)
+ CanMergeTail = false;
+ else if (NumPreds == 1 && CanMergeTail) {
+ MachineBasicBlock::pred_iterator PI = TailBB->pred_begin();
+ if (*PI != BBI1->BB && *PI != BBI2->BB)
+ CanMergeTail = false;
+ }
+ if (CanMergeTail) {
MergeBlocks(BBI, TailBBI);
TailBBI.IsDone = true;
} else {
With these fixes, I was able to run all the SingleSource and MultiSource
tests successfully.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107110 91177308-0d34-0410-b5e6-96231b3b80d8
2010-06-29 00:55:23 +00:00
|
|
|
if (!IgnoreBr) {
|
|
|
|
std::vector<MachineBasicBlock *> Succs(FromBBI.BB->succ_begin(),
|
|
|
|
FromBBI.BB->succ_end());
|
|
|
|
MachineBasicBlock *NBB = getNextBlock(FromBBI.BB);
|
|
|
|
MachineBasicBlock *FallThrough = FromBBI.HasFallThrough ? NBB : NULL;
|
2007-06-18 22:44:57 +00:00
|
|
|
|
Reapply my if-conversion cleanup from svn r106939 with fixes.
There are 2 changes relative to the previous version of the patch:
1) For the "simple" if-conversion case, there's no need to worry about
RemoveExtraEdges not handling an unanalyzable branch. Predicated terminators
are ignored in this context, so RemoveExtraEdges does the right thing.
This might break someday if we ever treat indirect branches (BRIND) as
predicable, but for now, I just removed this part of the patch, because
in the case where we do not add an unconditional branch, we rely on keeping
the fall-through edge to CvtBBI (which is empty after this transformation).
The change relative to the previous patch is:
@@ -1036,10 +1036,6 @@
IterIfcvt = false;
}
- // RemoveExtraEdges won't work if the block has an unanalyzable branch,
- // which is typically the case for IfConvertSimple, so explicitly remove
- // CvtBBI as a successor.
- BBI.BB->removeSuccessor(CvtBBI->BB);
RemoveExtraEdges(BBI);
// Update block info. BB can be iteratively if-converted.
2) My patch exposed a bug in the code for merging the tail of a "diamond",
which had previously never been exercised. The code was simply checking that
the tail had a single predecessor, but there was a case in
MultiSource/Benchmarks/VersaBench/dbms where that single predecessor was
neither edge of the diamond. I added the following change to check for
that:
@@ -1276,7 +1276,18 @@
// tail, add a unconditional branch to it.
if (TailBB) {
BBInfo TailBBI = BBAnalysis[TailBB->getNumber()];
- if (TailBB->pred_size() == 1 && !TailBBI.HasFallThrough) {
+ bool CanMergeTail = !TailBBI.HasFallThrough;
+ // There may still be a fall-through edge from BBI1 or BBI2 to TailBB;
+ // check if there are any other predecessors besides those.
+ unsigned NumPreds = TailBB->pred_size();
+ if (NumPreds > 1)
+ CanMergeTail = false;
+ else if (NumPreds == 1 && CanMergeTail) {
+ MachineBasicBlock::pred_iterator PI = TailBB->pred_begin();
+ if (*PI != BBI1->BB && *PI != BBI2->BB)
+ CanMergeTail = false;
+ }
+ if (CanMergeTail) {
MergeBlocks(BBI, TailBBI);
TailBBI.IsDone = true;
} else {
With these fixes, I was able to run all the SingleSource and MultiSource
tests successfully.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107110 91177308-0d34-0410-b5e6-96231b3b80d8
2010-06-29 00:55:23 +00:00
|
|
|
for (unsigned i = 0, e = Succs.size(); i != e; ++i) {
|
|
|
|
MachineBasicBlock *Succ = Succs[i];
|
|
|
|
// Fallthrough edge can't be transferred.
|
|
|
|
if (Succ == FallThrough)
|
|
|
|
continue;
|
|
|
|
ToBBI.BB->addSuccessor(Succ);
|
|
|
|
}
|
2007-06-18 22:44:57 +00:00
|
|
|
}
|
|
|
|
|
2007-06-15 07:36:12 +00:00
|
|
|
std::copy(FromBBI.Predicate.begin(), FromBBI.Predicate.end(),
|
|
|
|
std::back_inserter(ToBBI.Predicate));
|
|
|
|
std::copy(Cond.begin(), Cond.end(), std::back_inserter(ToBBI.Predicate));
|
|
|
|
|
|
|
|
ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
|
|
|
|
ToBBI.IsAnalyzed = false;
|
|
|
|
|
2010-06-22 15:08:57 +00:00
|
|
|
++NumDupBBs;
|
2007-06-15 07:36:12 +00:00
|
|
|
}
|
|
|
|
|
2007-05-18 00:20:58 +00:00
|
|
|
/// MergeBlocks - Move all instructions from FromBB to the end of ToBB.
|
Reapply my if-conversion cleanup from svn r106939 with fixes.
There are 2 changes relative to the previous version of the patch:
1) For the "simple" if-conversion case, there's no need to worry about
RemoveExtraEdges not handling an unanalyzable branch. Predicated terminators
are ignored in this context, so RemoveExtraEdges does the right thing.
This might break someday if we ever treat indirect branches (BRIND) as
predicable, but for now, I just removed this part of the patch, because
in the case where we do not add an unconditional branch, we rely on keeping
the fall-through edge to CvtBBI (which is empty after this transformation).
The change relative to the previous patch is:
@@ -1036,10 +1036,6 @@
IterIfcvt = false;
}
- // RemoveExtraEdges won't work if the block has an unanalyzable branch,
- // which is typically the case for IfConvertSimple, so explicitly remove
- // CvtBBI as a successor.
- BBI.BB->removeSuccessor(CvtBBI->BB);
RemoveExtraEdges(BBI);
// Update block info. BB can be iteratively if-converted.
2) My patch exposed a bug in the code for merging the tail of a "diamond",
which had previously never been exercised. The code was simply checking that
the tail had a single predecessor, but there was a case in
MultiSource/Benchmarks/VersaBench/dbms where that single predecessor was
neither edge of the diamond. I added the following change to check for
that:
@@ -1276,7 +1276,18 @@
// tail, add a unconditional branch to it.
if (TailBB) {
BBInfo TailBBI = BBAnalysis[TailBB->getNumber()];
- if (TailBB->pred_size() == 1 && !TailBBI.HasFallThrough) {
+ bool CanMergeTail = !TailBBI.HasFallThrough;
+ // There may still be a fall-through edge from BBI1 or BBI2 to TailBB;
+ // check if there are any other predecessors besides those.
+ unsigned NumPreds = TailBB->pred_size();
+ if (NumPreds > 1)
+ CanMergeTail = false;
+ else if (NumPreds == 1 && CanMergeTail) {
+ MachineBasicBlock::pred_iterator PI = TailBB->pred_begin();
+ if (*PI != BBI1->BB && *PI != BBI2->BB)
+ CanMergeTail = false;
+ }
+ if (CanMergeTail) {
MergeBlocks(BBI, TailBBI);
TailBBI.IsDone = true;
} else {
With these fixes, I was able to run all the SingleSource and MultiSource
tests successfully.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107110 91177308-0d34-0410-b5e6-96231b3b80d8
2010-06-29 00:55:23 +00:00
|
|
|
/// This will leave FromBB as an empty block, so remove all of its
|
|
|
|
/// successor edges except for the fall-through edge. If AddEdges is true,
|
|
|
|
/// i.e., when FromBBI's branch is being moved, add those successor edges to
|
|
|
|
/// ToBBI.
|
|
|
|
void IfConverter::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI, bool AddEdges) {
|
2013-05-05 18:03:49 +00:00
|
|
|
assert(!FromBBI.BB->hasAddressTaken() &&
|
|
|
|
"Removing a BB whose address is taken!");
|
|
|
|
|
2007-05-18 00:20:58 +00:00
|
|
|
ToBBI.BB->splice(ToBBI.BB->end(),
|
|
|
|
FromBBI.BB, FromBBI.BB->begin(), FromBBI.BB->end());
|
2007-05-23 07:23:16 +00:00
|
|
|
|
2007-06-07 02:12:15 +00:00
|
|
|
std::vector<MachineBasicBlock *> Succs(FromBBI.BB->succ_begin(),
|
|
|
|
FromBBI.BB->succ_end());
|
2007-06-08 22:01:07 +00:00
|
|
|
MachineBasicBlock *NBB = getNextBlock(FromBBI.BB);
|
2007-06-09 01:03:43 +00:00
|
|
|
MachineBasicBlock *FallThrough = FromBBI.HasFallThrough ? NBB : NULL;
|
2007-06-07 02:12:15 +00:00
|
|
|
|
|
|
|
for (unsigned i = 0, e = Succs.size(); i != e; ++i) {
|
|
|
|
MachineBasicBlock *Succ = Succs[i];
|
2007-06-08 22:01:07 +00:00
|
|
|
// Fallthrough edge can't be transferred.
|
2007-06-07 02:12:15 +00:00
|
|
|
if (Succ == FallThrough)
|
|
|
|
continue;
|
|
|
|
FromBBI.BB->removeSuccessor(Succ);
|
2013-01-24 23:59:08 +00:00
|
|
|
if (AddEdges && !ToBBI.BB->isSuccessor(Succ))
|
Reapply my if-conversion cleanup from svn r106939 with fixes.
There are 2 changes relative to the previous version of the patch:
1) For the "simple" if-conversion case, there's no need to worry about
RemoveExtraEdges not handling an unanalyzable branch. Predicated terminators
are ignored in this context, so RemoveExtraEdges does the right thing.
This might break someday if we ever treat indirect branches (BRIND) as
predicable, but for now, I just removed this part of the patch, because
in the case where we do not add an unconditional branch, we rely on keeping
the fall-through edge to CvtBBI (which is empty after this transformation).
The change relative to the previous patch is:
@@ -1036,10 +1036,6 @@
IterIfcvt = false;
}
- // RemoveExtraEdges won't work if the block has an unanalyzable branch,
- // which is typically the case for IfConvertSimple, so explicitly remove
- // CvtBBI as a successor.
- BBI.BB->removeSuccessor(CvtBBI->BB);
RemoveExtraEdges(BBI);
// Update block info. BB can be iteratively if-converted.
2) My patch exposed a bug in the code for merging the tail of a "diamond",
which had previously never been exercised. The code was simply checking that
the tail had a single predecessor, but there was a case in
MultiSource/Benchmarks/VersaBench/dbms where that single predecessor was
neither edge of the diamond. I added the following change to check for
that:
@@ -1276,7 +1276,18 @@
// tail, add a unconditional branch to it.
if (TailBB) {
BBInfo TailBBI = BBAnalysis[TailBB->getNumber()];
- if (TailBB->pred_size() == 1 && !TailBBI.HasFallThrough) {
+ bool CanMergeTail = !TailBBI.HasFallThrough;
+ // There may still be a fall-through edge from BBI1 or BBI2 to TailBB;
+ // check if there are any other predecessors besides those.
+ unsigned NumPreds = TailBB->pred_size();
+ if (NumPreds > 1)
+ CanMergeTail = false;
+ else if (NumPreds == 1 && CanMergeTail) {
+ MachineBasicBlock::pred_iterator PI = TailBB->pred_begin();
+ if (*PI != BBI1->BB && *PI != BBI2->BB)
+ CanMergeTail = false;
+ }
+ if (CanMergeTail) {
MergeBlocks(BBI, TailBBI);
TailBBI.IsDone = true;
} else {
With these fixes, I was able to run all the SingleSource and MultiSource
tests successfully.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107110 91177308-0d34-0410-b5e6-96231b3b80d8
2010-06-29 00:55:23 +00:00
|
|
|
ToBBI.BB->addSuccessor(Succ);
|
2007-06-07 02:12:15 +00:00
|
|
|
}
|
2007-06-04 06:47:22 +00:00
|
|
|
|
2009-05-13 23:25:24 +00:00
|
|
|
// Now FromBBI always falls through to the next block!
|
2009-05-13 23:48:58 +00:00
|
|
|
if (NBB && !FromBBI.BB->isSuccessor(NBB))
|
2007-06-08 22:01:07 +00:00
|
|
|
FromBBI.BB->addSuccessor(NBB);
|
|
|
|
|
2007-06-15 07:36:12 +00:00
|
|
|
std::copy(FromBBI.Predicate.begin(), FromBBI.Predicate.end(),
|
|
|
|
std::back_inserter(ToBBI.Predicate));
|
|
|
|
FromBBI.Predicate.clear();
|
|
|
|
|
2007-05-23 07:23:16 +00:00
|
|
|
ToBBI.NonPredSize += FromBBI.NonPredSize;
|
2010-10-26 00:02:21 +00:00
|
|
|
ToBBI.ExtraCost += FromBBI.ExtraCost;
|
2010-11-03 00:45:17 +00:00
|
|
|
ToBBI.ExtraCost2 += FromBBI.ExtraCost2;
|
2007-05-23 07:23:16 +00:00
|
|
|
FromBBI.NonPredSize = 0;
|
2010-10-26 00:02:21 +00:00
|
|
|
FromBBI.ExtraCost = 0;
|
2010-11-03 00:45:17 +00:00
|
|
|
FromBBI.ExtraCost2 = 0;
|
2007-06-06 10:16:17 +00:00
|
|
|
|
2007-06-11 22:26:22 +00:00
|
|
|
ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
|
2007-06-09 01:03:43 +00:00
|
|
|
ToBBI.HasFallThrough = FromBBI.HasFallThrough;
|
2007-06-14 20:28:52 +00:00
|
|
|
ToBBI.IsAnalyzed = false;
|
|
|
|
FromBBI.IsAnalyzed = false;
|
2007-05-16 02:00:57 +00:00
|
|
|
}
|