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:
Evan Cheng 2009-09-04 07:47:40 +00:00
parent e93909185f
commit 030a0a0cdb
5 changed files with 188 additions and 85 deletions

View File

@ -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;
}

View File

@ -0,0 +1,84 @@
//===-- BranchFolding.h - Fold machine code branch instructions --*- C++ -*===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_BRANCHFOLDING_HPP
#define LLVM_CODEGEN_BRANCHFOLDING_HPP
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include <vector>
namespace llvm {
class MachineFunction;
class MachineModuleInfo;
class RegScavenger;
class TargetInstrInfo;
class TargetRegisterInfo;
class BranchFolder {
public:
explicit BranchFolder(bool defaultEnableTailMerge);
bool OptimizeFunction(MachineFunction &MF,
const TargetInstrInfo *tii,
const TargetRegisterInfo *tri,
MachineModuleInfo *mmi);
private:
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;
bool EnableTailMerge;
const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
MachineModuleInfo *MMI;
RegScavenger *RS;
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);
bool OptimizeBranches(MachineFunction &MF);
bool 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);
};
/// BranchFolderPass - Wrap branch folder in a machine function pass.
class BranchFolderPass : public MachineFunctionPass,
public BranchFolder {
public:
static char ID;
explicit BranchFolderPass(bool defaultEnableTailMerge)
: MachineFunctionPass(&ID), BranchFolder(defaultEnableTailMerge) {}
virtual bool runOnMachineFunction(MachineFunction &MF);
virtual const char *getPassName() const { return "Control Flow Optimizer"; }
};
}
#endif /* LLVM_CODEGEN_BRANCHFOLDING_HPP */

View File

@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "ifcvt"
#include "BranchFolding.h"
#include "llvm/Function.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
@ -360,6 +361,13 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
Roots.clear();
BBAnalysis.clear();
if (MadeChange) {
BranchFolder BF(false);
BF.OptimizeFunction(MF, TII,
MF.getTarget().getRegisterInfo(),
getAnalysisIfAvailable<MachineModuleInfo>());
}
return MadeChange;
}

View File

@ -31,7 +31,7 @@ entry:
; CHECK: CountTree:
; CHECK: it eq
; CHECK: cmpeq
; CHECK: beq
; CHECK: bne
; CHECK: itt eq
; CHECK: moveq
; CHECK: popeq

View File

@ -0,0 +1,32 @@
; RUN: llvm-as < %s | llc -mtriple=thumbv7-apple-darwin | FileCheck %s
; There shouldn't be a unconditional branch at end of bb52.
; rdar://7184787
@posed = external global i64 ; <i64*> [#uses=1]
define i1 @ab_bb52(i64 %.reload78, i64* %.out, i64* %.out1) nounwind {
newFuncRoot:
br label %bb52
bb52.bb55_crit_edge.exitStub: ; preds = %bb52
store i64 %0, i64* %.out
store i64 %2, i64* %.out1
ret i1 true
bb52.bb53_crit_edge.exitStub: ; preds = %bb52
store i64 %0, i64* %.out
store i64 %2, i64* %.out1
ret i1 false
bb52: ; preds = %newFuncRoot
; CHECK: moveq
; CHECK: movne
; CHECK-NEXT: LBB1_2:
; CHECK-NEXT: pop
%0 = load i64* @posed, align 4 ; <i64> [#uses=3]
%1 = sub i64 %0, %.reload78 ; <i64> [#uses=1]
%2 = ashr i64 %1, 1 ; <i64> [#uses=3]
%3 = icmp eq i64 %2, 0 ; <i1> [#uses=1]
br i1 %3, label %bb52.bb55_crit_edge.exitStub, label %bb52.bb53_crit_edge.exitStub
}