Newer
Older
Evan Cheng
committed
// tail block, and the tail block does not have other predecessors, then
// fold the tail block in as well.
Evan Cheng
committed
if (BBI.TailBB &&
BBI.TailBB->pred_size() == 1 && CvtBBI->BB->succ_size() == 1) {
CvtBBI->NonPredSize -= TII->RemoveBranch(*CvtBBI->BB);
BBInfo TailBBI = BBAnalysis[BBI.TailBB->getNumber()];
MergeBlocks(*CvtBBI, TailBBI);
TailBBI.IsDone = true;
RemoveExtraEdges(BBI);
BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone = true;
// FIXME: Must maintain LiveIns.
return true;
}
/// PredicateBlock - Predicate every instruction in the block with the specified
/// condition. If IgnoreTerm is true, skip over all terminator instructions.
void IfConverter::PredicateBlock(BBInfo &BBI,
std::vector<MachineOperand> &Cond,
bool IgnoreTerm) {
for (MachineBasicBlock::iterator I = BBI.BB->begin(), E = BBI.BB->end();
if (IgnoreTerm && TII->isTerminatorInstr(I->getOpcode()))
if (TII->isPredicated(I))
if (!TII->PredicateInstruction(I, Cond)) {
cerr << "Unable to predicate " << *I << "!\n";
abort();
}
std::copy(Cond.begin(), Cond.end(), std::back_inserter(BBI.Predicate));
BBI.IsAnalyzed = false;
NumIfConvBBs++;
}
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
/// CopyAndPredicateBlock - Copy and predicate instructions from source BB to
/// the destination block. Skip end of block branches if IgnoreBr is true.
void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
std::vector<MachineOperand> &Cond,
bool IgnoreBr) {
for (MachineBasicBlock::iterator I = FromBBI.BB->begin(),
E = FromBBI.BB->end(); I != E; ++I) {
const TargetInstrDescriptor *TID = I->getInstrDescriptor();
bool isPredicated = TII->isPredicated(I);
// Do not copy the end of the block branches.
if (IgnoreBr && !isPredicated && (TID->Flags & M_BRANCH_FLAG) != 0)
break;
MachineInstr *MI = I->clone();
ToBBI.BB->insert(ToBBI.BB->end(), MI);
ToBBI.NonPredSize++;
if (!isPredicated)
if (!TII->PredicateInstruction(MI, Cond)) {
cerr << "Unable to predicate " << *MI << "!\n";
abort();
}
}
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.
void IfConverter::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI) {
ToBBI.BB->splice(ToBBI.BB->end(),
FromBBI.BB, FromBBI.BB->begin(), FromBBI.BB->end());
// Redirect all branches to FromBB to ToBB.
std::vector<MachineBasicBlock *> Preds(FromBBI.BB->pred_begin(),
FromBBI.BB->pred_end());
for (unsigned i = 0, e = Preds.size(); i != e; ++i) {
MachineBasicBlock *Pred = Preds[i];
if (Pred == ToBBI.BB)
continue;
Pred->ReplaceUsesOfBlockWith(FromBBI.BB, ToBBI.BB);
}
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 (!ToBBI.BB->isSuccessor(Succ))
ToBBI.BB->addSuccessor(Succ);
}
// Now FromBBI always fall through to the next block!
if (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;
FromBBI.NonPredSize = 0;
ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
Evan Cheng
committed
ToBBI.HasFallThrough = FromBBI.HasFallThrough;
ToBBI.IsAnalyzed = false;
FromBBI.IsAnalyzed = false;