#include "BugDriver.h"
#include "ListReducer.h"
#include "ToolRunner.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Instructions.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Config/config.h" // for HAVE_LINK_R
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
#include "llvm/Linker.h"
-#include "llvm/Module.h"
#include "llvm/Pass.h"
-#include "llvm/Analysis/Verifier.h"
-#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileUtilities.h"
-#include "llvm/Config/config.h" // for HAVE_LINK_R
+#include "llvm/Transforms/Utils/Cloning.h"
using namespace llvm;
namespace llvm {
}
namespace {
- static llvm::cl::opt<bool>
- DisableLoopExtraction("disable-loop-extraction",
+ static llvm::cl::opt<bool>
+ DisableLoopExtraction("disable-loop-extraction",
cl::desc("Don't extract loops when searching for miscompilations"),
cl::init(false));
- static llvm::cl::opt<bool>
- DisableBlockExtraction("disable-block-extraction",
+ static llvm::cl::opt<bool>
+ DisableBlockExtraction("disable-block-extraction",
cl::desc("Don't extract blocks when searching for miscompilations"),
cl::init(false));
BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false);
exit(BD.debugOptimizerCrash());
}
-
+
// Check to see if the finished program matches the reference output...
bool Diff = BD.diffProgram(BD.getProgram(), BitcodeResult, "",
true /*delete bitcode*/, &Error);
return InternalError;
if (Diff) {
outs() << " nope.\n";
- sys::Path(BitcodeResult).eraseFromDisk();
+ sys::fs::remove(BitcodeResult);
return KeepPrefix;
}
outs() << " yup.\n"; // No miscompilation!
//
OwningPtr<Module> PrefixOutput(ParseInputFile(BitcodeResult,
BD.getContext()));
- if (PrefixOutput == 0) {
+ if (!PrefixOutput) {
errs() << BD.getToolName() << ": Error reading bitcode file '"
<< BitcodeResult << "'!\n";
exit(1);
}
- sys::Path(BitcodeResult).eraseFromDisk(); // No longer need the file on disk
+ sys::fs::remove(BitcodeResult);
// Don't check if there are no passes in the suffix.
if (Suffix.empty())
M1 = CloneModule(M1);
M2 = CloneModule(M2);
}
- if (Linker::LinkModules(M1, M2, &ErrorMsg)) {
+ if (Linker::LinkModules(M1, M2, Linker::DestroySource, &ErrorMsg)) {
errs() << BD.getToolName() << ": Error linking modules together:"
<< ErrorMsg << '\n';
exit(1);
bool MadeChange = false;
while (1) {
if (BugpointIsInterrupted) return MadeChange;
-
+
ValueToValueMapTy VMap;
Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap);
Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to-le.bc",
ToOptimizeLoopExtracted);
- errs() << "Please submit the "
+ errs() << "Please submit the "
<< OutputPrefix << "-loop-extract-fail-*.bc files.\n";
delete ToOptimize;
delete ToNotOptimize;
outs() << "*** Loop extraction successful!\n";
- std::vector<std::pair<std::string, const FunctionType*> > MisCompFunctions;
+ std::vector<std::pair<std::string, FunctionType*> > MisCompFunctions;
for (Module::iterator I = ToOptimizeLoopExtracted->begin(),
E = ToOptimizeLoopExtracted->end(); I != E; ++I)
if (!I->isDeclaration())
// Replace the current program with the loop extracted version, and try to
// extract another loop.
std::string ErrorMsg;
- if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted, &ErrorMsg)){
+ if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted,
+ Linker::DestroySource, &ErrorMsg)){
errs() << BD.getToolName() << ": Error linking modules together:"
<< ErrorMsg << '\n';
exit(1);
MiscompiledFunctions.clear();
for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) {
Function *NewF = ToNotOptimize->getFunction(MisCompFunctions[i].first);
-
+
assert(NewF && "Function not found??");
- assert(NewF->getFunctionType() == MisCompFunctions[i].second &&
- "found wrong function type?");
MiscompiledFunctions.push_back(NewF);
}
std::vector<Function*> &MiscompiledFunctions,
std::string &Error) {
if (BugpointIsInterrupted) return false;
-
+
std::vector<BasicBlock*> Blocks;
for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i)
for (Function::iterator I = MiscompiledFunctions[i]->begin(),
// together.
delete ToExtract;
- std::vector<std::pair<std::string, const FunctionType*> > MisCompFunctions;
+ std::vector<std::pair<std::string, FunctionType*> > MisCompFunctions;
for (Module::iterator I = Extracted->begin(), E = Extracted->end();
I != E; ++I)
if (!I->isDeclaration())
I->getFunctionType()));
std::string ErrorMsg;
- if (Linker::LinkModules(ProgClone, Extracted, &ErrorMsg)) {
+ if (Linker::LinkModules(ProgClone, Extracted, Linker::DestroySource,
+ &ErrorMsg)) {
errs() << BD.getToolName() << ": Error linking modules together:"
<< ErrorMsg << '\n';
exit(1);
for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) {
Function *NewF = ProgClone->getFunction(MisCompFunctions[i].first);
assert(NewF && "Function not found??");
- assert(NewF->getFunctionType() == MisCompFunctions[i].second &&
- "Function has wrong type??");
MiscompiledFunctions.push_back(NewF);
}
if (!BugpointIsInterrupted)
ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions,
Error);
- if (!Error.empty())
+ if (!Error.empty()) {
+ errs() << "\n***Cannot reduce functions: ";
return MiscompiledFunctions;
-
+ }
outs() << "\n*** The following function"
<< (MiscompiledFunctions.size() == 1 ? " is" : "s are")
<< " being miscompiled: ";
<< getPassesString(getPassesToRun()) << '\n';
EmitProgressBitcode(Program, "passinput");
- std::vector<Function *> MiscompiledFunctions =
+ std::vector<Function *> MiscompiledFunctions =
DebugAMiscompilation(*this, TestOptimizer, *Error);
if (!Error->empty())
return;
// Call the old main function and return its result
BasicBlock *BB = BasicBlock::Create(Safe->getContext(), "entry", newMain);
- CallInst *call = CallInst::Create(oldMainProto, args.begin(), args.end(),
- "", BB);
+ CallInst *call = CallInst::Create(oldMainProto, args, "", BB);
// If the type of old function wasn't void, return value of call
ReturnInst::Create(Safe->getContext(), call, BB);
// Don't forward functions which are external in the test module too.
if (TestFn && !TestFn->isDeclaration()) {
// 1. Add a string constant with its name to the global file
- Constant *InitArray = ConstantArray::get(F->getContext(), F->getName());
+ Constant *InitArray =
+ ConstantDataArray::getString(F->getContext(), F->getName());
GlobalVariable *funcName =
new GlobalVariable(*Safe, InitArray->getType(), true /*isConstant*/,
GlobalValue::InternalLinkage, InitArray,
// GetElementPtr *funcName, ulong 0, ulong 0
std::vector<Constant*> GEPargs(2,
Constant::getNullValue(Type::getInt32Ty(F->getContext())));
- Value *GEP =
- ConstantExpr::getGetElementPtr(funcName, &GEPargs[0], 2);
+ Value *GEP = ConstantExpr::getGetElementPtr(funcName, GEPargs);
std::vector<Value*> ResolverArgs;
ResolverArgs.push_back(GEP);
// Create a new global to hold the cached function pointer.
Constant *NullPtr = ConstantPointerNull::get(F->getType());
GlobalVariable *Cache =
- new GlobalVariable(*F->getParent(), F->getType(),
+ new GlobalVariable(*F->getParent(), F->getType(),
false, GlobalValue::InternalLinkage,
NullPtr,F->getName()+".fpcache");
// Construct a new stub function that will re-route calls to F
- const FunctionType *FuncTy = F->getFunctionType();
+ FunctionType *FuncTy = F->getFunctionType();
Function *FuncWrapper = Function::Create(FuncTy,
GlobalValue::InternalLinkage,
F->getName() + "_wrapper",
//
// call resolver(GetElementPtr...)
CallInst *Resolver =
- CallInst::Create(resolverFunc, ResolverArgs.begin(),
- ResolverArgs.end(), "resolver", LookupBB);
+ CallInst::Create(resolverFunc, ResolverArgs, "resolver", LookupBB);
// Cast the result from the resolver to correctly-typed function.
CastInst *CastedResolver =
// Pass on the arguments to the real function, return its result
if (F->getReturnType()->isVoidTy()) {
- CallInst::Create(FuncPtr, Args.begin(), Args.end(), "", DoCallBB);
+ CallInst::Create(FuncPtr, Args, "", DoCallBB);
ReturnInst::Create(F->getContext(), DoCallBB);
} else {
- CallInst *Call = CallInst::Create(FuncPtr, Args.begin(), Args.end(),
+ CallInst *Call = CallInst::Create(FuncPtr, Args,
"retval", DoCallBB);
ReturnInst::Create(F->getContext(),Call, DoCallBB);
}
std::string &Error) {
CleanupAndPrepareModules(BD, Test, Safe);
- sys::Path TestModuleBC("bugpoint.test.bc");
- std::string ErrMsg;
- if (TestModuleBC.makeUnique(true, &ErrMsg)) {
+ SmallString<128> TestModuleBC;
+ int TestModuleFD;
+ error_code EC = sys::fs::unique_file("bugpoint.test-%%%%%%%.bc", TestModuleFD,
+ TestModuleBC);
+ if (EC) {
errs() << BD.getToolName() << "Error making unique filename: "
- << ErrMsg << "\n";
+ << EC.message() << "\n";
exit(1);
}
- if (BD.writeProgramToFile(TestModuleBC.str(), Test)) {
+ if (BD.writeProgramToFile(TestModuleBC.str(), TestModuleFD, Test)) {
errs() << "Error writing bitcode to `" << TestModuleBC.str()
<< "'\nExiting.";
exit(1);
}
delete Test;
- FileRemover TestModuleBCRemover(TestModuleBC, !SaveTemps);
+ FileRemover TestModuleBCRemover(TestModuleBC.str(), !SaveTemps);
// Make the shared library
- sys::Path SafeModuleBC("bugpoint.safe.bc");
- if (SafeModuleBC.makeUnique(true, &ErrMsg)) {
+ SmallString<128> SafeModuleBC;
+ int SafeModuleFD;
+ EC = sys::fs::unique_file("bugpoint.safe-%%%%%%%.bc", SafeModuleFD,
+ SafeModuleBC);
+ if (EC) {
errs() << BD.getToolName() << "Error making unique filename: "
- << ErrMsg << "\n";
+ << EC.message() << "\n";
exit(1);
}
- if (BD.writeProgramToFile(SafeModuleBC.str(), Safe)) {
+ if (BD.writeProgramToFile(SafeModuleBC.str(), SafeModuleFD, Safe)) {
errs() << "Error writing bitcode to `" << SafeModuleBC.str()
<< "'\nExiting.";
exit(1);
}
- FileRemover SafeModuleBCRemover(SafeModuleBC, !SaveTemps);
+ FileRemover SafeModuleBCRemover(SafeModuleBC.str(), !SaveTemps);
std::string SharedObject = BD.compileSharedObject(SafeModuleBC.str(), Error);
if (!Error.empty())
return false;
delete Safe;
- FileRemover SharedObjectRemover(sys::Path(SharedObject), !SaveTemps);
+ FileRemover SharedObjectRemover(SharedObject, !SaveTemps);
// Run the code generator on the `Test' code, loading the shared library.
// The function returns whether or not the new output differs from reference.
// Condition the modules
CleanupAndPrepareModules(*this, ToCodeGen, ToNotCodeGen);
- sys::Path TestModuleBC("bugpoint.test.bc");
- std::string ErrMsg;
- if (TestModuleBC.makeUnique(true, &ErrMsg)) {
+ SmallString<128> TestModuleBC;
+ int TestModuleFD;
+ error_code EC = sys::fs::unique_file("bugpoint.test-%%%%%%%.bc", TestModuleFD,
+ TestModuleBC);
+ if (EC) {
errs() << getToolName() << "Error making unique filename: "
- << ErrMsg << "\n";
+ << EC.message() << "\n";
exit(1);
}
- if (writeProgramToFile(TestModuleBC.str(), ToCodeGen)) {
+ if (writeProgramToFile(TestModuleBC.str(), TestModuleFD, ToCodeGen)) {
errs() << "Error writing bitcode to `" << TestModuleBC.str()
<< "'\nExiting.";
exit(1);
delete ToCodeGen;
// Make the shared library
- sys::Path SafeModuleBC("bugpoint.safe.bc");
- if (SafeModuleBC.makeUnique(true, &ErrMsg)) {
+ SmallString<128> SafeModuleBC;
+ int SafeModuleFD;
+ EC = sys::fs::unique_file("bugpoint.safe-%%%%%%%.bc", SafeModuleFD,
+ SafeModuleBC);
+ if (EC) {
errs() << getToolName() << "Error making unique filename: "
- << ErrMsg << "\n";
+ << EC.message() << "\n";
exit(1);
}
- if (writeProgramToFile(SafeModuleBC.str(), ToNotCodeGen)) {
+ if (writeProgramToFile(SafeModuleBC.str(), SafeModuleFD, ToNotCodeGen)) {
errs() << "Error writing bitcode to `" << SafeModuleBC.str()
<< "'\nExiting.";
exit(1);