#include "llvm/Config/config.h" // for HAVE_LINK_R
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
};
}
+static void diagnosticHandler(const DiagnosticInfo &DI) {
+ DiagnosticPrinterRawOStream DP(errs());
+ DI.print(DP);
+ errs() << '\n';
+ if (DI.getSeverity() == DS_Error)
+ exit(1);
+}
+
/// TestMergedProgram - Given two modules, link them together and run the
/// program, checking to see if the program matches the diff. If there is
/// an error, return NULL. If not, return the merged module. The Broken argument
bool &Broken) {
// Link the two portions of the program back to together.
if (!DeleteInputs) {
- M1 = CloneModule(M1);
- M2 = CloneModule(M2);
+ M1 = CloneModule(M1).release();
+ M2 = CloneModule(M2).release();
}
- if (Linker::LinkModules(M1, M2))
+ if (Linker::linkModules(*M1, *M2, diagnosticHandler))
exit(1);
delete M2; // We are done with this module.
// we can conclude that a function triggers the bug when in fact one
// needs a larger set of original functions to do so.
ValueToValueMapTy VMap;
- Module *Clone = CloneModule(BD.getProgram(), VMap);
+ Module *Clone = CloneModule(BD.getProgram(), VMap).release();
Module *Orig = BD.swapProgramIn(Clone);
std::vector<Function*> FuncsOnClone;
// Split the module into the two halves of the program we want.
VMap.clear();
- Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap);
- Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, FuncsOnClone,
- VMap);
+ Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap).release();
+ Module *ToOptimize =
+ SplitFunctionsOutOfModule(ToNotOptimize, FuncsOnClone, VMap).release();
// Run the predicate, note that the predicate will delete both input modules.
bool Broken = TestFn(BD, ToOptimize, ToNotOptimize, Error);
if (BugpointIsInterrupted) return MadeChange;
ValueToValueMapTy VMap;
- Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap);
- Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
- MiscompiledFunctions,
- VMap);
- Module *ToOptimizeLoopExtracted = BD.extractLoop(ToOptimize).release();
+ std::unique_ptr<Module> ToNotOptimize = CloneModule(BD.getProgram(), VMap);
+ Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize.get(),
+ MiscompiledFunctions, VMap)
+ .release();
+ std::unique_ptr<Module> ToOptimizeLoopExtracted =
+ BD.extractLoop(ToOptimize);
if (!ToOptimizeLoopExtracted) {
// If the loop extractor crashed or if there were no extractible loops,
// then this chapter of our odyssey is over with.
- delete ToNotOptimize;
delete ToOptimize;
return MadeChange;
}
// extraction.
AbstractInterpreter *AI = BD.switchToSafeInterpreter();
bool Failure;
- Module *New = TestMergedProgram(BD, ToOptimizeLoopExtracted,
- ToNotOptimize, false, Error, Failure);
+ Module *New = TestMergedProgram(BD, ToOptimizeLoopExtracted.get(),
+ ToNotOptimize.get(), false, Error, Failure);
if (!New)
return false;
errs() << " Continuing on with un-loop-extracted version.\n";
BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-tno.bc",
- ToNotOptimize);
+ ToNotOptimize.get());
BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to.bc",
ToOptimize);
BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to-le.bc",
- ToOptimizeLoopExtracted);
+ ToOptimizeLoopExtracted.get());
errs() << "Please submit the "
<< OutputPrefix << "-loop-extract-fail-*.bc files.\n";
delete ToOptimize;
- delete ToNotOptimize;
return MadeChange;
}
delete ToOptimize;
outs() << " Testing after loop extraction:\n";
// Clone modules, the tester function will free them.
- Module *TOLEBackup = CloneModule(ToOptimizeLoopExtracted, VMap);
- Module *TNOBackup = CloneModule(ToNotOptimize, VMap);
+ std::unique_ptr<Module> TOLEBackup =
+ CloneModule(ToOptimizeLoopExtracted.get(), VMap);
+ std::unique_ptr<Module> TNOBackup = CloneModule(ToNotOptimize.get(), VMap);
for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i)
MiscompiledFunctions[i] = cast<Function>(VMap[MiscompiledFunctions[i]]);
- Failure = TestFn(BD, ToOptimizeLoopExtracted, ToNotOptimize, Error);
+ Failure =
+ TestFn(BD, ToOptimizeLoopExtracted.get(), ToNotOptimize.get(), Error);
if (!Error.empty())
return false;
- ToOptimizeLoopExtracted = TOLEBackup;
- ToNotOptimize = TNOBackup;
+ ToOptimizeLoopExtracted = std::move(TOLEBackup);
+ ToNotOptimize = std::move(TNOBackup);
if (!Failure) {
outs() << "*** Loop extraction masked the problem. Undoing.\n";
MisCompFunctions.emplace_back(F->getName(), F->getFunctionType());
}
- if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted))
+ if (Linker::linkModules(*ToNotOptimize, *ToOptimizeLoopExtracted,
+ diagnosticHandler))
exit(1);
MiscompiledFunctions.clear();
MiscompiledFunctions.push_back(NewF);
}
- delete ToOptimizeLoopExtracted;
- BD.setNewProgram(ToNotOptimize);
+ BD.setNewProgram(ToNotOptimize.release());
return MadeChange;
}
// extraction both didn't break the program, and didn't mask the problem.
// Replace the current program with the loop extracted version, and try to
// extract another loop.
- if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted))
+ if (Linker::linkModules(*ToNotOptimize, *ToOptimizeLoopExtracted,
+ diagnosticHandler))
exit(1);
- delete ToOptimizeLoopExtracted;
-
// All of the Function*'s in the MiscompiledFunctions list are in the old
// module. Update this list to include all of the functions in the
// optimized and loop extracted module.
MiscompiledFunctions.push_back(NewF);
}
- BD.setNewProgram(ToNotOptimize);
+ BD.setNewProgram(ToNotOptimize.release());
MadeChange = true;
}
}
// Split the module into the two halves of the program we want.
ValueToValueMapTy VMap;
- Module *Clone = CloneModule(BD.getProgram(), VMap);
+ Module *Clone = CloneModule(BD.getProgram(), VMap).release();
Module *Orig = BD.swapProgramIn(Clone);
std::vector<Function*> FuncsOnClone;
std::vector<BasicBlock*> BBsOnClone;
}
VMap.clear();
- Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap);
- Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
- FuncsOnClone,
- VMap);
+ Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap).release();
+ Module *ToOptimize =
+ SplitFunctionsOutOfModule(ToNotOptimize, FuncsOnClone, VMap).release();
// 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.
}
ValueToValueMapTy VMap;
- Module *ProgClone = CloneModule(BD.getProgram(), VMap);
- Module *ToExtract = SplitFunctionsOutOfModule(ProgClone,
- MiscompiledFunctions,
- VMap);
+ Module *ProgClone = CloneModule(BD.getProgram(), VMap).release();
+ Module *ToExtract =
+ SplitFunctionsOutOfModule(ProgClone, MiscompiledFunctions, VMap)
+ .release();
std::unique_ptr<Module> Extracted =
BD.extractMappedBlocksFromModule(Blocks, ToExtract);
if (!Extracted) {
if (!I->isDeclaration())
MisCompFunctions.emplace_back(I->getName(), I->getFunctionType());
- if (Linker::LinkModules(ProgClone, Extracted.get()))
+ if (Linker::linkModules(*ProgClone, *Extracted, diagnosticHandler))
exit(1);
// Set the new program and delete the old one.
// Output a bunch of bitcode files for the user...
outs() << "Outputting reduced bitcode files which expose the problem:\n";
ValueToValueMapTy VMap;
- Module *ToNotOptimize = CloneModule(getProgram(), VMap);
- Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
- MiscompiledFunctions,
- VMap);
+ Module *ToNotOptimize = CloneModule(getProgram(), VMap).release();
+ Module *ToOptimize =
+ SplitFunctionsOutOfModule(ToNotOptimize, MiscompiledFunctions, VMap)
+ .release();
outs() << " Non-optimized portion: ";
EmitProgressBitcode(ToNotOptimize, "tonotoptimize", true);
// Split the module into the two halves of the program we want.
ValueToValueMapTy VMap;
- Module *ToNotCodeGen = CloneModule(getProgram(), VMap);
- Module *ToCodeGen = SplitFunctionsOutOfModule(ToNotCodeGen, Funcs, VMap);
+ Module *ToNotCodeGen = CloneModule(getProgram(), VMap).release();
+ Module *ToCodeGen =
+ SplitFunctionsOutOfModule(ToNotCodeGen, Funcs, VMap).release();
// Condition the modules
CleanupAndPrepareModules(*this, ToCodeGen, ToNotCodeGen);