mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-25 13:24:46 +00:00
Run branch folding if if-converter make some transformations.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80994 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "branchfolding"
|
||||
#include "BranchFolding.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
@@ -46,64 +47,28 @@ TailMergeThreshold("tail-merge-threshold",
|
||||
cl::desc("Max number of predecessors to consider tail merging"),
|
||||
cl::init(150), cl::Hidden);
|
||||
|
||||
namespace {
|
||||
struct VISIBILITY_HIDDEN BranchFolder : public MachineFunctionPass {
|
||||
static char ID;
|
||||
explicit BranchFolder(bool defaultEnableTailMerge) :
|
||||
MachineFunctionPass(&ID) {
|
||||
switch (FlagEnableTailMerge) {
|
||||
case cl::BOU_UNSET: EnableTailMerge = defaultEnableTailMerge; break;
|
||||
case cl::BOU_TRUE: EnableTailMerge = true; break;
|
||||
case cl::BOU_FALSE: EnableTailMerge = false; break;
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool runOnMachineFunction(MachineFunction &MF);
|
||||
virtual const char *getPassName() const { return "Control Flow Optimizer"; }
|
||||
const TargetInstrInfo *TII;
|
||||
MachineModuleInfo *MMI;
|
||||
bool MadeChange;
|
||||
private:
|
||||
// Tail Merging.
|
||||
bool EnableTailMerge;
|
||||
bool TailMergeBlocks(MachineFunction &MF);
|
||||
bool TryMergeBlocks(MachineBasicBlock* SuccBB,
|
||||
MachineBasicBlock* PredBB);
|
||||
void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst,
|
||||
MachineBasicBlock *NewDest);
|
||||
MachineBasicBlock *SplitMBBAt(MachineBasicBlock &CurMBB,
|
||||
MachineBasicBlock::iterator BBI1);
|
||||
unsigned ComputeSameTails(unsigned CurHash, unsigned minCommonTailLength);
|
||||
void RemoveBlocksWithHash(unsigned CurHash, MachineBasicBlock* SuccBB,
|
||||
MachineBasicBlock* PredBB);
|
||||
unsigned CreateCommonTailOnlyBlock(MachineBasicBlock *&PredBB,
|
||||
unsigned maxCommonTailLength);
|
||||
|
||||
typedef std::pair<unsigned,MachineBasicBlock*> MergePotentialsElt;
|
||||
typedef std::vector<MergePotentialsElt>::iterator MPIterator;
|
||||
std::vector<MergePotentialsElt> MergePotentials;
|
||||
|
||||
typedef std::pair<MPIterator, MachineBasicBlock::iterator> SameTailElt;
|
||||
std::vector<SameTailElt> SameTails;
|
||||
|
||||
const TargetRegisterInfo *RegInfo;
|
||||
RegScavenger *RS;
|
||||
// Branch optzn.
|
||||
bool OptimizeBranches(MachineFunction &MF);
|
||||
void OptimizeBlock(MachineBasicBlock *MBB);
|
||||
void RemoveDeadBlock(MachineBasicBlock *MBB);
|
||||
bool OptimizeImpDefsBlock(MachineBasicBlock *MBB);
|
||||
|
||||
bool CanFallThrough(MachineBasicBlock *CurBB);
|
||||
bool CanFallThrough(MachineBasicBlock *CurBB, bool BranchUnAnalyzable,
|
||||
MachineBasicBlock *TBB, MachineBasicBlock *FBB,
|
||||
const SmallVectorImpl<MachineOperand> &Cond);
|
||||
};
|
||||
char BranchFolder::ID = 0;
|
||||
}
|
||||
char BranchFolderPass::ID = 0;
|
||||
|
||||
FunctionPass *llvm::createBranchFoldingPass(bool DefaultEnableTailMerge) {
|
||||
return new BranchFolder(DefaultEnableTailMerge);
|
||||
return new BranchFolderPass(DefaultEnableTailMerge);
|
||||
}
|
||||
|
||||
bool BranchFolderPass::runOnMachineFunction(MachineFunction &MF) {
|
||||
return OptimizeFunction(MF,
|
||||
MF.getTarget().getInstrInfo(),
|
||||
MF.getTarget().getRegisterInfo(),
|
||||
getAnalysisIfAvailable<MachineModuleInfo>());
|
||||
}
|
||||
|
||||
|
||||
|
||||
BranchFolder::BranchFolder(bool defaultEnableTailMerge) {
|
||||
switch (FlagEnableTailMerge) {
|
||||
case cl::BOU_UNSET: EnableTailMerge = defaultEnableTailMerge; break;
|
||||
case cl::BOU_TRUE: EnableTailMerge = true; break;
|
||||
case cl::BOU_FALSE: EnableTailMerge = false; break;
|
||||
}
|
||||
}
|
||||
|
||||
/// RemoveDeadBlock - Remove the specified dead machine basic block from the
|
||||
@@ -149,7 +114,7 @@ bool BranchFolder::OptimizeImpDefsBlock(MachineBasicBlock *MBB) {
|
||||
break;
|
||||
unsigned Reg = I->getOperand(0).getReg();
|
||||
ImpDefRegs.insert(Reg);
|
||||
for (const unsigned *SubRegs = RegInfo->getSubRegisters(Reg);
|
||||
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
|
||||
unsigned SubReg = *SubRegs; ++SubRegs)
|
||||
ImpDefRegs.insert(SubReg);
|
||||
++I;
|
||||
@@ -183,32 +148,37 @@ bool BranchFolder::OptimizeImpDefsBlock(MachineBasicBlock *MBB) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BranchFolder::runOnMachineFunction(MachineFunction &MF) {
|
||||
TII = MF.getTarget().getInstrInfo();
|
||||
if (!TII) return false;
|
||||
/// OptimizeFunction - Perhaps branch folding, tail merging and other
|
||||
/// CFG optimizations on the given function.
|
||||
bool BranchFolder::OptimizeFunction(MachineFunction &MF,
|
||||
const TargetInstrInfo *tii,
|
||||
const TargetRegisterInfo *tri,
|
||||
MachineModuleInfo *mmi) {
|
||||
if (!tii) return false;
|
||||
|
||||
RegInfo = MF.getTarget().getRegisterInfo();
|
||||
TII = tii;
|
||||
TRI = tri;
|
||||
MMI = mmi;
|
||||
|
||||
RS = TRI->requiresRegisterScavenging(MF) ? new RegScavenger() : NULL;
|
||||
|
||||
// Fix CFG. The later algorithms expect it to be right.
|
||||
bool EverMadeChange = false;
|
||||
bool MadeChange = false;
|
||||
for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; I++) {
|
||||
MachineBasicBlock *MBB = I, *TBB = 0, *FBB = 0;
|
||||
SmallVector<MachineOperand, 4> Cond;
|
||||
if (!TII->AnalyzeBranch(*MBB, TBB, FBB, Cond, true))
|
||||
EverMadeChange |= MBB->CorrectExtraCFGEdges(TBB, FBB, !Cond.empty());
|
||||
EverMadeChange |= OptimizeImpDefsBlock(MBB);
|
||||
MadeChange |= MBB->CorrectExtraCFGEdges(TBB, FBB, !Cond.empty());
|
||||
MadeChange |= OptimizeImpDefsBlock(MBB);
|
||||
}
|
||||
|
||||
RS = RegInfo->requiresRegisterScavenging(MF) ? new RegScavenger() : NULL;
|
||||
|
||||
MMI = getAnalysisIfAvailable<MachineModuleInfo>();
|
||||
|
||||
bool MadeChangeThisIteration = true;
|
||||
while (MadeChangeThisIteration) {
|
||||
MadeChangeThisIteration = false;
|
||||
MadeChangeThisIteration |= TailMergeBlocks(MF);
|
||||
MadeChangeThisIteration |= OptimizeBranches(MF);
|
||||
EverMadeChange |= MadeChangeThisIteration;
|
||||
MadeChange |= MadeChangeThisIteration;
|
||||
}
|
||||
|
||||
// See if any jump tables have become mergable or dead as the code generator
|
||||
@@ -225,8 +195,12 @@ bool BranchFolder::runOnMachineFunction(MachineFunction &MF) {
|
||||
|
||||
// Scan the jump tables, seeing if there are any duplicates. Note that this
|
||||
// is N^2, which should be fixed someday.
|
||||
for (unsigned i = 1, e = JTs.size(); i != e; ++i)
|
||||
JTMapping.push_back(JTI->getJumpTableIndex(JTs[i].MBBs));
|
||||
for (unsigned i = 1, e = JTs.size(); i != e; ++i) {
|
||||
if (JTs[i].MBBs.empty())
|
||||
JTMapping.push_back(i);
|
||||
else
|
||||
JTMapping.push_back(JTI->getJumpTableIndex(JTs[i].MBBs));
|
||||
}
|
||||
|
||||
// If a jump table was merge with another one, walk the function rewriting
|
||||
// references to jump tables to reference the new JT ID's. Keep track of
|
||||
@@ -253,12 +227,12 @@ bool BranchFolder::runOnMachineFunction(MachineFunction &MF) {
|
||||
for (unsigned i = 0, e = JTIsLive.size(); i != e; ++i)
|
||||
if (!JTIsLive.test(i)) {
|
||||
JTI->RemoveJumpTable(i);
|
||||
EverMadeChange = true;
|
||||
MadeChange = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
delete RS;
|
||||
return EverMadeChange;
|
||||
return MadeChange;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -398,9 +372,9 @@ MachineBasicBlock *BranchFolder::SplitMBBAt(MachineBasicBlock &CurMBB,
|
||||
RS->enterBasicBlock(&CurMBB);
|
||||
if (!CurMBB.empty())
|
||||
RS->forward(prior(CurMBB.end()));
|
||||
BitVector RegsLiveAtExit(RegInfo->getNumRegs());
|
||||
BitVector RegsLiveAtExit(TRI->getNumRegs());
|
||||
RS->getRegsUsed(RegsLiveAtExit, false);
|
||||
for (unsigned int i=0, e=RegInfo->getNumRegs(); i!=e; i++)
|
||||
for (unsigned int i=0, e=TRI->getNumRegs(); i!=e; i++)
|
||||
if (RegsLiveAtExit[i])
|
||||
NewMBB->addLiveIn(i);
|
||||
}
|
||||
@@ -593,11 +567,12 @@ unsigned BranchFolder::CreateCommonTailOnlyBlock(MachineBasicBlock *&PredBB,
|
||||
|
||||
bool BranchFolder::TryMergeBlocks(MachineBasicBlock *SuccBB,
|
||||
MachineBasicBlock* PredBB) {
|
||||
bool MadeChange = false;
|
||||
|
||||
// It doesn't make sense to save a single instruction since tail merging
|
||||
// will add a jump.
|
||||
// FIXME: Ask the target to provide the threshold?
|
||||
unsigned minCommonTailLength = (SuccBB ? 1 : 2) + 1;
|
||||
MadeChange = false;
|
||||
|
||||
DEBUG(errs() << "\nTryMergeBlocks " << MergePotentials.size() << '\n');
|
||||
|
||||
@@ -668,7 +643,7 @@ bool BranchFolder::TailMergeBlocks(MachineFunction &MF) {
|
||||
|
||||
if (!EnableTailMerge) return false;
|
||||
|
||||
MadeChange = false;
|
||||
bool MadeChange = false;
|
||||
|
||||
// First find blocks with no successors.
|
||||
MergePotentials.clear();
|
||||
@@ -779,14 +754,14 @@ bool BranchFolder::TailMergeBlocks(MachineFunction &MF) {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool BranchFolder::OptimizeBranches(MachineFunction &MF) {
|
||||
MadeChange = false;
|
||||
bool MadeChange = false;
|
||||
|
||||
// Make sure blocks are numbered in order
|
||||
MF.RenumberBlocks();
|
||||
|
||||
for (MachineFunction::iterator I = ++MF.begin(), E = MF.end(); I != E; ) {
|
||||
MachineBasicBlock *MBB = I++;
|
||||
OptimizeBlock(MBB);
|
||||
MadeChange |= OptimizeBlock(MBB);
|
||||
|
||||
// If it is dead, remove it.
|
||||
if (MBB->pred_empty()) {
|
||||
@@ -880,7 +855,9 @@ static bool IsBetterFallthrough(MachineBasicBlock *MBB1,
|
||||
|
||||
/// OptimizeBlock - Analyze and optimize control flow related to the specified
|
||||
/// block. This is never called on the entry block.
|
||||
void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
|
||||
bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
|
||||
bool MadeChange = false;
|
||||
|
||||
MachineFunction::iterator FallThrough = MBB;
|
||||
++FallThrough;
|
||||
|
||||
@@ -889,7 +866,7 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
|
||||
// points to this block.
|
||||
if (MBB->empty() && !MBB->isLandingPad()) {
|
||||
// Dead block? Leave for cleanup later.
|
||||
if (MBB->pred_empty()) return;
|
||||
if (MBB->pred_empty()) return MadeChange;
|
||||
|
||||
if (FallThrough == MBB->getParent()->end()) {
|
||||
// TODO: Simplify preds to not branch here if possible!
|
||||
@@ -906,7 +883,7 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
|
||||
ReplaceMBBInJumpTables(MBB, FallThrough);
|
||||
MadeChange = true;
|
||||
}
|
||||
return;
|
||||
return MadeChange;
|
||||
}
|
||||
|
||||
// Check to see if we can simplify the terminator of the block before this
|
||||
@@ -1020,7 +997,7 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
|
||||
MBB->moveAfter(--MBB->getParent()->end());
|
||||
MadeChange = true;
|
||||
++NumBranchOpts;
|
||||
return;
|
||||
return MadeChange;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1122,7 +1099,7 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
|
||||
if (DidChange) {
|
||||
++NumBranchOpts;
|
||||
MadeChange = true;
|
||||
if (!HasBranchToSelf) return;
|
||||
if (!HasBranchToSelf) return MadeChange;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1203,8 +1180,10 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
|
||||
PrevBB.isSuccessor(FallThrough)) {
|
||||
MBB->moveAfter(--MBB->getParent()->end());
|
||||
MadeChange = true;
|
||||
return;
|
||||
return MadeChange;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return MadeChange;
|
||||
}
|
||||
|
Reference in New Issue
Block a user