diff options
Diffstat (limited to 'tools/bugpoint')
-rw-r--r-- | tools/bugpoint/BugDriver.cpp | 4 | ||||
-rw-r--r-- | tools/bugpoint/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tools/bugpoint/CrashDebugger.cpp | 11 | ||||
-rw-r--r-- | tools/bugpoint/ExecutionDriver.cpp | 50 | ||||
-rw-r--r-- | tools/bugpoint/ExtractFunction.cpp | 62 | ||||
-rw-r--r-- | tools/bugpoint/LLVMBuild.txt | 22 | ||||
-rw-r--r-- | tools/bugpoint/Makefile | 9 | ||||
-rw-r--r-- | tools/bugpoint/Miscompilation.cpp | 3 | ||||
-rw-r--r-- | tools/bugpoint/OptimizerDriver.cpp | 12 | ||||
-rw-r--r-- | tools/bugpoint/ToolRunner.cpp | 93 | ||||
-rw-r--r-- | tools/bugpoint/ToolRunner.h | 1 | ||||
-rw-r--r-- | tools/bugpoint/bugpoint.cpp | 1 |
12 files changed, 109 insertions, 161 deletions
diff --git a/tools/bugpoint/BugDriver.cpp b/tools/bugpoint/BugDriver.cpp index 677d178..6b219bf 100644 --- a/tools/bugpoint/BugDriver.cpp +++ b/tools/bugpoint/BugDriver.cpp @@ -87,7 +87,7 @@ Module *llvm::ParseInputFile(const std::string &Filename, SMDiagnostic Err; Module *Result = ParseIRFile(Filename, Err, Ctxt); if (!Result) - Err.Print("bugpoint", errs()); + Err.print("bugpoint", errs()); // If we don't have an override triple, use the first one to configure // bugpoint, or use the host triple if none provided. @@ -96,7 +96,7 @@ Module *llvm::ParseInputFile(const std::string &Filename, Triple TheTriple(Result->getTargetTriple()); if (TheTriple.getTriple().empty()) - TheTriple.setTriple(sys::getHostTriple()); + TheTriple.setTriple(sys::getDefaultTargetTriple()); TargetTriple.setTriple(TheTriple.getTriple()); } diff --git a/tools/bugpoint/CMakeLists.txt b/tools/bugpoint/CMakeLists.txt index e06feb1..ee2235b 100644 --- a/tools/bugpoint/CMakeLists.txt +++ b/tools/bugpoint/CMakeLists.txt @@ -1,5 +1,5 @@ set(LLVM_LINK_COMPONENTS asmparser instrumentation scalaropts ipo - linker bitreader bitwriter) + linker bitreader bitwriter vectorize) add_llvm_tool(bugpoint BugDriver.cpp diff --git a/tools/bugpoint/CrashDebugger.cpp b/tools/bugpoint/CrashDebugger.cpp index f19ef62..aed16f4 100644 --- a/tools/bugpoint/CrashDebugger.cpp +++ b/tools/bugpoint/CrashDebugger.cpp @@ -169,7 +169,7 @@ ReduceCrashingGlobalVariables::TestGlobalVariables( return false; } -namespace llvm { +namespace { /// ReduceCrashingFunctions reducer - This works by removing functions and /// seeing if the program still crashes. If it does, then keep the newer, /// smaller program. @@ -401,7 +401,8 @@ bool ReduceCrashingInstructions::TestInsts(std::vector<const Instruction*> for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE; ++FI) for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E;) { Instruction *Inst = I++; - if (!Instructions.count(Inst) && !isa<TerminatorInst>(Inst)) { + if (!Instructions.count(Inst) && !isa<TerminatorInst>(Inst) && + !isa<LandingPadInst>(Inst)) { if (!Inst->getType()->isVoidTy()) Inst->replaceAllUsesWith(UndefValue::get(Inst->getType())); Inst->eraseFromParent(); @@ -568,12 +569,15 @@ static bool DebugACrash(BugDriver &BD, for (Function::const_iterator BI = FI->begin(), E = FI->end(); BI != E; ++BI) for (BasicBlock::const_iterator I = BI->begin(), E = --BI->end(); - I != E; ++I, ++CurInstructionNum) + I != E; ++I, ++CurInstructionNum) { if (InstructionsToSkipBeforeDeleting) { --InstructionsToSkipBeforeDeleting; } else { if (BugpointIsInterrupted) goto ExitLoops; + if (isa<LandingPadInst>(I)) + continue; + outs() << "Checking instruction: " << *I; Module *M = BD.deleteInstructionFromProgram(I, Simplification); @@ -590,6 +594,7 @@ static bool DebugACrash(BugDriver &BD, // one. delete M; } + } if (InstructionsToSkipBeforeDeleting) { InstructionsToSkipBeforeDeleting = 0; diff --git a/tools/bugpoint/ExecutionDriver.cpp b/tools/bugpoint/ExecutionDriver.cpp index 77c01ac..218a559 100644 --- a/tools/bugpoint/ExecutionDriver.cpp +++ b/tools/bugpoint/ExecutionDriver.cpp @@ -28,8 +28,7 @@ namespace { // for miscompilation. // enum OutputType { - AutoPick, RunLLI, RunJIT, RunLLC, RunLLCIA, RunCBE, CBE_bug, LLC_Safe, - CompileCustom, Custom + AutoPick, RunLLI, RunJIT, RunLLC, RunLLCIA, LLC_Safe, CompileCustom, Custom }; cl::opt<double> @@ -48,8 +47,6 @@ namespace { clEnumValN(RunLLC, "run-llc", "Compile with LLC"), clEnumValN(RunLLCIA, "run-llc-ia", "Compile with LLC with integrated assembler"), - clEnumValN(RunCBE, "run-cbe", "Compile with CBE"), - clEnumValN(CBE_bug,"cbe-bug", "Find CBE bugs"), clEnumValN(LLC_Safe, "llc-safe", "Use LLC for all"), clEnumValN(CompileCustom, "compile-custom", "Use -compile-command to define a command to " @@ -64,7 +61,6 @@ namespace { SafeInterpreterSel(cl::desc("Specify \"safe\" i.e. known-good backend:"), cl::values(clEnumValN(AutoPick, "safe-auto", "Use best guess"), clEnumValN(RunLLC, "safe-run-llc", "Compile with LLC"), - clEnumValN(RunCBE, "safe-run-cbe", "Compile with CBE"), clEnumValN(Custom, "safe-run-custom", "Use -exec-command to define a command to execute " "the bitcode. Useful for cross-compilation."), @@ -154,10 +150,6 @@ bool BugDriver::initializeExecutionEnvironment() { switch (InterpreterSel) { case AutoPick: - InterpreterSel = RunCBE; - Interpreter = - AbstractInterpreter::createCBE(getToolName(), Message, GCCBinary, - &ToolArgv, &GCCToolArgv); if (!Interpreter) { InterpreterSel = RunJIT; Interpreter = AbstractInterpreter::createJIT(getToolName(), Message, @@ -195,12 +187,6 @@ bool BugDriver::initializeExecutionEnvironment() { Interpreter = AbstractInterpreter::createJIT(getToolName(), Message, &ToolArgv); break; - case RunCBE: - case CBE_bug: - Interpreter = AbstractInterpreter::createCBE(getToolName(), Message, - GCCBinary, &ToolArgv, - &GCCToolArgv); - break; case CompileCustom: Interpreter = AbstractInterpreter::createCustomCompiler(Message, CustomCompileCommand); @@ -209,9 +195,6 @@ bool BugDriver::initializeExecutionEnvironment() { Interpreter = AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand); break; - default: - Message = "Sorry, this back-end is not supported by bugpoint right now!\n"; - break; } if (!Interpreter) errs() << Message; @@ -224,17 +207,6 @@ bool BugDriver::initializeExecutionEnvironment() { std::vector<std::string> SafeToolArgs = SafeToolArgv; switch (SafeInterpreterSel) { case AutoPick: - // In "cbe-bug" mode, default to using LLC as the "safe" backend. - if (!SafeInterpreter && - InterpreterSel == CBE_bug) { - SafeInterpreterSel = RunLLC; - SafeToolArgs.push_back("--relocation-model=pic"); - SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, - GCCBinary, - &SafeToolArgs, - &GCCToolArgv); - } - // In "llc-safe" mode, default to using LLC as the "safe" backend. if (!SafeInterpreter && InterpreterSel == LLC_Safe) { @@ -246,17 +218,6 @@ bool BugDriver::initializeExecutionEnvironment() { &GCCToolArgv); } - // Pick a backend that's different from the test backend. The JIT and - // LLC backends share a lot of code, so prefer to use the CBE as the - // safe back-end when testing them. - if (!SafeInterpreter && - InterpreterSel != RunCBE) { - SafeInterpreterSel = RunCBE; - SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message, - GCCBinary, - &SafeToolArgs, - &GCCToolArgv); - } if (!SafeInterpreter && InterpreterSel != RunLLC && InterpreterSel != RunJIT) { @@ -280,11 +241,6 @@ bool BugDriver::initializeExecutionEnvironment() { &GCCToolArgv, SafeInterpreterSel == RunLLCIA); break; - case RunCBE: - SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message, - GCCBinary, &SafeToolArgs, - &GCCToolArgv); - break; case Custom: SafeInterpreter = AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand); @@ -462,8 +418,8 @@ bool BugDriver::createReferenceFile(Module *M, const std::string &Filename) { errs() << Error; if (Interpreter != SafeInterpreter) { errs() << "*** There is a bug running the \"safe\" backend. Either" - << " debug it (for example with the -run-cbe bugpoint option," - << " if CBE is being used as the \"safe\" backend), or fix the" + << " debug it (for example with the -run-jit bugpoint option," + << " if JIT is being used as the \"safe\" backend), or fix the" << " error some other way.\n"; } return false; diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp index 73b65ca..ac8e159 100644 --- a/tools/bugpoint/ExtractFunction.cpp +++ b/tools/bugpoint/ExtractFunction.cpp @@ -47,7 +47,39 @@ namespace { cl::opt<bool, true> NoSCFG("disable-simplifycfg", cl::location(DisableSimplifyCFG), cl::desc("Do not use the -simplifycfg pass to reduce testcases")); -} + + Function* globalInitUsesExternalBA(GlobalVariable* GV) { + if (!GV->hasInitializer()) + return 0; + + Constant *I = GV->getInitializer(); + + // walk the values used by the initializer + // (and recurse into things like ConstantExpr) + std::vector<Constant*> Todo; + std::set<Constant*> Done; + Todo.push_back(I); + + while (!Todo.empty()) { + Constant* V = Todo.back(); + Todo.pop_back(); + Done.insert(V); + + if (BlockAddress *BA = dyn_cast<BlockAddress>(V)) { + Function *F = BA->getFunction(); + if (F->isDeclaration()) + return F; + } + + for (User::op_iterator i = V->op_begin(), e = V->op_end(); i != e; ++i) { + Constant *C = dyn_cast<Constant>(*i); + if (C && !isa<GlobalValue>(C) && !Done.count(C)) + Todo.push_back(C); + } + } + return 0; + } +} // end anonymous namespace /// deleteInstructionFromProgram - This method clones the current Program and /// deletes the specified instruction from the cloned module. It then runs a @@ -272,11 +304,6 @@ llvm::SplitFunctionsOutOfModule(Module *M, ValueToValueMapTy NewVMap; Module *New = CloneModule(M, NewVMap); - // Make sure global initializers exist only in the safe module (CBE->.so) - for (Module::global_iterator I = New->global_begin(), E = New->global_end(); - I != E; ++I) - I->setInitializer(0); // Delete the initializer to make it external - // Remove the Test functions from the Safe module std::set<Function *> TestFunctions; for (unsigned i = 0, e = F.size(); i != e; ++i) { @@ -295,6 +322,27 @@ llvm::SplitFunctionsOutOfModule(Module *M, DeleteFunctionBody(I); + // Try to split the global initializers evenly + for (Module::global_iterator I = M->global_begin(), E = M->global_end(); + I != E; ++I) { + GlobalVariable *GV = cast<GlobalVariable>(NewVMap[I]); + if (Function *TestFn = globalInitUsesExternalBA(I)) { + if (Function *SafeFn = globalInitUsesExternalBA(GV)) { + errs() << "*** Error: when reducing functions, encountered " + "the global '"; + WriteAsOperand(errs(), GV, false); + errs() << "' with an initializer that references blockaddresses " + "from safe function '" << SafeFn->getName() + << "' and from test function '" << TestFn->getName() << "'.\n"; + exit(1); + } + I->setInitializer(0); // Delete the initializer to make it external + } else { + // If we keep it in the safe module, then delete it in the test module + GV->setInitializer(0); + } + } + // Make sure that there is a global ctor/dtor array in both halves of the // module if they both have static ctor/dtor functions. SplitStaticCtorDtor("llvm.global_ctors", M, New, NewVMap); @@ -340,7 +388,7 @@ Module *BugDriver::ExtractMappedBlocksFromModule(const // 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.os() << BB->getParent()->getNameStr() << " " + BlocksToNotExtractFile.os() << BB->getParent()->getName() << " " << BB->getName() << "\n"; } BlocksToNotExtractFile.os().close(); diff --git a/tools/bugpoint/LLVMBuild.txt b/tools/bugpoint/LLVMBuild.txt new file mode 100644 index 0000000..549d9d0 --- /dev/null +++ b/tools/bugpoint/LLVMBuild.txt @@ -0,0 +1,22 @@ +;===- ./tools/bugpoint/LLVMBuild.txt ---------------------------*- Conf -*--===; +; +; The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Tool +name = bugpoint +parent = Tools +required_libraries = AsmParser BitReader BitWriter IPO Instrumentation Linker Scalar diff --git a/tools/bugpoint/Makefile b/tools/bugpoint/Makefile index 5d287ef..34f4bdd 100644 --- a/tools/bugpoint/Makefile +++ b/tools/bugpoint/Makefile @@ -6,11 +6,10 @@ # License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## -LEVEL = ../.. -TOOLNAME = bugpoint - -LINK_COMPONENTS := asmparser instrumentation scalaropts ipo \ - linker bitreader bitwriter +LEVEL := ../.. +TOOLNAME := bugpoint +LINK_COMPONENTS := asmparser instrumentation scalaropts ipo linker bitreader \ + bitwriter vectorize include $(LEVEL)/Makefile.common diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp index 7ff16db..82a3a86 100644 --- a/tools/bugpoint/Miscompilation.cpp +++ b/tools/bugpoint/Miscompilation.cpp @@ -820,7 +820,8 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test, // 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, diff --git a/tools/bugpoint/OptimizerDriver.cpp b/tools/bugpoint/OptimizerDriver.cpp index 336c83d..fb090ee 100644 --- a/tools/bugpoint/OptimizerDriver.cpp +++ b/tools/bugpoint/OptimizerDriver.cpp @@ -85,8 +85,11 @@ void BugDriver::EmitProgressBitcode(const Module *M, if (NoFlyer || PassesToRun.empty()) return; outs() << "\n*** You can reproduce the problem with: "; if (UseValgrind) outs() << "valgrind "; - outs() << "opt " << Filename << " "; - outs() << getPassesString(PassesToRun) << "\n"; + outs() << "opt " << Filename; + for (unsigned i = 0, e = PluginLoader::getNumPlugins(); i != e; ++i) { + outs() << " -load " << PluginLoader::getPlugin(i); + } + outs() << " " << getPassesString(PassesToRun) << "\n"; } cl::opt<bool> SilencePasses("silence-passes", @@ -145,10 +148,9 @@ bool BugDriver::runPasses(Module *Program, return 1; } - sys::Path tool = PrependMainExecutablePath("opt", getToolName(), - (void*)"opt"); + sys::Path tool = sys::Program::FindProgramByName("opt"); if (tool.empty()) { - errs() << "Cannot find `opt' in executable directory!\n"; + errs() << "Cannot find `opt' in PATH!\n"; return 1; } diff --git a/tools/bugpoint/ToolRunner.cpp b/tools/bugpoint/ToolRunner.cpp index 0d98262..25a2bae 100644 --- a/tools/bugpoint/ToolRunner.cpp +++ b/tools/bugpoint/ToolRunner.cpp @@ -234,6 +234,8 @@ int LLI::ExecuteProgram(const std::string &Bitcode, Timeout, MemoryLimit, Error); } +void AbstractInterpreter::anchor() { } + // LLI create method - Try to find the LLI executable AbstractInterpreter *AbstractInterpreter::createLLI(const char *Argv0, std::string &Message, @@ -621,94 +623,6 @@ AbstractInterpreter *AbstractInterpreter::createJIT(const char *Argv0, return 0; } -GCC::FileType CBE::OutputCode(const std::string &Bitcode, - sys::Path &OutputCFile, std::string &Error, - unsigned Timeout, unsigned MemoryLimit) { - sys::Path uniqueFile(Bitcode+".cbe.c"); - std::string ErrMsg; - if (uniqueFile.makeUnique(true, &ErrMsg)) { - errs() << "Error making unique filename: " << ErrMsg << "\n"; - exit(1); - } - OutputCFile = uniqueFile; - std::vector<const char *> LLCArgs; - LLCArgs.push_back(LLCPath.c_str()); - - // Add any extra LLC args. - for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i) - LLCArgs.push_back(ToolArgs[i].c_str()); - - LLCArgs.push_back("-o"); - LLCArgs.push_back(OutputCFile.c_str()); // Output to the C file - LLCArgs.push_back("-march=c"); // Output C language - LLCArgs.push_back(Bitcode.c_str()); // This is the input bitcode - LLCArgs.push_back(0); - - outs() << "<cbe>"; outs().flush(); - DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i = 0, e = LLCArgs.size()-1; i != e; ++i) - errs() << " " << LLCArgs[i]; - errs() << "\n"; - ); - if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(), - sys::Path(), Timeout, MemoryLimit)) - Error = ProcessFailure(LLCPath, &LLCArgs[0], Timeout, MemoryLimit); - return GCC::CFile; -} - -void CBE::compileProgram(const std::string &Bitcode, std::string *Error, - unsigned Timeout, unsigned MemoryLimit) { - sys::Path OutputCFile; - OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit); - OutputCFile.eraseFromDisk(); -} - -int CBE::ExecuteProgram(const std::string &Bitcode, - const std::vector<std::string> &Args, - const std::string &InputFile, - const std::string &OutputFile, - std::string *Error, - const std::vector<std::string> &ArgsForGCC, - const std::vector<std::string> &SharedLibs, - unsigned Timeout, - unsigned MemoryLimit) { - sys::Path OutputCFile; - OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit); - - FileRemover CFileRemove(OutputCFile.str(), !SaveTemps); - - std::vector<std::string> GCCArgs(ArgsForGCC); - GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end()); - - return gcc->ExecuteProgram(OutputCFile.str(), Args, GCC::CFile, - InputFile, OutputFile, Error, GCCArgs, - Timeout, MemoryLimit); -} - -/// createCBE - Try to find the 'llc' executable -/// -CBE *AbstractInterpreter::createCBE(const char *Argv0, - std::string &Message, - const std::string &GCCBinary, - const std::vector<std::string> *Args, - const std::vector<std::string> *GCCArgs) { - sys::Path LLCPath = - PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createCBE); - if (LLCPath.isEmpty()) { - Message = - "Cannot find `llc' in executable directory!\n"; - return 0; - } - - Message = "Found llc: " + LLCPath.str() + "\n"; - GCC *gcc = GCC::create(Message, GCCBinary, GCCArgs); - if (!gcc) { - errs() << Message << "\n"; - exit(1); - } - return new CBE(LLCPath, gcc, Args); -} - //===---------------------------------------------------------------------===// // GCC abstraction // @@ -920,8 +834,7 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType, } else GCCArgs.push_back("-shared"); // `-shared' for Linux/X86, maybe others - if ((TargetTriple.getArch() == Triple::alpha) || - (TargetTriple.getArch() == Triple::x86_64)) + if (TargetTriple.getArch() == Triple::x86_64) GCCArgs.push_back("-fPIC"); // Requires shared objs to contain PIC if (TargetTriple.getArch() == Triple::sparc) diff --git a/tools/bugpoint/ToolRunner.h b/tools/bugpoint/ToolRunner.h index cfa8acf..7b93394 100644 --- a/tools/bugpoint/ToolRunner.h +++ b/tools/bugpoint/ToolRunner.h @@ -86,6 +86,7 @@ public: /// complexity behind a simple interface. /// class AbstractInterpreter { + virtual void anchor(); public: static CBE *createCBE(const char *Argv0, std::string &Message, const std::string &GCCBinary, diff --git a/tools/bugpoint/bugpoint.cpp b/tools/bugpoint/bugpoint.cpp index 6a87521..8f15b02 100644 --- a/tools/bugpoint/bugpoint.cpp +++ b/tools/bugpoint/bugpoint.cpp @@ -120,6 +120,7 @@ int main(int argc, char **argv) { PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeScalarOpts(Registry); + initializeVectorization(Registry); initializeIPO(Registry); initializeAnalysis(Registry); initializeIPA(Registry); |