#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));
- class ReduceMiscompilingPasses : public ListReducer<const PassInfo*> {
+ class ReduceMiscompilingPasses : public ListReducer<std::string> {
BugDriver &BD;
public:
ReduceMiscompilingPasses(BugDriver &bd) : BD(bd) {}
- virtual TestResult doTest(std::vector<const PassInfo*> &Prefix,
- std::vector<const PassInfo*> &Suffix,
+ virtual TestResult doTest(std::vector<std::string> &Prefix,
+ std::vector<std::string> &Suffix,
std::string &Error);
};
}
/// group, see if they still break the program.
///
ReduceMiscompilingPasses::TestResult
-ReduceMiscompilingPasses::doTest(std::vector<const PassInfo*> &Prefix,
- std::vector<const PassInfo*> &Suffix,
+ReduceMiscompilingPasses::doTest(std::vector<std::string> &Prefix,
+ std::vector<std::string> &Suffix,
std::string &Error) {
// First, run the program with just the Suffix passes. If it is still broken
// with JUST the kept passes, discard the prefix passes.
<< "' compiles correctly: ";
std::string BitcodeResult;
- if (BD.runPasses(Suffix, BitcodeResult, false/*delete*/, true/*quiet*/)) {
+ if (BD.runPasses(BD.getProgram(), Suffix, BitcodeResult, false/*delete*/,
+ true/*quiet*/)) {
errs() << " Error running this sequence of passes"
<< " on the input program!\n";
BD.setPassesToRun(Suffix);
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);
// kept passes, we can update our bitcode file to include the result of the
// prefix passes, then discard the prefix passes.
//
- if (BD.runPasses(Prefix, BitcodeResult, false/*delete*/, true/*quiet*/)) {
+ if (BD.runPasses(BD.getProgram(), Prefix, BitcodeResult, false/*delete*/,
+ true/*quiet*/)) {
errs() << " Error running this sequence of passes"
<< " on the input program!\n";
BD.setPassesToRun(Prefix);
<< getPassesString(Prefix) << "' passes: ";
OwningPtr<Module> OriginalInput(BD.swapProgramIn(PrefixOutput.take()));
- if (BD.runPasses(Suffix, BitcodeResult, false/*delete*/, true/*quiet*/)) {
+ if (BD.runPasses(BD.getProgram(), Suffix, BitcodeResult, false/*delete*/,
+ true/*quiet*/)) {
errs() << " Error running this sequence of passes"
<< " on the input program!\n";
BD.setPassesToRun(Suffix);
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);
// a function, we want to continue with the original function. Otherwise
// we can conclude that a function triggers the bug when in fact one
// needs a larger set of original functions to do so.
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *Clone = CloneModule(BD.getProgram(), VMap);
Module *Orig = BD.swapProgramIn(Clone);
bool MadeChange = false;
while (1) {
if (BugpointIsInterrupted) return MadeChange;
-
- ValueMap<const Value*, Value*> VMap;
+
+ ValueToValueMapTy VMap;
Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap);
Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
MiscompiledFunctions,
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);
}
outs() << '\n';
// Split the module into the two halves of the program we want.
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *Clone = CloneModule(BD.getProgram(), VMap);
Module *Orig = BD.swapProgramIn(Clone);
std::vector<Function*> FuncsOnClone;
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(),
return false;
}
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *ProgClone = CloneModule(BD.getProgram(), VMap);
Module *ToExtract = SplitFunctionsOutOfModule(ProgClone,
MiscompiledFunctions,
// 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;
// Output a bunch of bitcode files for the user...
outs() << "Outputting reduced bitcode files which expose the problem:\n";
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *ToNotOptimize = CloneModule(getProgram(), VMap);
Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
MiscompiledFunctions,
// 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 =
new StoreInst(CastedResolver, Cache, LookupBB);
BranchInst::Create(DoCallBB, LookupBB);
- PHINode *FuncPtr = PHINode::Create(NullPtr->getType(),
+ PHINode *FuncPtr = PHINode::Create(NullPtr->getType(), 2,
"fp", DoCallBB);
FuncPtr->addIncoming(CastedResolver, LookupBB);
FuncPtr->addIncoming(CachedVal, EntryBB);
// 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);
}
}
delete Test;
- FileRemover TestModuleBCRemover(TestModuleBC, !SaveTemps);
+ FileRemover TestModuleBCRemover(TestModuleBC.str(), !SaveTemps);
// Make the shared library
sys::Path SafeModuleBC("bugpoint.safe.bc");
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.
return true;
// Split the module into the two halves of the program we want.
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *ToNotCodeGen = CloneModule(getProgram(), VMap);
Module *ToCodeGen = SplitFunctionsOutOfModule(ToNotCodeGen, Funcs, VMap);