#define DEBUG_TYPE "simplifycfg"
#include "llvm/Transforms/Scalar.h"
-#include "llvm/Transforms/Utils/Local.h"
-#include "llvm/Constants.h"
-#include "llvm/Instructions.h"
-#include "llvm/IntrinsicInst.h"
-#include "llvm/Module.h"
-#include "llvm/Attributes.h"
-#include "llvm/Support/CFG.h"
-#include "llvm/Pass.h"
-#include "llvm/DataLayout.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Transforms/Utils/Local.h"
using namespace llvm;
STATISTIC(NumSimpl, "Number of blocks simplified");
}
virtual bool runOnFunction(Function &F);
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<TargetTransformInfo>();
+ }
};
}
char CFGSimplifyPass::ID = 0;
-INITIALIZE_PASS(CFGSimplifyPass, "simplifycfg",
- "Simplify the CFG", false, false)
+INITIALIZE_PASS_BEGIN(CFGSimplifyPass, "simplifycfg", "Simplify the CFG",
+ false, false)
+INITIALIZE_AG_DEPENDENCY(TargetTransformInfo)
+INITIALIZE_PASS_END(CFGSimplifyPass, "simplifycfg", "Simplify the CFG",
+ false, false)
// Public interface to the CFGSimplification pass
FunctionPass *llvm::createCFGSimplificationPass() {
SmallVector<BasicBlock*, 128> Worklist;
Worklist.push_back(BB);
+ Reachable.insert(BB);
bool Changed = false;
do {
BB = Worklist.pop_back_val();
- if (!Reachable.insert(BB))
- continue;
-
// Do a quick scan of the basic block, turning any obviously unreachable
// instructions into LLVM unreachable insts. The instruction combining pass
// canonicalizes unreachable insts into stores to null or undef.
Changed |= ConstantFoldTerminator(BB, true);
for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
- Worklist.push_back(*SI);
+ if (Reachable.insert(*SI))
+ Worklist.push_back(*SI);
} while (!Worklist.empty());
return Changed;
}
/// iterativelySimplifyCFG - Call SimplifyCFG on all the blocks in the function,
/// iterating until no more changes are made.
-static bool iterativelySimplifyCFG(Function &F, const DataLayout *TD) {
+static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
+ const DataLayout *TD) {
bool Changed = false;
bool LocalChange = true;
while (LocalChange) {
// Loop over all of the basic blocks and remove them if they are unneeded...
//
for (Function::iterator BBIt = F.begin(); BBIt != F.end(); ) {
- if (SimplifyCFG(BBIt++, TD)) {
+ if (SimplifyCFG(BBIt++, TTI, TD)) {
LocalChange = true;
++NumSimpl;
}
// simplify the CFG.
//
bool CFGSimplifyPass::runOnFunction(Function &F) {
+ const TargetTransformInfo &TTI = getAnalysis<TargetTransformInfo>();
const DataLayout *TD = getAnalysisIfAvailable<DataLayout>();
bool EverChanged = removeUnreachableBlocksFromFn(F);
EverChanged |= mergeEmptyReturnBlocks(F);
- EverChanged |= iterativelySimplifyCFG(F, TD);
+ EverChanged |= iterativelySimplifyCFG(F, TTI, TD);
// If neither pass changed anything, we're done.
if (!EverChanged) return false;
return true;
do {
- EverChanged = iterativelySimplifyCFG(F, TD);
+ EverChanged = iterativelySimplifyCFG(F, TTI, TD);
EverChanged |= removeUnreachableBlocksFromFn(F);
} while (EverChanged);