+ if (isa<StructType>(BBTerm->getType()))
+ BBTerm->replaceAllUsesWith(UndefValue::get(BBTerm->getType()));
+ else if (BB->getTerminator()->getType() != Type::VoidTy)
+ BBTerm->replaceAllUsesWith(Constant::getNullValue(BBTerm->getType()));
+
+ // Replace the old terminator instruction.
+ BB->getInstList().pop_back();
+ new UnreachableInst(BB);
+ }
+
+ // The CFG Simplifier pass may delete one of the basic blocks we are
+ // interested in. If it does we need to take the block out of the list. Make
+ // a "persistent mapping" by turning basic blocks into <function, name> pairs.
+ // This won't work well if blocks are unnamed, but that is just the risk we
+ // have to take.
+ std::vector<std::pair<Function*, std::string> > BlockInfo;
+
+ for (std::set<BasicBlock*>::iterator I = Blocks.begin(), E = Blocks.end();
+ I != E; ++I)
+ BlockInfo.push_back(std::make_pair((*I)->getParent(), (*I)->getName()));
+
+ // Now run the CFG simplify pass on the function...
+ PassManager Passes;
+ Passes.add(createCFGSimplificationPass());
+ Passes.add(createVerifierPass());
+ Passes.run(*M);
+
+ // Try running on the hacked up program...
+ if (TestFn(BD, M)) {
+ BD.setNewProgram(M); // It crashed, keep the trimmed version...
+
+ // Make sure to use basic block pointers that point into the now-current
+ // module, and that they don't include any deleted blocks.
+ BBs.clear();
+ for (unsigned i = 0, e = BlockInfo.size(); i != e; ++i) {
+ ValueSymbolTable &ST = BlockInfo[i].first->getValueSymbolTable();
+ Value* V = ST.lookup(BlockInfo[i].second);
+ if (V && V->getType() == Type::LabelTy)
+ BBs.push_back(cast<BasicBlock>(V));
+ }
+ return true;
+ }
+ delete M; // It didn't crash, try something else.
+ return false;
+}
+
+/// DebugACrash - Given a predicate that determines whether a component crashes
+/// on a program, try to destructively reduce the program while still keeping
+/// the predicate true.
+static bool DebugACrash(BugDriver &BD, bool (*TestFn)(BugDriver &, Module *)) {
+ // See if we can get away with nuking some of the global variable initializers
+ // in the program...
+ if (BD.getProgram()->global_begin() != BD.getProgram()->global_end()) {
+ // Now try to reduce the number of global variable initializers in the
+ // module to something small.
+ Module *M = CloneModule(BD.getProgram());
+ bool DeletedInit = false;
+
+ for (Module::global_iterator I = M->global_begin(), E = M->global_end();
+ I != E; ++I)
+ if (I->hasInitializer()) {
+ I->setInitializer(0);
+ I->setLinkage(GlobalValue::ExternalLinkage);
+ DeletedInit = true;