"git@repo.hca.bsc.es:rferrer/llvm-epi-0.8.git" did not exist on "5352717508c897d87ec25a686519081e1adb357d"
Newer
Older
Chris Lattner
committed
//===- CodeGenPrepare.cpp - Prepare a function for code generation --------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
Chris Lattner
committed
//
//===----------------------------------------------------------------------===//
//
// This pass munges the code in the input function to better prepare it for
// SelectionDAG-based code generation. This works around limitations in it's
// basic-block-at-a-time approach. It should eventually be removed.
Chris Lattner
committed
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "codegenprepare"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/InlineAsm.h"
Chris Lattner
committed
#include "llvm/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/ADT/DenseMap.h"
Chris Lattner
committed
#include "llvm/ADT/SmallSet.h"
#include "llvm/Support/CallSite.h"
Evan Cheng
committed
#include "llvm/Support/CommandLine.h"
Chris Lattner
committed
#include "llvm/Support/Compiler.h"
Evan Cheng
committed
#include "llvm/Support/Debug.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/PatternMatch.h"
Chris Lattner
committed
using namespace llvm;
using namespace llvm::PatternMatch;
Chris Lattner
committed
Evan Cheng
committed
static cl::opt<bool> FactorCommonPreds("split-critical-paths-tweak",
cl::init(false), cl::Hidden);
namespace {
Chris Lattner
committed
class VISIBILITY_HIDDEN CodeGenPrepare : public FunctionPass {
/// TLI - Keep a pointer of a TargetLowering to consult for determining
/// transformation profitability.
const TargetLowering *TLI;
Evan Cheng
committed
/// BackEdges - Keep a set of all the loop back edges.
///
SmallSet<std::pair<BasicBlock*,BasicBlock*>, 8> BackEdges;
Chris Lattner
committed
public:
static char ID; // Pass identification, replacement for typeid
explicit CodeGenPrepare(const TargetLowering *tli = 0)
: FunctionPass(&ID), TLI(tli) {}
Chris Lattner
committed
bool runOnFunction(Function &F);
Chris Lattner
committed
private:
Chris Lattner
committed
bool EliminateMostlyEmptyBlocks(Function &F);
bool CanMergeBlocks(const BasicBlock *BB, const BasicBlock *DestBB) const;
void EliminateMostlyEmptyBlock(BasicBlock *BB);
Chris Lattner
committed
bool OptimizeBlock(BasicBlock &BB);
bool OptimizeMemoryInst(Instruction *I, Value *Addr, const Type *AccessTy,
DenseMap<Value*,Value*> &SunkAddrs);
bool OptimizeInlineAsmInst(Instruction *I, CallSite CS,
DenseMap<Value*,Value*> &SunkAddrs);
Evan Cheng
committed
bool OptimizeExtUses(Instruction *I);
Evan Cheng
committed
void findLoopBackEdges(Function &F);
Chris Lattner
committed
};
}
Chris Lattner
committed
static RegisterPass<CodeGenPrepare> X("codegenprepare",
"Optimize for code generation");
FunctionPass *llvm::createCodeGenPreparePass(const TargetLowering *TLI) {
return new CodeGenPrepare(TLI);
}
Evan Cheng
committed
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/// findLoopBackEdges - Do a DFS walk to find loop back edges.
///
void CodeGenPrepare::findLoopBackEdges(Function &F) {
SmallPtrSet<BasicBlock*, 8> Visited;
SmallVector<std::pair<BasicBlock*, succ_iterator>, 8> VisitStack;
SmallPtrSet<BasicBlock*, 8> InStack;
BasicBlock *BB = &F.getEntryBlock();
if (succ_begin(BB) == succ_end(BB))
return;
Visited.insert(BB);
VisitStack.push_back(std::make_pair(BB, succ_begin(BB)));
InStack.insert(BB);
do {
std::pair<BasicBlock*, succ_iterator> &Top = VisitStack.back();
BasicBlock *ParentBB = Top.first;
succ_iterator &I = Top.second;
bool FoundNew = false;
while (I != succ_end(ParentBB)) {
BB = *I++;
if (Visited.insert(BB)) {
FoundNew = true;
break;
}
// Successor is in VisitStack, it's a back edge.
if (InStack.count(BB))
BackEdges.insert(std::make_pair(ParentBB, BB));
}
if (FoundNew) {
// Go down one level if there is a unvisited successor.
InStack.insert(BB);
VisitStack.push_back(std::make_pair(BB, succ_begin(BB)));
} else {
// Go up one level.
std::pair<BasicBlock*, succ_iterator> &Pop = VisitStack.back();
InStack.erase(Pop.first);
VisitStack.pop_back();
}
} while (!VisitStack.empty());
}
Chris Lattner
committed
bool CodeGenPrepare::runOnFunction(Function &F) {
bool EverMadeChange = false;
Chris Lattner
committed
// First pass, eliminate blocks that contain only PHI nodes and an
// unconditional branch.
EverMadeChange |= EliminateMostlyEmptyBlocks(F);
// Now find loop back edges.
findLoopBackEdges(F);
Chris Lattner
committed
bool MadeChange = true;
Chris Lattner
committed
while (MadeChange) {
MadeChange = false;
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
MadeChange |= OptimizeBlock(*BB);
EverMadeChange |= MadeChange;
}
return EverMadeChange;
}
Chris Lattner
committed
/// EliminateMostlyEmptyBlocks - eliminate blocks that contain only PHI nodes
/// and an unconditional branch. Passes before isel (e.g. LSR/loopsimplify)
Chris Lattner
committed
/// often split edges in ways that are non-optimal for isel. Start by
/// eliminating these blocks so we can split them the way we want them.
bool CodeGenPrepare::EliminateMostlyEmptyBlocks(Function &F) {
bool MadeChange = false;
// Note that this intentionally skips the entry block.
for (Function::iterator I = ++F.begin(), E = F.end(); I != E; ) {
BasicBlock *BB = I++;
// If this block doesn't end with an uncond branch, ignore it.
BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator());
if (!BI || !BI->isUnconditional())
continue;
Chris Lattner
committed
// If the instruction before the branch isn't a phi node, then other stuff
// is happening here.
BasicBlock::iterator BBI = BI;
if (BBI != BB->begin()) {
--BBI;
if (!isa<PHINode>(BBI)) continue;
}
Chris Lattner
committed
// Do not break infinite loops.
BasicBlock *DestBB = BI->getSuccessor(0);
if (DestBB == BB)
continue;
Chris Lattner
committed
if (!CanMergeBlocks(BB, DestBB))
continue;
Chris Lattner
committed
EliminateMostlyEmptyBlock(BB);
MadeChange = true;
}
return MadeChange;
}
/// CanMergeBlocks - Return true if we can merge BB into DestBB if there is a
/// single uncond branch between them, and BB contains no other non-phi
/// instructions.
bool CodeGenPrepare::CanMergeBlocks(const BasicBlock *BB,
const BasicBlock *DestBB) const {
// We only want to eliminate blocks whose phi nodes are used by phi nodes in
// the successor. If there are more complex condition (e.g. preheaders),
// don't mess around with them.
BasicBlock::const_iterator BBI = BB->begin();
while (const PHINode *PN = dyn_cast<PHINode>(BBI++)) {
for (Value::use_const_iterator UI = PN->use_begin(), E = PN->use_end();
UI != E; ++UI) {
const Instruction *User = cast<Instruction>(*UI);
if (User->getParent() != DestBB || !isa<PHINode>(User))
return false;
// If User is inside DestBB block and it is a PHINode then check
// incoming value. If incoming value is not from BB then this is
// a complex condition (e.g. preheaders) we want to avoid here.
if (User->getParent() == DestBB) {
Loading
Loading full blame...