Newer
Older
//===-- BranchFolding.cpp - Fold machine code branch instructions ---------===//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//===----------------------------------------------------------------------===//
//
// This pass forwards branches to unconditional branches to make them branch
// directly to the target block. This pass often results in dead MBB's, which
// it then removes.
//
// Note that this pass must be run after register allocation, it cannot handle
// SSA form.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "branchfolding"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/MRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/ADT/Statistic.h"
using namespace llvm;
STATISTIC(NumDeadBlocks, "Number of dead blocks removed");
STATISTIC(NumBranchOpts, "Number of branches optimized");
STATISTIC(NumTailMerge , "Number of block tails merged");
static cl::opt<cl::boolOrDefault> FlagEnableTailMerge("enable-tail-merge",
cl::init(cl::BOU_UNSET), cl::Hidden);
// Throttle for huge numbers of predecessors (compile speed problems)
cl::opt<unsigned>
TailMergeThreshold("tail-merge-threshold",
cl::desc("Max number of predecessors to consider tail merging"),
cl::init(100), cl::Hidden);
struct BranchFolder : public MachineFunctionPass {
BranchFolder(bool defaultEnableTailMerge) :
MachineFunctionPass((intptr_t)&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;
bool EnableTailMerge;
bool TailMergeBlocks(MachineFunction &MF);
bool TryMergeBlocks(MachineBasicBlock* SuccBB,
MachineBasicBlock* PredBB);
void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst,
MachineBasicBlock *NewDest);
Chris Lattner
committed
MachineBasicBlock *SplitMBBAt(MachineBasicBlock &CurMBB,
MachineBasicBlock::iterator BBI1);
std::vector<std::pair<unsigned,MachineBasicBlock*> > MergePotentials;
const MRegisterInfo *RegInfo;
RegScavenger *RS;
// Branch optzn.
bool OptimizeBranches(MachineFunction &MF);
void OptimizeBlock(MachineBasicBlock *MBB);
void RemoveDeadBlock(MachineBasicBlock *MBB);
Chris Lattner
committed
bool CanFallThrough(MachineBasicBlock *CurBB);
bool CanFallThrough(MachineBasicBlock *CurBB, bool BranchUnAnalyzable,
MachineBasicBlock *TBB, MachineBasicBlock *FBB,
const std::vector<MachineOperand> &Cond);
static bool CorrectExtraCFGEdges(MachineBasicBlock &MBB,
MachineBasicBlock *DestA,
MachineBasicBlock *DestB,
bool isCond,
MachineFunction::iterator FallThru);
FunctionPass *llvm::createBranchFoldingPass(bool DefaultEnableTailMerge) {
return new BranchFolder(DefaultEnableTailMerge); }
/// RemoveDeadBlock - Remove the specified dead machine basic block from the
/// function, updating the CFG.
void BranchFolder::RemoveDeadBlock(MachineBasicBlock *MBB) {
DOUT << "\nRemoving MBB: " << *MBB;
MachineFunction *MF = MBB->getParent();
// drop all successors.
while (!MBB->succ_empty())
MBB->removeSuccessor(MBB->succ_end()-1);
// If there is DWARF info to active, check to see if there are any LABEL
// records in the basic block. If so, unregister them from MachineModuleInfo.
if (MMI && !MBB->empty()) {
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
I != E; ++I) {
if ((unsigned)I->getOpcode() == TargetInstrInfo::LABEL) {
// The label ID # is always operand #0, an immediate.
MMI->InvalidateLabel(I->getOperand(0).getImm());
}
}
}
// Remove the block.
MF->getBasicBlockList().erase(MBB);
}
bool BranchFolder::runOnMachineFunction(MachineFunction &MF) {
TII = MF.getTarget().getInstrInfo();
if (!TII) return false;
// Fix CFG. The later algorithms expect it to be right.
bool EverMadeChange = false;
for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; I++) {
MachineBasicBlock *MBB = I, *TBB = 0, *FBB = 0;
std::vector<MachineOperand> Cond;
if (!TII->AnalyzeBranch(*MBB, TBB, FBB, Cond))
EverMadeChange |= CorrectExtraCFGEdges(*MBB, TBB, FBB,
!Cond.empty(), next(I));
}
RegInfo = MF.getTarget().getRegisterInfo();
RS = RegInfo->requiresRegisterScavenging(MF) ? new RegScavenger() : NULL;
MMI = getAnalysisToUpdate<MachineModuleInfo>();
bool MadeChangeThisIteration = true;
while (MadeChangeThisIteration) {
MadeChangeThisIteration = false;
MadeChangeThisIteration |= TailMergeBlocks(MF);
MadeChangeThisIteration |= OptimizeBranches(MF);
EverMadeChange |= MadeChangeThisIteration;
}
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
// See if any jump tables have become mergable or dead as the code generator
// did its thing.
MachineJumpTableInfo *JTI = MF.getJumpTableInfo();
const std::vector<MachineJumpTableEntry> &JTs = JTI->getJumpTables();
if (!JTs.empty()) {
// Figure out how these jump tables should be merged.
std::vector<unsigned> JTMapping;
JTMapping.reserve(JTs.size());
// We always keep the 0th jump table.
JTMapping.push_back(0);
// 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));
// 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
// whether we see a jump table idx, if not, we can delete the JT.
std::vector<bool> JTIsLive;
JTIsLive.resize(JTs.size());
for (MachineFunction::iterator BB = MF.begin(), E = MF.end();
BB != E; ++BB) {
for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
I != E; ++I)
for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) {
MachineOperand &Op = I->getOperand(op);
if (!Op.isJumpTableIndex()) continue;
unsigned NewIdx = JTMapping[Op.getJumpTableIndex()];
Op.setJumpTableIndex(NewIdx);
// Remember that this JT is live.
JTIsLive[NewIdx] = true;
}
}
// Finally, remove dead jump tables. This happens either because the
// indirect jump was unreachable (and thus deleted) or because the jump
// table was merged with some other one.
for (unsigned i = 0, e = JTIsLive.size(); i != e; ++i)
if (!JTIsLive[i]) {
JTI->RemoveJumpTable(i);
EverMadeChange = true;
}
}
delete RS;
Loading
Loading full blame...