"llvm/lib/git@repo.hca.bsc.es:rferrer/llvm-epi-0.8.git" did not exist on "a618e13c8390040521e3bd55cfd072d3afd3f7d0"
Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
static void UpdatePredRedefs(MachineInstr *MI, SmallSet<unsigned,4> &Redefs,
const TargetRegisterInfo *TRI,
bool AddImpUse = false) {
SmallVector<unsigned, 4> Defs;
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())
Defs.push_back(Reg);
else if (MO.isKill()) {
Redefs.erase(Reg);
for (const unsigned *SR = TRI->getSubRegisters(Reg); *SR; ++SR)
Redefs.erase(*SR);
}
}
for (unsigned i = 0, e = Defs.size(); i != e; ++i) {
unsigned Reg = Defs[i];
if (Redefs.count(Reg)) {
if (AddImpUse)
// Treat predicated update as read + write.
MI->addOperand(MachineOperand::CreateReg(Reg, false/*IsDef*/,
} else {
Redefs.insert(Reg);
for (const unsigned *SR = TRI->getSubRegisters(Reg); *SR; ++SR)
Redefs.insert(*SR);
}
}
}
static void UpdatePredRedefs(MachineBasicBlock::iterator I,
MachineBasicBlock::iterator E,
SmallSet<unsigned,4> &Redefs,
const TargetRegisterInfo *TRI) {
while (I != E) {
UpdatePredRedefs(I, Redefs, TRI);
++I;
}
}
/// IfConvertSimple - If convert a simple (split, no rejoin) sub-CFG.
bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) {
BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
BBInfo *CvtBBI = &TrueBBI;
BBInfo *NextBBI = &FalseBBI;
Owen Anderson
committed
SmallVector<MachineOperand, 4> Cond(BBI.BrCond.begin(), BBI.BrCond.end());
Evan Cheng
committed
if (CvtBBI->IsDone ||
(CvtBBI->CannotBeCopied && CvtBBI->BB->pred_size() > 1)) {
// Something has changed. It's no longer safe to predicate this block.
BBI.IsAnalyzed = false;
CvtBBI->IsAnalyzed = false;
return false;
if (TII->ReverseBranchCondition(Cond))
assert(false && "Unable to reverse branch condition!");
// Initialize liveins to the first BB. These are potentiall redefined by
// predicated instructions.
SmallSet<unsigned, 4> Redefs;
InitPredRedefs(CvtBBI->BB, Redefs, TRI);
InitPredRedefs(NextBBI->BB, Redefs, TRI);
if (CvtBBI->BB->pred_size() > 1) {
BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
// Copy instructions in the true block, predicate them, and add them to
// the entry block.
CopyAndPredicateBlock(BBI, *CvtBBI, Cond, Redefs);
PredicateBlock(*CvtBBI, CvtBBI->BB->end(), Cond, Redefs);
// Merge converted block into entry block.
BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
MergeBlocks(BBI, *CvtBBI);
}
Evan Cheng
committed
bool IterIfcvt = true;
if (!canFallThroughTo(BBI.BB, NextBBI->BB)) {
Evan Cheng
committed
InsertUncondBranch(BBI.BB, NextBBI->BB, TII);
Evan Cheng
committed
BBI.HasFallThrough = false;
// 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;
Evan Cheng
committed
}
RemoveExtraEdges(BBI);
// Update block info. BB can be iteratively if-converted.
if (!IterIfcvt)
BBI.IsDone = true;
Evan Cheng
committed
InvalidatePreds(BBI.BB);
CvtBBI->IsDone = true;
// FIXME: Must maintain LiveIns.
return true;
}
/// IfConvertTriangle - If convert a triangle sub-CFG.
///
bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
Evan Cheng
committed
BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
BBInfo *CvtBBI = &TrueBBI;
BBInfo *NextBBI = &FalseBBI;
DebugLoc dl; // FIXME: this is nowhere
Evan Cheng
committed
Owen Anderson
committed
SmallVector<MachineOperand, 4> Cond(BBI.BrCond.begin(), BBI.BrCond.end());
if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
Evan Cheng
committed
std::swap(CvtBBI, NextBBI);
Evan Cheng
committed
if (CvtBBI->IsDone ||
(CvtBBI->CannotBeCopied && CvtBBI->BB->pred_size() > 1)) {
// Something has changed. It's no longer safe to predicate this block.
BBI.IsAnalyzed = false;
CvtBBI->IsAnalyzed = false;
return false;
Evan Cheng
committed
}
if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
if (TII->ReverseBranchCondition(Cond))
assert(false && "Unable to reverse branch condition!");
if (Kind == ICTriangleRev || Kind == ICTriangleFRev) {
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;
}
// Initialize liveins to the first BB. These are potentially redefined by
// predicated instructions.
SmallSet<unsigned, 4> Redefs;
InitPredRedefs(CvtBBI->BB, Redefs, TRI);
InitPredRedefs(NextBBI->BB, Redefs, TRI);
bool HasEarlyExit = CvtBBI->FalseBB != NULL;
if (CvtBBI->BB->pred_size() > 1) {
BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
// Copy instructions in the true block, predicate them, and add them to
// the entry block.
CopyAndPredicateBlock(BBI, *CvtBBI, Cond, Redefs, true);
} else {
// Predicate the 'true' block after removing its branch.
CvtBBI->NonPredSize -= TII->RemoveBranch(*CvtBBI->BB);
PredicateBlock(*CvtBBI, CvtBBI->BB->end(), Cond, Redefs);
// Now merge the entry of the triangle with the true block.
BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
MergeBlocks(BBI, *CvtBBI, false);
// If 'true' block has a 'false' successor, add an exit branch to it.
Evan Cheng
committed
if (HasEarlyExit) {
Owen Anderson
committed
SmallVector<MachineOperand, 4> RevCond(CvtBBI->BrCond.begin(),
CvtBBI->BrCond.end());
if (TII->ReverseBranchCondition(RevCond))
assert(false && "Unable to reverse branch condition!");
TII->InsertBranch(*BBI.BB, CvtBBI->FalseBB, NULL, RevCond, dl);
BBI.BB->addSuccessor(CvtBBI->FalseBB);
// Merge in the 'false' block if the 'false' block has no other
// predecessors. Otherwise, add an unconditional branch to 'false'.
Evan Cheng
committed
bool FalseBBDead = false;
Evan Cheng
committed
bool IterIfcvt = true;
Evan Cheng
committed
bool isFallThrough = canFallThroughTo(BBI.BB, NextBBI->BB);
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.
Evan Cheng
committed
if (!HasEarlyExit &&
NextBBI->BB->pred_size() == 1 && !NextBBI->HasFallThrough) {
Evan Cheng
committed
MergeBlocks(BBI, *NextBBI);
FalseBBDead = true;
} else {
Evan Cheng
committed
InsertUncondBranch(BBI.BB, NextBBI->BB, TII);
BBI.HasFallThrough = false;
}
// Mixed predicated and unpredicated code. This cannot be iteratively
// predicated.
IterIfcvt = false;
Evan Cheng
committed
}
RemoveExtraEdges(BBI);
// Update block info. BB can be iteratively if-converted.
if (!IterIfcvt)
Evan Cheng
committed
InvalidatePreds(BBI.BB);
CvtBBI->IsDone = true;
Evan Cheng
committed
if (FalseBBDead)
NextBBI->IsDone = true;
// FIXME: Must maintain LiveIns.
return true;
/// IfConvertDiamond - If convert a diamond sub-CFG.
///
Evan Cheng
committed
bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
unsigned NumDups1, unsigned NumDups2) {
BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
MachineBasicBlock *TailBB = TrueBBI.TrueBB;
// True block must fall through or end with an unanalyzable terminator.
Evan Cheng
committed
if (blockAlwaysFallThrough(TrueBBI))
TailBB = FalseBBI.TrueBB;
assert((TailBB || !TrueBBI.IsBrAnalyzable) && "Unexpected!");
Evan Cheng
committed
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;
Evan Cheng
committed
// 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.
BBInfo *BBI1 = &TrueBBI;
BBInfo *BBI2 = &FalseBBI;
Owen Anderson
committed
SmallVector<MachineOperand, 4> RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
if (TII->ReverseBranchCondition(RevCond))
assert(false && "Unable to reverse branch condition!");
Owen Anderson
committed
SmallVector<MachineOperand, 4> *Cond1 = &BBI.BrCond;
SmallVector<MachineOperand, 4> *Cond2 = &RevCond;
// Figure out the more profitable ordering.
bool DoSwap = false;
if (TrueBBI.ClobbersPred && !FalseBBI.ClobbersPred)
DoSwap = true;
else if (TrueBBI.ClobbersPred == FalseBBI.ClobbersPred) {
if (TrueBBI.NonPredSize > FalseBBI.NonPredSize)
Evan Cheng
committed
std::swap(BBI1, BBI2);
std::swap(Cond1, Cond2);
}
Evan Cheng
committed
// Remove the conditional branch from entry to the blocks.
BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
// Initialize liveins to the first BB. These are potentially redefined by
// predicated instructions.
SmallSet<unsigned, 4> Redefs;
InitPredRedefs(BBI1->BB, Redefs, TRI);
Evan Cheng
committed
// Remove the duplicated instructions at the beginnings of both paths.
MachineBasicBlock::iterator DI1 = BBI1->BB->begin();
MachineBasicBlock::iterator DI2 = BBI2->BB->begin();
Jim Grosbach
committed
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;
Evan Cheng
committed
BBI1->NonPredSize -= NumDups1;
BBI2->NonPredSize -= NumDups1;
// 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;
}
while (NumDups1 != 0) {
Evan Cheng
committed
++DI2;
if (!DI2->isDebugValue())
--NumDups1;
Evan Cheng
committed
}
UpdatePredRedefs(BBI1->BB->begin(), DI1, Redefs, TRI);
Evan Cheng
committed
BBI.BB->splice(BBI.BB->end(), BBI1->BB, BBI1->BB->begin(), DI1);
BBI2->BB->erase(BBI2->BB->begin(), DI2);
// Predicate the 'true' block after removing its branch.
BBI1->NonPredSize -= TII->RemoveBranch(*BBI1->BB);
Evan Cheng
committed
DI1 = BBI1->BB->end();
Jim Grosbach
committed
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());
Evan Cheng
committed
--DI1;
Jim Grosbach
committed
// skip dbg_value instructions
if (!DI1->isDebugValue())
++i;
}
Evan Cheng
committed
BBI1->BB->erase(DI1, BBI1->BB->end());
PredicateBlock(*BBI1, BBI1->BB->end(), *Cond1, Redefs);
Evan Cheng
committed
BBI2->NonPredSize -= TII->RemoveBranch(*BBI2->BB);
DI2 = BBI2->BB->end();
while (NumDups2 != 0) {
Jim Grosbach
committed
// NumDups2 only counted non-dbg_value instructions, so this won't
// run off the head of the list.
assert (DI2 != BBI2->BB->begin());
Evan Cheng
committed
--DI2;
Jim Grosbach
committed
// skip dbg_value instructions
if (!DI2->isDebugValue())
--NumDups2;
Evan Cheng
committed
}
PredicateBlock(*BBI2, DI2, *Cond2, Redefs);
// Merge the true block into the entry of the diamond.
MergeBlocks(BBI, *BBI1, TailBB == 0);
MergeBlocks(BBI, *BBI2, TailBB == 0);
Evan Cheng
committed
// If the if-converted block falls through or unconditionally branches into
// the tail block, and the tail block does not have other predecessors, then
Evan Cheng
committed
// fold the tail block in as well. Otherwise, unless it falls through to the
// tail, add a unconditional branch to it.
if (TailBB) {
BBInfo TailBBI = BBAnalysis[TailBB->getNumber()];
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) {
Evan Cheng
committed
TailBBI.IsDone = true;
} else {
BBI.BB->addSuccessor(TailBB);
InsertUncondBranch(BBI.BB, TailBB, TII);
BBI.HasFallThrough = false;
Evan Cheng
committed
}
// 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);
RemoveExtraEdges(BBI);
BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone = true;
Evan Cheng
committed
InvalidatePreds(BBI.BB);
// FIXME: Must maintain LiveIns.
return true;
Evan Cheng
committed
/// PredicateBlock - Predicate instructions from the start of the block to the
/// specified end with the specified condition.
void IfConverter::PredicateBlock(BBInfo &BBI,
Evan Cheng
committed
MachineBasicBlock::iterator E,
SmallVectorImpl<MachineOperand> &Cond,
SmallSet<unsigned, 4> &Redefs) {
Evan Cheng
committed
for (MachineBasicBlock::iterator I = BBI.BB->begin(); I != E; ++I) {
Jim Grosbach
committed
if (I->isDebugValue() || TII->isPredicated(I))
if (!TII->PredicateInstruction(I, Cond)) {
llvm_unreachable(0);
// If the predicated instruction now redefines a register as the result of
// if-conversion, add an implicit kill.
UpdatePredRedefs(I, Redefs, TRI, true);
std::copy(Cond.begin(), Cond.end(), std::back_inserter(BBI.Predicate));
BBI.IsAnalyzed = false;
++NumIfConvBBs;
}
/// 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,
Owen Anderson
committed
SmallVectorImpl<MachineOperand> &Cond,
SmallSet<unsigned, 4> &Redefs,
bool IgnoreBr) {
MachineFunction &MF = *ToBBI.BB->getParent();
for (MachineBasicBlock::iterator I = FromBBI.BB->begin(),
E = FromBBI.BB->end(); I != E; ++I) {
const TargetInstrDesc &TID = I->getDesc();
// Do not copy the end of the block branches.
if (IgnoreBr && TID.isBranch())
MachineInstr *MI = MF.CloneMachineInstr(I);
ToBBI.BB->insert(ToBBI.BB->end(), MI);
ToBBI.NonPredSize++;
unsigned NumOps = TII->getNumMicroOps(MI, InstrItins);
if (NumOps > 1)
ToBBI.ExtraCost += NumOps-1;
if (!TII->isPredicated(I) && !MI->isDebugValue()) {
if (!TII->PredicateInstruction(MI, Cond)) {
llvm_unreachable(0);
}
// If the predicated instruction now redefines a register as the result of
// if-conversion, add an implicit kill.
UpdatePredRedefs(MI, Redefs, TRI, true);
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;
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);
}
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;
++NumDupBBs;
/// MergeBlocks - Move all instructions from FromBB to the end of ToBB.
/// 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) {
ToBBI.BB->splice(ToBBI.BB->end(),
FromBBI.BB, FromBBI.BB->begin(), FromBBI.BB->end());
std::vector<MachineBasicBlock *> Succs(FromBBI.BB->succ_begin(),
FromBBI.BB->succ_end());
MachineBasicBlock *NBB = getNextBlock(FromBBI.BB);
Evan Cheng
committed
MachineBasicBlock *FallThrough = FromBBI.HasFallThrough ? NBB : NULL;
for (unsigned i = 0, e = Succs.size(); i != e; ++i) {
MachineBasicBlock *Succ = Succs[i];
// Fallthrough edge can't be transferred.
if (Succ == FallThrough)
continue;
FromBBI.BB->removeSuccessor(Succ);
if (AddEdges)
ToBBI.BB->addSuccessor(Succ);
// Now FromBBI always falls through to the next block!
if (NBB && !FromBBI.BB->isSuccessor(NBB))
FromBBI.BB->addSuccessor(NBB);
std::copy(FromBBI.Predicate.begin(), FromBBI.Predicate.end(),
std::back_inserter(ToBBI.Predicate));
FromBBI.Predicate.clear();
ToBBI.NonPredSize += FromBBI.NonPredSize;
ToBBI.ExtraCost += FromBBI.ExtraCost;
FromBBI.ExtraCost = 0;
ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
Evan Cheng
committed
ToBBI.HasFallThrough = FromBBI.HasFallThrough;
ToBBI.IsAnalyzed = false;
FromBBI.IsAnalyzed = false;