#include "Support/FileUtilities.h"
#include <fstream>
#include <set>
+using namespace llvm;
-class DebugCrashes : public ListReducer<const PassInfo*> {
- BugDriver &BD;
-public:
- DebugCrashes(BugDriver &bd) : BD(bd) {}
-
- // doTest - Return true iff running the "removed" passes succeeds, and running
- // the "Kept" passes fail when run on the output of the "removed" passes. If
- // we return true, we update the current module of bugpoint.
- //
- virtual TestResult doTest(std::vector<const PassInfo*> &Removed,
- std::vector<const PassInfo*> &Kept);
-};
+namespace llvm {
+ class DebugCrashes : public ListReducer<const PassInfo*> {
+ BugDriver &BD;
+ public:
+ DebugCrashes(BugDriver &bd) : BD(bd) {}
+
+ // doTest - Return true iff running the "removed" passes succeeds, and
+ // running the "Kept" passes fail when run on the output of the "removed"
+ // passes. If we return true, we update the current module of bugpoint.
+ //
+ virtual TestResult doTest(std::vector<const PassInfo*> &Removed,
+ std::vector<const PassInfo*> &Kept);
+ };
+}
DebugCrashes::TestResult
DebugCrashes::doTest(std::vector<const PassInfo*> &Prefix,
return NoFailure;
}
-class ReduceCrashingFunctions : public ListReducer<Function*> {
- BugDriver &BD;
-public:
- ReduceCrashingFunctions(BugDriver &bd) : BD(bd) {}
-
- virtual TestResult doTest(std::vector<Function*> &Prefix,
- std::vector<Function*> &Kept) {
- if (!Kept.empty() && TestFuncs(Kept))
- return KeepSuffix;
- if (!Prefix.empty() && TestFuncs(Prefix))
- return KeepPrefix;
- return NoFailure;
- }
-
- bool TestFuncs(std::vector<Function*> &Prefix);
-};
+namespace llvm {
+ class ReduceCrashingFunctions : public ListReducer<Function*> {
+ BugDriver &BD;
+ public:
+ ReduceCrashingFunctions(BugDriver &bd) : BD(bd) {}
+
+ virtual TestResult doTest(std::vector<Function*> &Prefix,
+ std::vector<Function*> &Kept) {
+ if (!Kept.empty() && TestFuncs(Kept))
+ return KeepSuffix;
+ if (!Prefix.empty() && TestFuncs(Prefix))
+ return KeepPrefix;
+ return NoFailure;
+ }
+
+ bool TestFuncs(std::vector<Function*> &Prefix);
+ };
+}
bool ReduceCrashingFunctions::TestFuncs(std::vector<Function*> &Funcs) {
// Clone the program to try hacking it apart...
}
-/// ReduceCrashingBlocks reducer - This works by setting the terminators of all
-/// terminators except the specified basic blocks to a 'ret' instruction, then
-/// running the simplify-cfg pass. This has the effect of chopping up the CFG
-/// really fast which can reduce large functions quickly.
-///
-class ReduceCrashingBlocks : public ListReducer<BasicBlock*> {
- BugDriver &BD;
-public:
- ReduceCrashingBlocks(BugDriver &bd) : BD(bd) {}
+namespace llvm {
+ /// ReduceCrashingBlocks reducer - This works by setting the terminators of
+ /// all terminators except the specified basic blocks to a 'ret' instruction,
+ /// then running the simplify-cfg pass. This has the effect of chopping up
+ /// the CFG really fast which can reduce large functions quickly.
+ ///
+ class ReduceCrashingBlocks : public ListReducer<BasicBlock*> {
+ BugDriver &BD;
+ public:
+ ReduceCrashingBlocks(BugDriver &bd) : BD(bd) {}
- virtual TestResult doTest(std::vector<BasicBlock*> &Prefix,
- std::vector<BasicBlock*> &Kept) {
- if (!Kept.empty() && TestBlocks(Kept))
- return KeepSuffix;
- if (!Prefix.empty() && TestBlocks(Prefix))
- return KeepPrefix;
- return NoFailure;
- }
+ virtual TestResult doTest(std::vector<BasicBlock*> &Prefix,
+ std::vector<BasicBlock*> &Kept) {
+ if (!Kept.empty() && TestBlocks(Kept))
+ return KeepSuffix;
+ if (!Prefix.empty() && TestBlocks(Prefix))
+ return KeepPrefix;
+ return NoFailure;
+ }
- bool TestBlocks(std::vector<BasicBlock*> &Prefix);
-};
+ bool TestBlocks(std::vector<BasicBlock*> &Prefix);
+ };
+}
bool ReduceCrashingBlocks::TestBlocks(std::vector<BasicBlock*> &BBs) {
// Clone the program to try hacking it apart...
// Loop over and delete any hack up any blocks that are not listed...
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
for (Function::iterator BB = I->begin(), E = I->end(); BB != E; ++BB)
- if (!Blocks.count(BB) && !isa<ReturnInst>(BB->getTerminator())) {
+ if (!Blocks.count(BB) && BB->getTerminator()->getNumSuccessors()) {
// Loop over all of the successors of this block, deleting any PHI nodes
// that might include it.
for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI)
(*SI)->removePredecessor(BB);
+ if (BB->getTerminator()->getType() != Type::VoidTy)
+ BB->getTerminator()->replaceAllUsesWith(
+ Constant::getNullValue(BB->getTerminator()->getType()));
+
// Delete the old terminator instruction...
BB->getInstList().pop_back();
// Add a new return instruction of the appropriate type...
const Type *RetTy = BB->getParent()->getReturnType();
- ReturnInst *RI = new ReturnInst(RetTy == Type::VoidTy ? 0 :
- Constant::getNullValue(RetTy));
- BB->getInstList().push_back(RI);
+ new ReturnInst(RetTy == Type::VoidTy ? 0 :
+ Constant::getNullValue(RetTy), BB);
}
// The CFG Simplifier pass may delete one of the basic blocks we are
// Try to clean up the testcase by running funcresolve and globaldce...
std::cout << "\n*** Attempting to perform final cleanups: ";
Module *M = CloneModule(Program);
- performFinalCleanups(M, true);
+ M = performFinalCleanups(M, true);
std::swap(Program, M);
// Find out if the pass still crashes on the cleaned up program...
return false;
}
+