//
//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "tailduplicate"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Constant.h"
#include "llvm/Function.h"
#include "llvm/Support/CFG.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/ADT/Statistic.h"
-#include <iostream>
using namespace llvm;
+STATISTIC(NumEliminated, "Number of unconditional branches eliminated");
+
namespace {
cl::opt<unsigned>
Threshold("taildup-threshold", cl::desc("Max block size to tail duplicate"),
cl::init(6), cl::Hidden);
- Statistic<> NumEliminated("tailduplicate",
- "Number of unconditional branches eliminated");
- Statistic<> NumPHINodes("tailduplicate", "Number of phi nodes inserted");
-
- class TailDup : public FunctionPass {
+ class VISIBILITY_HIDDEN TailDup : public FunctionPass {
bool runOnFunction(Function &F);
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ TailDup() : FunctionPass((intptr_t)&ID) {}
+
private:
inline bool shouldEliminateUnconditionalBranch(TerminatorInst *TI);
inline void eliminateUnconditionalBranch(BranchInst *BI);
};
+ char TailDup::ID = 0;
RegisterPass<TailDup> X("tailduplicate", "Tail Duplication");
}
BasicBlock *DestBlock = Branch->getSuccessor(0);
assert(SourceBlock != DestBlock && "Our predicate is broken!");
- DEBUG(std::cerr << "TailDuplication[" << SourceBlock->getParent()->getName()
- << "]: Eliminating branch: " << *Branch);
+ DOUT << "TailDuplication[" << SourceBlock->getParent()->getName()
+ << "]: Eliminating branch: " << *Branch;
// See if we can avoid duplicating code by moving it up to a dominator of both
// blocks.
if (BasicBlock *DomBlock = FindObviousSharedDomOf(SourceBlock, DestBlock)) {
- DEBUG(std::cerr << "Found shared dominator: " << DomBlock->getName()
- << "\n");
+ DOUT << "Found shared dominator: " << DomBlock->getName() << "\n";
// If there are non-phi instructions in DestBlock that have no operands
// defined in DestBlock, and if the instruction has no side effects, we can
// Remove from DestBlock, move right before the term in DomBlock.
DestBlock->getInstList().remove(I);
DomBlock->getInstList().insert(DomBlock->getTerminator(), I);
- DEBUG(std::cerr << "Hoisted: " << *I);
+ DOUT << "Hoisted: " << *I;
}
}
}