#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileUtilities.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Path.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Signals.h"
#include <set>
using namespace llvm;
/// depends on the value. The modified module is then returned.
///
Module *BugDriver::deleteInstructionFromProgram(const Instruction *I,
- unsigned Simplification) const {
- Module *Result = CloneModule(Program);
+ unsigned Simplification) {
+ // FIXME, use vmap?
+ Module *Clone = CloneModule(Program);
const BasicBlock *PBB = I->getParent();
const Function *PF = PBB->getParent();
- Module::iterator RFI = Result->begin(); // Get iterator to corresponding fn
+ Module::iterator RFI = Clone->begin(); // Get iterator to corresponding fn
std::advance(RFI, std::distance(PF->getParent()->begin(),
Module::const_iterator(PF)));
// Remove the instruction from the program.
TheInst->getParent()->getInstList().erase(TheInst);
-
- //writeProgramToFile("current.bc", Result);
-
// Spiff up the output a little bit.
- PassManager Passes;
- // Make sure that the appropriate target data is always used...
- Passes.add(new TargetData(Result));
+ std::vector<std::string> Passes;
- /// FIXME: If this used runPasses() like the methods below, we could get rid
- /// of the -disable-* options!
+ /// Can we get rid of the -disable-* options?
if (Simplification > 1 && !NoDCE)
- Passes.add(createDeadCodeEliminationPass());
+ Passes.push_back("dce");
if (Simplification && !DisableSimplifyCFG)
- Passes.add(createCFGSimplificationPass()); // Delete dead control flow
-
- Passes.add(createVerifierPass());
- Passes.run(*Result);
- return Result;
-}
-
-static const PassInfo *getPI(Pass *P) {
- const PassInfo *PI = P->getPassInfo();
- delete P;
- return PI;
+ Passes.push_back("simplifycfg"); // Delete dead control flow
+
+ Passes.push_back("verify");
+ Module *New = runPassesOn(Clone, Passes);
+ delete Clone;
+ if (!New) {
+ errs() << "Instruction removal failed. Sorry. :( Please report a bug!\n";
+ exit(1);
+ }
+ return New;
}
/// performFinalCleanups - This method clones the current Program and performs
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
I->setLinkage(GlobalValue::ExternalLinkage);
- std::vector<const PassInfo*> CleanupPasses;
- CleanupPasses.push_back(getPI(createGlobalDCEPass()));
+ std::vector<std::string> CleanupPasses;
+ CleanupPasses.push_back("globaldce");
if (MayModifySemantics)
- CleanupPasses.push_back(getPI(createDeadArgHackingPass()));
+ CleanupPasses.push_back("deadarghaX0r");
else
- CleanupPasses.push_back(getPI(createDeadArgEliminationPass()));
-
- CleanupPasses.push_back(getPI(createDeadTypeEliminationPass()));
+ CleanupPasses.push_back("deadargelim");
Module *New = runPassesOn(M, CleanupPasses);
if (New == 0) {
/// function. This returns null if there are no extractable loops in the
/// program or if the loop extractor crashes.
Module *BugDriver::ExtractLoop(Module *M) {
- std::vector<const PassInfo*> LoopExtractPasses;
- LoopExtractPasses.push_back(getPI(createSingleLoopExtractorPass()));
+ std::vector<std::string> LoopExtractPasses;
+ LoopExtractPasses.push_back("loop-extract-single");
Module *NewM = runPassesOn(M, LoopExtractPasses);
if (NewM == 0) {
static Constant *GetTorInit(std::vector<std::pair<Function*, int> > &TorList) {
assert(!TorList.empty() && "Don't create empty tor list!");
std::vector<Constant*> ArrayElts;
+ Type *Int32Ty = Type::getInt32Ty(TorList[0].first->getContext());
+
+ StructType *STy =
+ StructType::get(Int32Ty, TorList[0].first->getType(), NULL);
for (unsigned i = 0, e = TorList.size(); i != e; ++i) {
- std::vector<Constant*> Elts;
- Elts.push_back(ConstantInt::get(
- Type::getInt32Ty(TorList[i].first->getContext()), TorList[i].second));
- Elts.push_back(TorList[i].first);
- ArrayElts.push_back(ConstantStruct::get(TorList[i].first->getContext(),
- Elts, false));
+ Constant *Elts[] = {
+ ConstantInt::get(Int32Ty, TorList[i].second),
+ TorList[i].first
+ };
+ ArrayElts.push_back(ConstantStruct::get(STy, Elts));
}
return ConstantArray::get(ArrayType::get(ArrayElts[0]->getType(),
ArrayElts.size()),
/// static ctors/dtors, we need to add an llvm.global_[cd]tors global to M2, and
/// prune appropriate entries out of M1s list.
static void SplitStaticCtorDtor(const char *GlobalName, Module *M1, Module *M2,
- ValueMap<const Value*, Value*> &VMap) {
+ ValueToValueMapTy &VMap) {
GlobalVariable *GV = M1->getNamedGlobal(GlobalName);
if (!GV || GV->isDeclaration() || GV->hasLocalLinkage() ||
!GV->use_empty()) return;
Module *
llvm::SplitFunctionsOutOfModule(Module *M,
const std::vector<Function*> &F,
- ValueMap<const Value*, Value*> &VMap) {
+ ValueToValueMapTy &VMap) {
// Make sure functions & globals are all external so that linkage
// between the two modules will work.
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
I->setLinkage(GlobalValue::ExternalLinkage);
}
- ValueMap<const Value*, Value*> NewVMap;
+ ValueToValueMapTy NewVMap;
Module *New = CloneModule(M, NewVMap);
// Make sure global initializers exist only in the safe module (CBE->.so)
sys::RemoveFileOnSignal(uniqueFilename);
std::string ErrorInfo;
- raw_fd_ostream BlocksToNotExtractFile(uniqueFilename.c_str(), ErrorInfo);
+ tool_output_file BlocksToNotExtractFile(uniqueFilename.c_str(), ErrorInfo);
if (!ErrorInfo.empty()) {
outs() << "*** Basic Block extraction failed!\n";
errs() << "Error writing list of blocks to not extract: " << ErrorInfo
// If the BB doesn't have a name, give it one so we have something to key
// off of.
if (!BB->hasName()) BB->setName("tmpbb");
- BlocksToNotExtractFile << BB->getParent()->getNameStr() << " "
- << BB->getName() << "\n";
+ BlocksToNotExtractFile.os() << BB->getParent()->getNameStr() << " "
+ << BB->getName() << "\n";
+ }
+ BlocksToNotExtractFile.os().close();
+ if (BlocksToNotExtractFile.os().has_error()) {
+ errs() << "Error writing list of blocks to not extract: " << ErrorInfo
+ << "\n";
+ EmitProgressBitcode(M, "basicblockextractfail", true);
+ BlocksToNotExtractFile.os().clear_error();
+ return 0;
}
- BlocksToNotExtractFile.close();
+ BlocksToNotExtractFile.keep();
std::string uniqueFN = "--extract-blocks-file=" + uniqueFilename.str();
const char *ExtraArg = uniqueFN.c_str();
- std::vector<const PassInfo*> PI;
- PI.push_back(getPI(createBlockExtractorPass()));
+ std::vector<std::string> PI;
+ PI.push_back("extract-blocks");
Module *Ret = runPassesOn(M, PI, false, 1, &ExtraArg);
uniqueFilename.eraseFromDisk(); // Free disk space