delete gcc;
}
-
-/// ParseInputFile - Given a bitcode or assembly input filename, parse and
-/// return it, or return null if not possible.
-///
-Module *llvm::ParseInputFile(const std::string &Filename,
- LLVMContext& Ctxt) {
+std::unique_ptr<Module> llvm::parseInputFile(StringRef Filename,
+ LLVMContext &Ctxt) {
SMDiagnostic Err;
- Module *Result = ParseIRFile(Filename, Err, Ctxt);
+ std::unique_ptr<Module> Result (ParseIRFile(Filename, Err, Ctxt));
if (!Result)
Err.print("bugpoint", errs());
assert(!Filenames.empty() && "Must specify at least on input filename!");
// Load the first input file.
- Program = ParseInputFile(Filenames[0], Context);
+ Program = parseInputFile(Filenames[0], Context).release();
if (!Program) return true;
outs() << "Read input file : '" << Filenames[0] << "'\n";
for (unsigned i = 1, e = Filenames.size(); i != e; ++i) {
- std::unique_ptr<Module> M(ParseInputFile(Filenames[i], Context));
+ std::unique_ptr<Module> M = parseInputFile(Filenames[i], Context);
if (!M.get()) return true;
outs() << "Linking in input file: '" << Filenames[i] << "'\n";
#include "llvm/IR/ValueMap.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
+#include <memory>
#include <string>
#include <vector>
void EmitProgressBitcode(const Module *M, const std::string &ID,
bool NoFlyer = false) const;
- /// deleteInstructionFromProgram - This method clones the current Program and
- /// deletes the specified instruction from the cloned module. It then runs a
- /// series of cleanup passes (ADCE and SimplifyCFG) to eliminate any code
- /// which depends on the value. The modified module is then returned.
+ /// This method clones the current Program and deletes the specified
+ /// instruction from the cloned module. It then runs a series of cleanup
+ /// passes (ADCE and SimplifyCFG) to eliminate any code which depends on the
+ /// value. The modified module is then returned.
///
- Module *deleteInstructionFromProgram(const Instruction *I, unsigned Simp);
+ std::unique_ptr<Module> deleteInstructionFromProgram(const Instruction *I,
+ unsigned Simp);
- /// performFinalCleanups - This method clones the current Program and performs
- /// a series of cleanups intended to get rid of extra cruft on the module. If
- /// the MayModifySemantics argument is true, then the cleanups is allowed to
+ /// This method clones the current Program and performs a series of cleanups
+ /// intended to get rid of extra cruft on the module. If the
+ /// MayModifySemantics argument is true, then the cleanups is allowed to
/// modify how the code behaves.
///
- Module *performFinalCleanups(Module *M, bool MayModifySemantics = false);
-
- /// ExtractLoop - Given a module, extract up to one loop from it into a new
- /// function. This returns null if there are no extractable loops in the
- /// program or if the loop extractor crashes.
- Module *ExtractLoop(Module *M);
-
- /// ExtractMappedBlocksFromModule - Extract all but the specified basic blocks
- /// into their own functions. The only detail is that M is actually a module
- /// cloned from the one the BBs are in, so some mapping needs to be performed.
- /// If this operation fails for some reason (ie the implementation is buggy),
- /// this function should return null, otherwise it returns a new Module.
- Module *ExtractMappedBlocksFromModule(const std::vector<BasicBlock*> &BBs,
- Module *M);
-
- /// runPassesOn - Carefully run the specified set of pass on the specified
- /// module, returning the transformed module on success, or a null pointer on
- /// failure. If AutoDebugCrashes is set to true, then bugpoint will
- /// automatically attempt to track down a crashing pass if one exists, and
- /// this method will never return null.
- Module *runPassesOn(Module *M, const std::vector<std::string> &Passes,
- bool AutoDebugCrashes = false, unsigned NumExtraArgs = 0,
- const char * const *ExtraArgs = nullptr);
+ std::unique_ptr<Module> performFinalCleanups(Module *M,
+ bool MayModifySemantics = false);
+
+ /// Given a module, extract up to one loop from it into a new function. This
+ /// returns null if there are no extractable loops in the program or if the
+ /// loop extractor crashes.
+ std::unique_ptr<Module> extractLoop(Module *M);
+
+ /// Extract all but the specified basic blocks into their own functions. The
+ /// only detail is that M is actually a module cloned from the one the BBs are
+ /// in, so some mapping needs to be performed. If this operation fails for
+ /// some reason (ie the implementation is buggy), this function should return
+ /// null, otherwise it returns a new Module.
+ std::unique_ptr<Module>
+ extractMappedBlocksFromModule(const std::vector<BasicBlock *> &BBs,
+ Module *M);
+
+ /// Carefully run the specified set of pass on the specified/ module,
+ /// returning the transformed module on success, or a null pointer on failure.
+ /// If AutoDebugCrashes is set to true, then bugpoint will automatically
+ /// attempt to track down a crashing pass if one exists, and this method will
+ /// never return null.
+ std::unique_ptr<Module> runPassesOn(Module *M,
+ const std::vector<std::string> &Passes,
+ bool AutoDebugCrashes = false,
+ unsigned NumExtraArgs = 0,
+ const char *const *ExtraArgs = nullptr);
/// runPasses - Run the specified passes on Program, outputting a bitcode
/// file and writting the filename into OutputFile if successful. If the
bool initializeExecutionEnvironment();
};
-/// ParseInputFile - Given a bitcode or assembly input filename, parse and
-/// return it, or return null if not possible.
+/// Given a bitcode or assembly input filename, parse and return it, or return
+/// null if not possible.
///
-Module *ParseInputFile(const std::string &InputFilename,
- LLVMContext& ctxt);
-
+std::unique_ptr<Module> parseInputFile(StringRef InputFilename,
+ LLVMContext &ctxt);
/// getPassesString - Turn a list of passes into a string which indicates the
/// command line options that must be passed to add the passes.
OrigProgram = BD.Program;
- BD.Program = ParseInputFile(PrefixOutput, BD.getContext());
+ BD.Program = parseInputFile(PrefixOutput, BD.getContext()).release();
if (BD.Program == nullptr) {
errs() << BD.getToolName() << ": Error reading bitcode file '"
<< PrefixOutput << "'!\n";
std::vector<std::string> Passes;
Passes.push_back("simplifycfg");
Passes.push_back("verify");
- Module *New = BD.runPassesOn(M, Passes);
+ std::unique_ptr<Module> New = BD.runPassesOn(M, Passes);
delete M;
if (!New) {
errs() << "simplifycfg failed!\n";
exit(1);
}
- M = New;
+ M = New.release();
// Try running on the hacked up program...
if (TestFn(BD, M)) {
continue;
outs() << "Checking instruction: " << *I;
- Module *M = BD.deleteInstructionFromProgram(I, Simplification);
+ std::unique_ptr<Module> M =
+ BD.deleteInstructionFromProgram(I, Simplification);
// Find out if the pass still crashes on this pass...
- if (TestFn(BD, M)) {
+ if (TestFn(BD, M.get())) {
// Yup, it does, we delete the old module, and continue trying
// to reduce the testcase...
- BD.setNewProgram(M);
+ BD.setNewProgram(M.release());
InstructionsToSkipBeforeDeleting = CurInstructionNum;
goto TryAgain; // I wish I had a multi-level break here!
}
-
- // This pass didn't crash without this instruction, try the next
- // one.
- delete M;
}
}
if (!BugpointIsInterrupted) {
outs() << "\n*** Attempting to perform final cleanups: ";
Module *M = CloneModule(BD.getProgram());
- M = BD.performFinalCleanups(M, true);
+ M = BD.performFinalCleanups(M, true).release();
// Find out if the pass still crashes on the cleaned up program...
if (TestFn(BD, M)) {
}
} // end anonymous namespace
-/// deleteInstructionFromProgram - This method clones the current Program and
-/// deletes the specified instruction from the cloned module. It then runs a
-/// series of cleanup passes (ADCE and SimplifyCFG) to eliminate any code which
-/// depends on the value. The modified module is then returned.
-///
-Module *BugDriver::deleteInstructionFromProgram(const Instruction *I,
- unsigned Simplification) {
+std::unique_ptr<Module>
+BugDriver::deleteInstructionFromProgram(const Instruction *I,
+ unsigned Simplification) {
// FIXME, use vmap?
Module *Clone = CloneModule(Program);
Passes.push_back("simplifycfg"); // Delete dead control flow
Passes.push_back("verify");
- Module *New = runPassesOn(Clone, Passes);
+ std::unique_ptr<Module> New = runPassesOn(Clone, Passes);
delete Clone;
if (!New) {
errs() << "Instruction removal failed. Sorry. :( Please report a bug!\n";
return New;
}
-/// performFinalCleanups - This method clones the current Program and performs
-/// a series of cleanups intended to get rid of extra cruft on the module
-/// before handing it to the user.
-///
-Module *BugDriver::performFinalCleanups(Module *M, bool MayModifySemantics) {
+std::unique_ptr<Module>
+BugDriver::performFinalCleanups(Module *M, bool MayModifySemantics) {
// Make all functions external, so GlobalDCE doesn't delete them...
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
I->setLinkage(GlobalValue::ExternalLinkage);
else
CleanupPasses.push_back("deadargelim");
- Module *New = runPassesOn(M, CleanupPasses);
+ std::unique_ptr<Module> New = runPassesOn(M, CleanupPasses);
if (!New) {
errs() << "Final cleanups failed. Sorry. :( Please report a bug!\n";
- return M;
+ return nullptr;
}
delete M;
return New;
}
-
-/// ExtractLoop - Given a module, extract up to one loop from it into a new
-/// 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::unique_ptr<Module> BugDriver::extractLoop(Module *M) {
std::vector<std::string> LoopExtractPasses;
LoopExtractPasses.push_back("loop-extract-single");
- Module *NewM = runPassesOn(M, LoopExtractPasses);
+ std::unique_ptr<Module> NewM = runPassesOn(M, LoopExtractPasses);
if (!NewM) {
outs() << "*** Loop extraction failed: ";
EmitProgressBitcode(M, "loopextraction", true);
// to avoid taking forever.
static unsigned NumExtracted = 32;
if (M->size() == NewM->size() || --NumExtracted == 0) {
- delete NewM;
return nullptr;
} else {
assert(M->size() < NewM->size() && "Loop extract removed functions?");
// Basic Block Extraction Code
//===----------------------------------------------------------------------===//
-/// ExtractMappedBlocksFromModule - Extract all but the specified basic blocks
-/// into their own functions. The only detail is that M is actually a module
-/// cloned from the one the BBs are in, so some mapping needs to be performed.
-/// If this operation fails for some reason (ie the implementation is buggy),
-/// this function should return null, otherwise it returns a new Module.
-Module *BugDriver::ExtractMappedBlocksFromModule(const
- std::vector<BasicBlock*> &BBs,
- Module *M) {
+std::unique_ptr<Module>
+BugDriver::extractMappedBlocksFromModule(const std::vector<BasicBlock *> &BBs,
+ Module *M) {
SmallString<128> Filename;
int FD;
std::error_code EC = sys::fs::createUniqueFile(
std::vector<std::string> PI;
PI.push_back("extract-blocks");
- Module *Ret = runPassesOn(M, PI, false, 1, &ExtraArg);
+ std::unique_ptr<Module> Ret = runPassesOn(M, PI, false, 1, &ExtraArg);
sys::fs::remove(Filename.c_str());
// Ok, so now we know that the prefix passes work, try running the suffix
// passes on the result of the prefix passes.
//
- std::unique_ptr<Module> PrefixOutput(
- ParseInputFile(BitcodeResult, BD.getContext()));
+ std::unique_ptr<Module> PrefixOutput =
+ parseInputFile(BitcodeResult, BD.getContext());
if (!PrefixOutput) {
errs() << BD.getToolName() << ": Error reading bitcode file '"
<< BitcodeResult << "'!\n";
Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
MiscompiledFunctions,
VMap);
- Module *ToOptimizeLoopExtracted = BD.ExtractLoop(ToOptimize);
+ Module *ToOptimizeLoopExtracted = BD.extractLoop(ToOptimize).release();
if (!ToOptimizeLoopExtracted) {
// If the loop extractor crashed or if there were no extractible loops,
// then this chapter of our odyssey is over with.
// extraction.
AbstractInterpreter *AI = BD.switchToSafeInterpreter();
bool Failure;
- Module *New = TestMergedProgram(BD, ToOptimizeLoopExtracted, ToNotOptimize,
- false, Error, Failure);
+ Module *New = TestMergedProgram(BD, ToOptimizeLoopExtracted,
+ ToNotOptimize, false, Error, Failure);
if (!New)
return false;
<< OutputPrefix << "-loop-extract-fail-*.bc files.\n";
delete ToOptimize;
delete ToNotOptimize;
- delete ToOptimizeLoopExtracted;
return MadeChange;
}
delete ToOptimize;
// Try the extraction. If it doesn't work, then the block extractor crashed
// or something, in which case bugpoint can't chase down this possibility.
- if (Module *New = BD.ExtractMappedBlocksFromModule(BBsOnClone, ToOptimize)) {
+ if (std::unique_ptr<Module> New =
+ BD.extractMappedBlocksFromModule(BBsOnClone, ToOptimize)) {
delete ToOptimize;
// Run the predicate,
// note that the predicate will delete both input modules.
- bool Ret = TestFn(BD, New, ToNotOptimize, Error);
+ bool Ret = TestFn(BD, New.get(), ToNotOptimize, Error);
delete BD.swapProgramIn(Orig);
return Ret;
}
Module *ToExtract = SplitFunctionsOutOfModule(ProgClone,
MiscompiledFunctions,
VMap);
- Module *Extracted = BD.ExtractMappedBlocksFromModule(Blocks, ToExtract);
+ std::unique_ptr<Module> Extracted =
+ BD.extractMappedBlocksFromModule(Blocks, ToExtract);
if (!Extracted) {
// Weird, extraction should have worked.
errs() << "Nondeterministic problem extracting blocks??\n";
I->getFunctionType()));
std::string ErrorMsg;
- if (Linker::LinkModules(ProgClone, Extracted, Linker::DestroySource,
+ if (Linker::LinkModules(ProgClone, Extracted.get(), Linker::DestroySource,
&ErrorMsg)) {
errs() << BD.getToolName() << ": Error linking modules together:"
<< ErrorMsg << '\n';
exit(1);
}
- delete Extracted;
// Set the new program and delete the old one.
BD.setNewProgram(ProgClone);
// Run the optimization passes on ToOptimize, producing a transformed version
// of the functions being tested.
outs() << " Optimizing functions being tested: ";
- Module *Optimized = BD.runPassesOn(Test, BD.getPassesToRun(),
- /*AutoDebugCrashes*/true);
+ std::unique_ptr<Module> Optimized = BD.runPassesOn(Test, BD.getPassesToRun(),
+ /*AutoDebugCrashes*/ true);
outs() << "done.\n";
delete Test;
outs() << " Checking to see if the merged program executes correctly: ";
bool Broken;
- Module *New = TestMergedProgram(BD, Optimized, Safe, true, Error, Broken);
+ Module *New =
+ TestMergedProgram(BD, Optimized.get(), Safe, true, Error, Broken);
if (New) {
outs() << (Broken ? " nope.\n" : " yup.\n");
// Delete the original and set the new program.
static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,
Module *Safe) {
// Clean up the modules, removing extra cruft that we don't need anymore...
- Test = BD.performFinalCleanups(Test);
+ Test = BD.performFinalCleanups(Test).release();
// If we are executing the JIT, we have several nasty issues to take care of.
if (!BD.isExecutingJIT()) return;
}
-/// runPassesOn - Carefully run the specified set of pass on the specified
-/// module, returning the transformed module on success, or a null pointer on
-/// failure.
-Module *BugDriver::runPassesOn(Module *M,
- const std::vector<std::string> &Passes,
- bool AutoDebugCrashes, unsigned NumExtraArgs,
- const char * const *ExtraArgs) {
+std::unique_ptr<Module>
+BugDriver::runPassesOn(Module *M, const std::vector<std::string> &Passes,
+ bool AutoDebugCrashes, unsigned NumExtraArgs,
+ const char *const *ExtraArgs) {
std::string BitcodeResult;
if (runPasses(M, Passes, BitcodeResult, false/*delete*/, true/*quiet*/,
NumExtraArgs, ExtraArgs)) {
return nullptr;
}
- Module *Ret = ParseInputFile(BitcodeResult, Context);
+ std::unique_ptr<Module> Ret = parseInputFile(BitcodeResult, Context);
if (!Ret) {
errs() << getToolName() << ": Error reading bitcode file '"
<< BitcodeResult << "'!\n";