diff options
-rw-r--r-- | llvm/tools/bugpoint/BugDriver.cpp | 56 | ||||
-rw-r--r-- | llvm/tools/bugpoint/BugDriver.h | 66 | ||||
-rw-r--r-- | llvm/tools/bugpoint/CrashDebugger.cpp | 396 | ||||
-rw-r--r-- | llvm/tools/bugpoint/ExecutionDriver.cpp | 337 | ||||
-rw-r--r-- | llvm/tools/bugpoint/ExtractFunction.cpp | 156 | ||||
-rw-r--r-- | llvm/tools/bugpoint/FindBugs.cpp | 45 | ||||
-rw-r--r-- | llvm/tools/bugpoint/Miscompilation.cpp | 411 | ||||
-rw-r--r-- | llvm/tools/bugpoint/OptimizerDriver.cpp | 74 | ||||
-rw-r--r-- | llvm/tools/bugpoint/ToolRunner.cpp | 503 | ||||
-rw-r--r-- | llvm/tools/bugpoint/ToolRunner.h | 106 | ||||
-rw-r--r-- | llvm/tools/bugpoint/bugpoint.cpp | 95 |
11 files changed, 1088 insertions, 1157 deletions
diff --git a/llvm/tools/bugpoint/BugDriver.cpp b/llvm/tools/bugpoint/BugDriver.cpp index 030749fa9ea..dde552174b4 100644 --- a/llvm/tools/bugpoint/BugDriver.cpp +++ b/llvm/tools/bugpoint/BugDriver.cpp @@ -29,20 +29,20 @@ using namespace llvm; namespace llvm { - Triple TargetTriple; +Triple TargetTriple; } // Anonymous namespace to define command line options for debugging. // namespace { - // Output - The user can specify a file containing the expected output of the - // program. If this filename is set, it is used as the reference diff source, - // otherwise the raw input run through an interpreter is used as the reference - // source. - // - cl::opt<std::string> - OutputFile("output", cl::desc("Specify a reference program output " - "(for miscompilation detection)")); +// Output - The user can specify a file containing the expected output of the +// program. If this filename is set, it is used as the reference diff source, +// otherwise the raw input run through an interpreter is used as the reference +// source. +// +cl::opt<std::string> OutputFile("output", + cl::desc("Specify a reference program output " + "(for miscompilation detection)")); } /// setNewProgram - If we reduce or update the program somehow, call this method @@ -53,27 +53,26 @@ void BugDriver::setNewProgram(Module *M) { Program = M; } - /// getPassesString - Turn a list of passes into a string which indicates the /// command line options that must be passed to add the passes. /// std::string llvm::getPassesString(const std::vector<std::string> &Passes) { std::string Result; for (unsigned i = 0, e = Passes.size(); i != e; ++i) { - if (i) Result += " "; + if (i) + Result += " "; Result += "-"; Result += Passes[i]; } return Result; } -BugDriver::BugDriver(const char *toolname, bool find_bugs, - unsigned timeout, unsigned memlimit, bool use_valgrind, - LLVMContext& ctxt) - : Context(ctxt), ToolName(toolname), ReferenceOutputFile(OutputFile), - Program(nullptr), Interpreter(nullptr), SafeInterpreter(nullptr), - cc(nullptr), run_find_bugs(find_bugs), Timeout(timeout), - MemoryLimit(memlimit), UseValgrind(use_valgrind) {} +BugDriver::BugDriver(const char *toolname, bool find_bugs, unsigned timeout, + unsigned memlimit, bool use_valgrind, LLVMContext &ctxt) + : Context(ctxt), ToolName(toolname), ReferenceOutputFile(OutputFile), + Program(nullptr), Interpreter(nullptr), SafeInterpreter(nullptr), + cc(nullptr), run_find_bugs(find_bugs), Timeout(timeout), + MemoryLimit(memlimit), UseValgrind(use_valgrind) {} BugDriver::~BugDriver() { delete Program; @@ -123,13 +122,15 @@ bool BugDriver::addSources(const std::vector<std::string> &Filenames) { // Load the first input file. Program = parseInputFile(Filenames[0], Context).release(); - if (!Program) return true; + 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); - if (!M.get()) return true; + if (!M.get()) + return true; outs() << "Linking in input file: '" << Filenames[i] << "'\n"; if (Linker::linkModules(*Program, std::move(M))) @@ -142,8 +143,6 @@ bool BugDriver::addSources(const std::vector<std::string> &Filenames) { return false; } - - /// run - The top level method that is invoked after all of the instance /// variables are set up from command line arguments. /// @@ -168,7 +167,8 @@ bool BugDriver::run(std::string &ErrMsg) { } // Set up the execution environment, selecting a method to run LLVM bitcode. - if (initializeExecutionEnvironment()) return true; + if (initializeExecutionEnvironment()) + return true; // Test to see if we have a code generator crash. outs() << "Running the code generator to test for a crash: "; @@ -227,9 +227,10 @@ bool BugDriver::run(std::string &ErrMsg) { return Failure; } -void llvm::PrintFunctionList(const std::vector<Function*> &Funcs) { +void llvm::PrintFunctionList(const std::vector<Function *> &Funcs) { unsigned NumPrint = Funcs.size(); - if (NumPrint > 10) NumPrint = 10; + if (NumPrint > 10) + NumPrint = 10; for (unsigned i = 0; i != NumPrint; ++i) outs() << " " << Funcs[i]->getName(); if (NumPrint < Funcs.size()) @@ -237,9 +238,10 @@ void llvm::PrintFunctionList(const std::vector<Function*> &Funcs) { outs().flush(); } -void llvm::PrintGlobalVariableList(const std::vector<GlobalVariable*> &GVs) { +void llvm::PrintGlobalVariableList(const std::vector<GlobalVariable *> &GVs) { unsigned NumPrint = GVs.size(); - if (NumPrint > 10) NumPrint = 10; + if (NumPrint > 10) + NumPrint = 10; for (unsigned i = 0; i != NumPrint; ++i) outs() << " " << GVs[i]->getName(); if (NumPrint < GVs.size()) diff --git a/llvm/tools/bugpoint/BugDriver.h b/llvm/tools/bugpoint/BugDriver.h index 52ec2c00564..7ae2d5c2f99 100644 --- a/llvm/tools/bugpoint/BugDriver.h +++ b/llvm/tools/bugpoint/BugDriver.h @@ -45,13 +45,13 @@ extern bool DisableSimplifyCFG; extern bool BugpointIsInterrupted; class BugDriver { - LLVMContext& Context; + LLVMContext &Context; const char *ToolName; // argv[0] of bugpoint std::string ReferenceOutputFile; // Name of `good' output file - Module *Program; // The raw program, linked together + Module *Program; // The raw program, linked together std::vector<std::string> PassesToRun; - AbstractInterpreter *Interpreter; // How to run the program - AbstractInterpreter *SafeInterpreter; // To generate reference output, etc. + AbstractInterpreter *Interpreter; // How to run the program + AbstractInterpreter *SafeInterpreter; // To generate reference output, etc. CC *cc; bool run_find_bugs; unsigned Timeout; @@ -63,14 +63,13 @@ class BugDriver { friend class ReduceMisCodegenFunctions; public: - BugDriver(const char *toolname, bool find_bugs, - unsigned timeout, unsigned memlimit, bool use_valgrind, - LLVMContext& ctxt); + BugDriver(const char *toolname, bool find_bugs, unsigned timeout, + unsigned memlimit, bool use_valgrind, LLVMContext &ctxt); ~BugDriver(); const char *getToolName() const { return ToolName; } - LLVMContext& getContext() const { return Context; } + LLVMContext &getContext() const { return Context; } // Set up methods... these methods are used to copy information about the // command line arguments into instance variables of BugDriver. @@ -80,9 +79,7 @@ public: void setPassesToRun(const std::vector<std::string> &PTR) { PassesToRun = PTR; } - const std::vector<std::string> &getPassesToRun() const { - return PassesToRun; - } + const std::vector<std::string> &getPassesToRun() const { return PassesToRun; } /// run - The top level method that is invoked after all of the instance /// variables are set up from command line arguments. The \p as_child argument @@ -142,13 +139,11 @@ public: AbstractInterpreter *switchToSafeInterpreter() { AbstractInterpreter *Old = Interpreter; - Interpreter = (AbstractInterpreter*)SafeInterpreter; + Interpreter = (AbstractInterpreter *)SafeInterpreter; return Old; } - void switchToInterpreter(AbstractInterpreter *AI) { - Interpreter = AI; - } + void switchToInterpreter(AbstractInterpreter *AI) { Interpreter = AI; } /// setNewProgram - If we reduce or update the program somehow, call this /// method to update bugdriver with it. This deletes the old module and sets @@ -164,12 +159,10 @@ public: /// executeProgram - This method runs "Program", capturing the output of the /// program to a file. A recommended filename may be optionally specified. /// - std::string executeProgram(const Module *Program, - std::string OutputFilename, + std::string executeProgram(const Module *Program, std::string OutputFilename, std::string Bitcode, const std::string &SharedObjects, - AbstractInterpreter *AI, - std::string *Error) const; + AbstractInterpreter *AI, std::string *Error) const; /// executeProgramSafely - Used to create reference output with the "safe" /// backend, if reference output is not provided. If there is a problem with @@ -181,20 +174,19 @@ public: std::string *Error) const; /// createReferenceFile - calls compileProgram and then records the output - /// into ReferenceOutputFile. Returns true if reference file created, false + /// into ReferenceOutputFile. Returns true if reference file created, false /// otherwise. Note: initializeExecutionEnvironment should be called BEFORE /// this function. /// - bool createReferenceFile(Module *M, const std::string &Filename - = "bugpoint.reference.out-%%%%%%%"); + bool createReferenceFile(Module *M, const std::string &Filename = + "bugpoint.reference.out-%%%%%%%"); /// diffProgram - This method executes the specified module and diffs the /// output against the file specified by ReferenceOutputFile. If the output /// is different, 1 is returned. If there is a problem with the code /// generator (e.g., llc crashes), this will return -1 and set Error. /// - bool diffProgram(const Module *Program, - const std::string &BitcodeFile = "", + bool diffProgram(const Module *Program, const std::string &BitcodeFile = "", const std::string &SharedObj = "", bool RemoveBitcode = false, std::string *Error = nullptr) const; @@ -251,27 +243,27 @@ public: /// or failed, unless Quiet is set. ExtraArgs specifies additional arguments /// to pass to the child bugpoint instance. /// - bool runPasses(Module *Program, - const std::vector<std::string> &PassesToRun, + bool runPasses(Module *Program, const std::vector<std::string> &PassesToRun, std::string &OutputFilename, bool DeleteOutput = false, bool Quiet = false, unsigned NumExtraArgs = 0, - const char * const *ExtraArgs = nullptr) const; + const char *const *ExtraArgs = nullptr) const; /// runPasses - Just like the method above, but this just returns true or /// false indicating whether or not the optimizer crashed on the specified /// input (true = crashed). Does not produce any output. /// - bool runPasses(Module *M, - const std::vector<std::string> &PassesToRun) const { + bool runPasses(Module *M, const std::vector<std::string> &PassesToRun) const { std::string Filename; return runPasses(M, PassesToRun, Filename, true); } - - /// runManyPasses - Take the specified pass list and create different - /// combinations of passes to compile the program with. Compile the program with - /// each set and mark test to see if it compiled correctly. If the passes - /// compiled correctly output nothing and rearrange the passes into a new order. - /// If the passes did not compile correctly, output the command required to + + /// runManyPasses - Take the specified pass list and create different + /// combinations of passes to compile the program with. Compile the program + /// with + /// each set and mark test to see if it compiled correctly. If the passes + /// compiled correctly output nothing and rearrange the passes into a new + /// order. + /// If the passes did not compile correctly, output the command required to /// recreate the failure. This returns true if a compiler error is found. /// bool runManyPasses(const std::vector<std::string> &AllPasses, @@ -304,11 +296,11 @@ std::string getPassesString(const std::vector<std::string> &Passes); /// PrintFunctionList - prints out list of problematic functions /// -void PrintFunctionList(const std::vector<Function*> &Funcs); +void PrintFunctionList(const std::vector<Function *> &Funcs); /// PrintGlobalVariableList - prints out list of problematic global variables /// -void PrintGlobalVariableList(const std::vector<GlobalVariable*> &GVs); +void PrintGlobalVariableList(const std::vector<GlobalVariable *> &GVs); // DeleteGlobalInitializer - "Remove" the global variable by deleting its // initializer, making it external. diff --git a/llvm/tools/bugpoint/CrashDebugger.cpp b/llvm/tools/bugpoint/CrashDebugger.cpp index f6b35f5fd53..649cac7c681 100644 --- a/llvm/tools/bugpoint/CrashDebugger.cpp +++ b/llvm/tools/bugpoint/CrashDebugger.cpp @@ -14,9 +14,9 @@ #include "BugDriver.h" #include "ListReducer.h" #include "ToolRunner.h" -#include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringSet.h" +#include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/IR/CFG.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" @@ -36,52 +36,49 @@ using namespace llvm; namespace { - cl::opt<bool> - KeepMain("keep-main", - cl::desc("Force function reduction to keep main"), - cl::init(false)); - cl::opt<bool> - NoGlobalRM ("disable-global-remove", - cl::desc("Do not remove global variables"), - cl::init(false)); - - cl::opt<bool> - ReplaceFuncsWithNull("replace-funcs-with-null", - cl::desc("When stubbing functions, replace all uses will null"), - cl::init(false)); - cl::opt<bool> - DontReducePassList("disable-pass-list-reduction", - cl::desc("Skip pass list reduction steps"), - cl::init(false)); - - cl::opt<bool> NoNamedMDRM("disable-namedmd-remove", - cl::desc("Do not remove global named metadata"), - cl::init(false)); - cl::opt<bool> VerboseErrors("verbose-errors", +cl::opt<bool> KeepMain("keep-main", + cl::desc("Force function reduction to keep main"), + cl::init(false)); +cl::opt<bool> NoGlobalRM("disable-global-remove", + cl::desc("Do not remove global variables"), + cl::init(false)); + +cl::opt<bool> ReplaceFuncsWithNull( + "replace-funcs-with-null", + cl::desc("When stubbing functions, replace all uses will null"), + cl::init(false)); +cl::opt<bool> DontReducePassList("disable-pass-list-reduction", + cl::desc("Skip pass list reduction steps"), + cl::init(false)); + +cl::opt<bool> NoNamedMDRM("disable-namedmd-remove", + cl::desc("Do not remove global named metadata"), + cl::init(false)); +cl::opt<bool> VerboseErrors("verbose-errors", cl::desc("Print the output of crashing program"), cl::init(false)); } namespace llvm { - class ReducePassList : public ListReducer<std::string> { - BugDriver &BD; - public: - ReducePassList(BugDriver &bd) : BD(bd) {} - - // doTest - Return true iff running the "removed" passes succeeds, and - // running the "Kept" passes fail when run on the output of the "removed" - // passes. If we return true, we update the current module of bugpoint. - // - TestResult doTest(std::vector<std::string> &Removed, - std::vector<std::string> &Kept, - std::string &Error) override; - }; +class ReducePassList : public ListReducer<std::string> { + BugDriver &BD; + +public: + ReducePassList(BugDriver &bd) : BD(bd) {} + + // doTest - Return true iff running the "removed" passes succeeds, and + // running the "Kept" passes fail when run on the output of the "removed" + // passes. If we return true, we update the current module of bugpoint. + // + TestResult doTest(std::vector<std::string> &Removed, + std::vector<std::string> &Kept, + std::string &Error) override; +}; } ReducePassList::TestResult ReducePassList::doTest(std::vector<std::string> &Prefix, - std::vector<std::string> &Suffix, - std::string &Error) { + std::vector<std::string> &Suffix, std::string &Error) { std::string PrefixOutput; Module *OrigProgram = nullptr; if (!Prefix.empty()) { @@ -101,11 +98,11 @@ ReducePassList::doTest(std::vector<std::string> &Prefix, sys::fs::remove(PrefixOutput); } - outs() << "Checking to see if these passes crash: " - << getPassesString(Suffix) << ": "; + outs() << "Checking to see if these passes crash: " << getPassesString(Suffix) + << ": "; if (BD.runPasses(BD.getProgram(), Suffix)) { - delete OrigProgram; // The suffix crashes alone... + delete OrigProgram; // The suffix crashes alone... return KeepSuffix; } @@ -118,44 +115,44 @@ ReducePassList::doTest(std::vector<std::string> &Prefix, } namespace { - /// ReduceCrashingGlobalVariables - This works by removing the global - /// variable's initializer and seeing if the program still crashes. If it - /// does, then we keep that program and try again. - /// - class ReduceCrashingGlobalVariables : public ListReducer<GlobalVariable*> { - BugDriver &BD; - bool (*TestFn)(const BugDriver &, Module *); - public: - ReduceCrashingGlobalVariables(BugDriver &bd, - bool (*testFn)(const BugDriver &, Module *)) +/// ReduceCrashingGlobalVariables - This works by removing the global +/// variable's initializer and seeing if the program still crashes. If it +/// does, then we keep that program and try again. +/// +class ReduceCrashingGlobalVariables : public ListReducer<GlobalVariable *> { + BugDriver &BD; + bool (*TestFn)(const BugDriver &, Module *); + +public: + ReduceCrashingGlobalVariables(BugDriver &bd, + bool (*testFn)(const BugDriver &, Module *)) : BD(bd), TestFn(testFn) {} - TestResult doTest(std::vector<GlobalVariable*> &Prefix, - std::vector<GlobalVariable*> &Kept, - std::string &Error) override { - if (!Kept.empty() && TestGlobalVariables(Kept)) - return KeepSuffix; - if (!Prefix.empty() && TestGlobalVariables(Prefix)) - return KeepPrefix; - return NoFailure; - } + TestResult doTest(std::vector<GlobalVariable *> &Prefix, + std::vector<GlobalVariable *> &Kept, + std::string &Error) override { + if (!Kept.empty() && TestGlobalVariables(Kept)) + return KeepSuffix; + if (!Prefix.empty() && TestGlobalVariables(Prefix)) + return KeepPrefix; + return NoFailure; + } - bool TestGlobalVariables(std::vector<GlobalVariable*> &GVs); - }; + bool TestGlobalVariables(std::vector<GlobalVariable *> &GVs); +}; } -bool -ReduceCrashingGlobalVariables::TestGlobalVariables( - std::vector<GlobalVariable*> &GVs) { +bool ReduceCrashingGlobalVariables::TestGlobalVariables( + std::vector<GlobalVariable *> &GVs) { // Clone the program to try hacking it apart... ValueToValueMapTy VMap; Module *M = CloneModule(BD.getProgram(), VMap).release(); // Convert list to set for fast lookup... - std::set<GlobalVariable*> GVSet; + std::set<GlobalVariable *> GVSet; for (unsigned i = 0, e = GVs.size(); i != e; ++i) { - GlobalVariable* CMGV = cast<GlobalVariable>(VMap[GVs[i]]); + GlobalVariable *CMGV = cast<GlobalVariable>(VMap[GVs[i]]); assert(CMGV && "Global Variable not in module?!"); GVSet.insert(CMGV); } @@ -175,7 +172,7 @@ ReduceCrashingGlobalVariables::TestGlobalVariables( // Try running the hacked up program... if (TestFn(BD, M)) { - BD.setNewProgram(M); // It crashed, keep the trimmed version... + BD.setNewProgram(M); // It crashed, keep the trimmed version... // Make sure to use global variable pointers that point into the now-current // module. @@ -188,45 +185,47 @@ ReduceCrashingGlobalVariables::TestGlobalVariables( } namespace { - /// ReduceCrashingFunctions reducer - This works by removing functions and - /// seeing if the program still crashes. If it does, then keep the newer, - /// smaller program. - /// - class ReduceCrashingFunctions : public ListReducer<Function*> { - BugDriver &BD; - bool (*TestFn)(const BugDriver &, Module *); - public: - ReduceCrashingFunctions(BugDriver &bd, - bool (*testFn)(const BugDriver &, Module *)) +/// ReduceCrashingFunctions reducer - This works by removing functions and +/// seeing if the program still crashes. If it does, then keep the newer, +/// smaller program. +/// +class ReduceCrashingFunctions : public ListReducer<Function *> { + BugDriver &BD; + bool (*TestFn)(const BugDriver &, Module *); + +public: + ReduceCrashingFunctions(BugDriver &bd, + bool (*testFn)(const BugDriver &, Module *)) : BD(bd), TestFn(testFn) {} - TestResult doTest(std::vector<Function*> &Prefix, - std::vector<Function*> &Kept, - std::string &Error) override { - if (!Kept.empty() && TestFuncs(Kept)) - return KeepSuffix; - if (!Prefix.empty() && TestFuncs(Prefix)) - return KeepPrefix; - return NoFailure; - } + TestResult doTest(std::vector<Function *> &Prefix, + std::vector<Function *> &Kept, + std::string &Error) override { + if (!Kept.empty() && TestFuncs(Kept)) + return KeepSuffix; + if (!Prefix.empty() && TestFuncs(Prefix)) + return KeepPrefix; + return NoFailure; + } - bool TestFuncs(std::vector<Function*> &Prefix); - }; + bool TestFuncs(std::vector<Function *> &Prefix); +}; } -static void RemoveFunctionReferences(Module *M, const char* Name) { +static void RemoveFunctionReferences(Module *M, const char *Name) { auto *UsedVar = M->getGlobalVariable(Name, true); - if (!UsedVar || !UsedVar->hasInitializer()) return; + if (!UsedVar || !UsedVar->hasInitializer()) + return; if (isa<ConstantAggregateZero>(UsedVar->getInitializer())) { assert(UsedVar->use_empty()); UsedVar->eraseFromParent(); return; } auto *OldUsedVal = cast<ConstantArray>(UsedVar->getInitializer()); - std::vector<Constant*> Used; - for(Value *V : OldUsedVal->operand_values()) { + std::vector<Constant *> Used; + for (Value *V : OldUsedVal->operand_values()) { Constant *Op = cast<Constant>(V->stripPointerCasts()); - if(!Op->isNullValue()) { + if (!Op->isNullValue()) { Used.push_back(cast<Constant>(V)); } } @@ -237,7 +236,7 @@ static void RemoveFunctionReferences(Module *M, const char* Name) { UsedVar->setInitializer(NewUsedVal); } -bool ReduceCrashingFunctions::TestFuncs(std::vector<Function*> &Funcs) { +bool ReduceCrashingFunctions::TestFuncs(std::vector<Function *> &Funcs) { // If main isn't present, claim there is no problem. if (KeepMain && !is_contained(Funcs, BD.getProgram()->getFunction("main"))) return false; @@ -247,7 +246,7 @@ bool ReduceCrashingFunctions::TestFuncs(std::vector<Function*> &Funcs) { Module *M = CloneModule(BD.getProgram(), VMap).release(); // Convert list to set for fast lookup... - std::set<Function*> Functions; + std::set<Function *> Functions; for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { Function *CMF = cast<Function>(VMap[Funcs[i]]); assert(CMF && "Function not in module?!"); @@ -266,7 +265,7 @@ bool ReduceCrashingFunctions::TestFuncs(std::vector<Function*> &Funcs) { if (!I.isDeclaration() && !Functions.count(&I)) DeleteFunctionBody(&I); } else { - std::vector<GlobalValue*> ToRemove; + std::vector<GlobalValue *> ToRemove; // First, remove aliases to functions we're about to purge. for (GlobalAlias &Alias : M->aliases()) { GlobalObject *Root = Alias.getBaseObject(); @@ -308,7 +307,7 @@ bool ReduceCrashingFunctions::TestFuncs(std::vector<Function*> &Funcs) { } // Try running the hacked up program... if (TestFn(BD, M)) { - BD.setNewProgram(M); // It crashed, keep the trimmed version... + BD.setNewProgram(M); // It crashed, keep the trimmed version... // Make sure to use function pointers that point into the now-current // module. @@ -350,7 +349,7 @@ void simpleSimplifyCfg(Function &F, SmallVectorImpl<BasicBlock *> &BBs) { // The dead BB's may be in a dead cycle or otherwise have references to each // other. Because of this, we have to drop all references first, then delete // them all at once. - for (auto *BB : Unreachable) { + for (auto *BB : Unreachable) { for (BasicBlock *Successor : successors(&*BB)) if (Visited.count(Successor)) Successor->removePredecessor(&*BB); @@ -359,46 +358,48 @@ void simpleSimplifyCfg(Function &F, SmallVectorImpl<BasicBlock *> &BBs) { for (auto *BB : Unreachable) BB->eraseFromParent(); } - /// ReduceCrashingBlocks reducer - This works by setting the terminators of - /// all terminators except the specified basic blocks to a 'ret' instruction, - /// then running the simplify-cfg pass. This has the effect of chopping up - /// the CFG really fast which can reduce large functions quickly. - /// - class ReduceCrashingBlocks : public ListReducer<const BasicBlock*> { - BugDriver &BD; - bool (*TestFn)(const BugDriver &, Module *); - public: - ReduceCrashingBlocks(BugDriver &BD, - bool (*testFn)(const BugDriver &, Module *)) +/// ReduceCrashingBlocks reducer - This works by setting the terminators of +/// all terminators except the specified basic blocks to a 'ret' instruction, +/// then running the simplify-cfg pass. This has the effect of chopping up +/// the CFG really fast which can reduce large functions quickly. +/// +class ReduceCrashingBlocks : public ListReducer<const BasicBlock *> { + BugDriver &BD; + bool (*TestFn)(const BugDriver &, Module *); + +public: + ReduceCrashingBlocks(BugDriver &BD, + bool (*testFn)(const BugDriver &, Module *)) : BD(BD), TestFn(testFn) {} - TestResult doTest(std::vector<const BasicBlock*> &Prefix, - std::vector<const BasicBlock*> &Kept, - std::string &Error) override { - if (!Kept.empty() && TestBlocks(Kept)) - return KeepSuffix; - if (!Prefix.empty() && TestBlocks(Prefix)) - return KeepPrefix; - return NoFailure; - } + TestResult doTest(std::vector<const BasicBlock *> &Prefix, + std::vector<const BasicBlock *> &Kept, + std::string &Error) override { + if (!Kept.empty() && TestBlocks(Kept)) + return KeepSuffix; + if (!Prefix.empty() && TestBlocks(Prefix)) + return KeepPrefix; + return NoFailure; + } - bool TestBlocks(std::vector<const BasicBlock*> &Prefix); - }; + bool TestBlocks(std::vector<const BasicBlock *> &Prefix); +}; } -bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock*> &BBs) { +bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock *> &BBs) { // Clone the program to try hacking it apart... ValueToValueMapTy VMap; Module *M = CloneModule(BD.getProgram(), VMap).release(); // Convert list to set for fast lookup... - SmallPtrSet<BasicBlock*, 8> Blocks; + SmallPtrSet<BasicBlock *, 8> Blocks; for (unsigned i = 0, e = BBs.size(); i != e; ++i) Blocks.insert(cast<BasicBlock>(VMap[BBs[i]])); outs() << "Checking for crash with only these blocks:"; unsigned NumPrint = Blocks.size(); - if (NumPrint > 10) NumPrint = 10; + if (NumPrint > 10) + NumPrint = 10; for (unsigned i = 0, e = NumPrint; i != e; ++i) outs() << " " << BBs[i]->getName(); if (NumPrint < Blocks.size()) @@ -431,13 +432,13 @@ bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock*> &BBs) { // a "persistent mapping" by turning basic blocks into <function, name> pairs. // This won't work well if blocks are unnamed, but that is just the risk we // have to take. - std::vector<std::pair<std::string, std::string> > BlockInfo; + std::vector<std::pair<std::string, std::string>> BlockInfo; for (BasicBlock *BB : Blocks) BlockInfo.emplace_back(BB->getParent()->getName(), BB->getName()); - + SmallVector<BasicBlock *, 16> ToProcess; - for (auto &F :*M) { + for (auto &F : *M) { for (auto &BB : F) if (!Blocks.count(&BB)) ToProcess.push_back(&BB); @@ -454,10 +455,10 @@ bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock*> &BBs) { exit(1); } M = New.release(); - + // Try running on the hacked up program... if (TestFn(BD, M)) { - BD.setNewProgram(M); // It crashed, keep the trimmed version... + BD.setNewProgram(M); // It crashed, keep the trimmed version... // Make sure to use basic block pointers that point into the now-current // module, and that they don't include any deleted blocks. @@ -466,13 +467,13 @@ bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock*> &BBs) { for (unsigned i = 0, e = BlockInfo.size(); i != e; ++i) { Function *F = cast<Function>(GST.lookup(BlockInfo[i].first)); ValueSymbolTable &ST = F->getValueSymbolTable(); - Value* V = ST.lookup(BlockInfo[i].second); + Value *V = ST.lookup(BlockInfo[i].second); if (V && V->getType() == Type::getLabelTy(V->getContext())) BBs.push_back(cast<BasicBlock>(V)); } return true; } - delete M; // It didn't crash, try something else. + delete M; // It didn't crash, try something else. return false; } @@ -515,7 +516,7 @@ bool ReduceCrashingConditionals::TestBlocks( // Convert list to set for fast lookup... SmallPtrSet<const BasicBlock *, 8> Blocks; - for (const auto *BB: BBs) + for (const auto *BB : BBs) Blocks.insert(cast<BasicBlock>(VMap[BB])); outs() << "Checking for crash with changing conditionals to always jump to " @@ -530,7 +531,7 @@ bool ReduceCrashingConditionals::TestBlocks( outs() << ": "; // Loop over and delete any hack up any blocks that are not listed... - for (auto &F: *M) + for (auto &F : *M) for (auto &BB : F) if (!Blocks.count(&BB)) { auto *BR = dyn_cast<BranchInst>(BB.getTerminator()); @@ -549,7 +550,7 @@ bool ReduceCrashingConditionals::TestBlocks( BlockInfo.emplace_back(BB->getParent()->getName(), BB->getName()); SmallVector<BasicBlock *, 16> ToProcess; - for (auto &F :*M) { + for (auto &F : *M) { for (auto &BB : F) if (!Blocks.count(&BB)) ToProcess.push_back(&BB); @@ -596,12 +597,10 @@ class ReduceSimplifyCFG : public ListReducer<const BasicBlock *> { BugDriver &BD; bool (*TestFn)(const BugDriver &, Module *); TargetTransformInfo TTI; - + public: - ReduceSimplifyCFG(BugDriver &bd, - bool (*testFn)(const BugDriver &, Module *)) - : BD(bd), TestFn(testFn), TTI(bd.getProgram()->getDataLayout()) - {} + ReduceSimplifyCFG(BugDriver &bd, bool (*testFn)(const BugDriver &, Module *)) + : BD(bd), TestFn(testFn), TTI(bd.getProgram()->getDataLayout()) {} TestResult doTest(std::vector<const BasicBlock *> &Prefix, std::vector<const BasicBlock *> &Kept, @@ -617,15 +616,14 @@ public: }; } -bool ReduceSimplifyCFG::TestBlocks( - std::vector<const BasicBlock *> &BBs) { +bool ReduceSimplifyCFG::TestBlocks(std::vector<const BasicBlock *> &BBs) { // Clone the program to try hacking it apart... ValueToValueMapTy VMap; Module *M = CloneModule(BD.getProgram(), VMap).release(); // Convert list to set for fast lookup... SmallPtrSet<const BasicBlock *, 8> Blocks; - for (const auto *BB: BBs) + for (const auto *BB : BBs) Blocks.insert(cast<BasicBlock>(VMap[BB])); outs() << "Checking for crash with CFG simplifying:"; @@ -638,23 +636,22 @@ bool ReduceSimplifyCFG::TestBlocks( outs() << "... <" << Blocks.size() << " total>"; outs() << ": "; - // The following may destroy some blocks, so we save them first + // The following may destroy some blocks, so we save them first std::vector<std::pair<std::string, std::string>> BlockInfo; for (const BasicBlock *BB : Blocks) BlockInfo.emplace_back(BB->getParent()->getName(), BB->getName()); - // Loop over and delete any hack up any blocks that are not listed... - for (auto &F: *M) - // Loop over all of the basic blocks and remove them if they are unneeded. - for (Function::iterator BBIt = F.begin(); BBIt != F.end(); ) { - if (!Blocks.count(&*BBIt)) { - ++BBIt; - continue; - } - SimplifyCFG(&*BBIt++, TTI, 1); - } + for (auto &F : *M) + // Loop over all of the basic blocks and remove them if they are unneeded. + for (Function::iterator BBIt = F.begin(); BBIt != F.end();) { + if (!Blocks.count(&*BBIt)) { + ++BBIt; + continue; + } + SimplifyCFG(&*BBIt++, TTI, 1); + } // Verify we didn't break anything std::vector<std::string> Passes; Passes.push_back("verify"); @@ -674,7 +671,7 @@ bool ReduceSimplifyCFG::TestBlocks( // module, and that they don't include any deleted blocks. BBs.clear(); const ValueSymbolTable &GST = M->getValueSymbolTable(); - for (auto &BI : BlockInfo){ + for (auto &BI : BlockInfo) { auto *F = cast<Function>(GST.lookup(BI.first)); ValueSymbolTable &ST = F->getValueSymbolTable(); Value *V = ST.lookup(BI.second); @@ -688,39 +685,40 @@ bool ReduceSimplifyCFG::TestBlocks( } namespace { - /// ReduceCrashingInstructions reducer - This works by removing the specified - /// non-terminator instructions and replacing them with undef. - /// - class ReduceCrashingInstructions : public ListReducer<const Instruction*> { - BugDriver &BD; - bool (*TestFn)(const BugDriver &, Module *); - public: - ReduceCrashingInstructions(BugDriver &bd, - bool (*testFn)(const BugDriver &, Module *)) +/// ReduceCrashingInstructions reducer - This works by removing the specified +/// non-terminator instructions and replacing them with undef. +/// +class ReduceCrashingInstructions : public ListReducer<const Instruction *> { + BugDriver &BD; + bool (*TestFn)(const BugDriver &, Module *); + +public: + ReduceCrashingInstructions(BugDriver &bd, + bool (*testFn)(const BugDriver &, Module *)) : BD(bd), TestFn(testFn) {} - TestResult doTest(std::vector<const Instruction*> &Prefix, - std::vector<const Instruction*> &Kept, - std::string &Error) override { - if (!Kept.empty() && TestInsts(Kept)) - return KeepSuffix; - if (!Prefix.empty() && TestInsts(Prefix)) - return KeepPrefix; - return NoFailure; - } + TestResult doTest(std::vector<const Instruction *> &Prefix, + std::vector<const Instruction *> &Kept, + std::string &Error) override { + if (!Kept.empty() && TestInsts(Kept)) + return KeepSuffix; + if (!Prefix.empty() && TestInsts(Prefix)) + return KeepPrefix; + return NoFailure; + } - bool TestInsts(std::vector<const Instruction*> &Prefix); - }; + bool TestInsts(std::vector<const Instruction *> &Prefix); +}; } -bool ReduceCrashingInstructions::TestInsts(std::vector<const Instruction*> - &Insts) { +bool ReduceCrashingInstructions::TestInsts( + std::vector<const Instruction *> &Insts) { // Clone the program to try hacking it apart... ValueToValueMapTy VMap; Module *M = CloneModule(BD.getProgram(), VMap).release(); // Convert list to set for fast lookup... - SmallPtrSet<Instruction*, 32> Instructions; + SmallPtrSet<Instruction *, 32> Instructions; for (unsigned i = 0, e = Insts.size(); i != e; ++i) { assert(!isa<TerminatorInst>(Insts[i])); Instructions.insert(cast<Instruction>(VMap[Insts[i]])); @@ -751,7 +749,7 @@ bool ReduceCrashingInstructions::TestInsts(std::vector<const Instruction*> // Try running on the hacked up program... if (TestFn(BD, M)) { - BD.setNewProgram(M); // It crashed, keep the trimmed version... + BD.setNewProgram(M); // It crashed, keep the trimmed version... // Make sure to use instruction pointers that point into the now-current // module, and that they don't include any deleted blocks. @@ -760,7 +758,7 @@ bool ReduceCrashingInstructions::TestInsts(std::vector<const Instruction*> Insts.push_back(Inst); return true; } - delete M; // It didn't crash, try something else. + delete M; // It didn't crash, try something else. return false; } @@ -910,7 +908,8 @@ bool ReduceCrashingNamedMDOps::TestNamedMDOps( } static void ReduceGlobalInitializers(BugDriver &BD, - bool (*TestFn)(const BugDriver &, Module *), + bool (*TestFn)(const BugDriver &, + Module *), std::string &Error) { if (BD.getProgram()->global_begin() != BD.getProgram()->global_end()) { // Now try to reduce the number of global variable initializers in the @@ -928,28 +927,29 @@ static void ReduceGlobalInitializers(BugDriver &BD, } if (!DeletedInit) { - delete M; // No change made... + delete M; // No change made... } else { // See if the program still causes a crash... outs() << "\nChecking to see if we can delete global inits: "; - if (TestFn(BD, M)) { // Still crashes? + if (TestFn(BD, M)) { // Still crashes? BD.setNewProgram(M); outs() << "\n*** Able to remove all global initializers!\n"; - } else { // No longer crashes? + } else { // No longer crashes? outs() << " - Removing all global inits hides problem!\n"; delete M; - std::vector<GlobalVariable*> GVs; + std::vector<GlobalVariable *> GVs; for (Module::global_iterator I = BD.getProgram()->global_begin(), - E = BD.getProgram()->global_end(); I != E; ++I) + E = BD.getProgram()->global_end(); + I != E; ++I) if (I->hasInitializer()) GVs.push_back(&*I); if (GVs.size() > 1 && !BugpointIsInterrupted) { outs() << "\n*** Attempting to reduce the number of global " - << "variables in the testcase\n"; + << "variables in the testcase\n"; unsigned OldSize = GVs.size(); ReduceCrashingGlobalVariables(BD, TestFn).reduceList(GVs, Error); @@ -969,7 +969,7 @@ static void ReduceInsts(BugDriver &BD, // Attempt to delete instructions using bisection. This should help out nasty // cases with large basic blocks where the problem is at one end. if (!BugpointIsInterrupted) { - std::vector<const Instruction*> Insts; + std::vector<const Instruction *> Insts; for (const Function &F : *BD.getProgram()) for (const BasicBlock &BB : F) for (const Instruction &I : BB) @@ -1002,7 +1002,8 @@ static void ReduceInsts(BugDriver &BD, // function, attempting to delete them. unsigned CurInstructionNum = 0; for (Module::const_iterator FI = BD.getProgram()->begin(), - E = BD.getProgram()->end(); FI != E; ++FI) + E = BD.getProgram()->end(); + FI != E; ++FI) if (!FI->isDeclaration()) for (Function::const_iterator BI = FI->begin(), E = FI->end(); BI != E; ++BI) @@ -1027,7 +1028,7 @@ static void ReduceInsts(BugDriver &BD, // to reduce the testcase... BD.setNewProgram(M.release()); InstructionsToSkipBeforeDeleting = CurInstructionNum; - goto TryAgain; // I wish I had a multi-level break here! + goto TryAgain; // I wish I had a multi-level break here! } } } @@ -1041,7 +1042,6 @@ static void ReduceInsts(BugDriver &BD, BD.EmitProgressBitcode(BD.getProgram(), "reduced-instructions"); } - /// DebugACrash - Given a predicate that determines whether a component crashes /// on a program, try to destructively reduce the program while still keeping /// the predicate true. @@ -1054,14 +1054,14 @@ static bool DebugACrash(BugDriver &BD, ReduceGlobalInitializers(BD, TestFn, Error); // Now try to reduce the number of functions in the module to something small. - std::vector<Function*> Functions; + std::vector<Function *> Functions; for (Function &F : *BD.getProgram()) if (!F.isDeclaration()) Functions.push_back(&F); if (Functions.size() > 1 && !BugpointIsInterrupted) { outs() << "\n*** Attempting to reduce the number of functions " - "in the testcase\n"; + "in the testcase\n"; unsigned OldSize = Functions.size(); ReduceCrashingFunctions(BD, TestFn).reduceList(Functions, Error); @@ -1073,7 +1073,7 @@ static bool DebugACrash(BugDriver &BD, // Attempt to change conditional branches into unconditional branches to // eliminate blocks. if (!DisableSimplifyCFG && !BugpointIsInterrupted) { - std::vector<const BasicBlock*> Blocks; + std::vector<const BasicBlock *> Blocks; for (Function &F : *BD.getProgram()) for (BasicBlock &BB : F) Blocks.push_back(&BB); @@ -1090,7 +1090,7 @@ static bool DebugACrash(BugDriver &BD, // shrinks the code dramatically quickly // if (!DisableSimplifyCFG && !BugpointIsInterrupted) { - std::vector<const BasicBlock*> Blocks; + std::vector<const BasicBlock *> Blocks; for (Function &F : *BD.getProgram()) for (BasicBlock &BB : F) Blocks.push_back(&BB); @@ -1101,7 +1101,7 @@ static bool DebugACrash(BugDriver &BD, } if (!DisableSimplifyCFG & !BugpointIsInterrupted) { - std::vector<const BasicBlock*> Blocks; + std::vector<const BasicBlock *> Blocks; for (Function &F : *BD.getProgram()) for (BasicBlock &BB : F) Blocks.push_back(&BB); @@ -1110,7 +1110,7 @@ static bool DebugACrash(BugDriver &BD, if (Blocks.size() < OldSize) BD.EmitProgressBitcode(BD.getProgram(), "reduced-simplifycfg"); } - + // Attempt to delete instructions using bisection. This should help out nasty // cases with large basic blocks where the problem is at one end. if (!BugpointIsInterrupted) @@ -1147,7 +1147,7 @@ static bool DebugACrash(BugDriver &BD, // Find out if the pass still crashes on the cleaned up program... if (TestFn(BD, M)) { - BD.setNewProgram(M); // Yup, it does, keep the reduced version... + BD.setNewProgram(M); // Yup, it does, keep the reduced version... } else { delete M; } @@ -1194,7 +1194,7 @@ static bool TestForCodeGenCrash(const BugDriver &BD, Module *M) { errs() << Error << "\n"; else errs() << "<crash>\n"; - return true; // Tool is still crashing. + return true; // Tool is still crashing. } errs() << '\n'; return false; diff --git a/llvm/tools/bugpoint/ExecutionDriver.cpp b/llvm/tools/bugpoint/ExecutionDriver.cpp index ab9c05fa924..695461e2d50 100644 --- a/llvm/tools/bugpoint/ExecutionDriver.cpp +++ b/llvm/tools/bugpoint/ExecutionDriver.cpp @@ -25,112 +25,113 @@ using namespace llvm; namespace { - // OutputType - Allow the user to specify the way code should be run, to test - // for miscompilation. - // - enum OutputType { - AutoPick, RunLLI, RunJIT, RunLLC, RunLLCIA, LLC_Safe, CompileCustom, Custom - }; - - cl::opt<double> - AbsTolerance("abs-tolerance", cl::desc("Absolute error tolerated"), - cl::init(0.0)); - cl::opt<double> - RelTolerance("rel-tolerance", cl::desc("Relative error tolerated"), - cl::init(0.0)); - - cl::opt<OutputType> - InterpreterSel(cl::desc("Specify the \"test\" i.e. suspect back-end:"), - cl::values(clEnumValN(AutoPick, "auto", "Use best guess"), - clEnumValN(RunLLI, "run-int", - "Execute with the interpreter"), - clEnumValN(RunJIT, "run-jit", "Execute with JIT"), - clEnumValN(RunLLC, "run-llc", "Compile with LLC"), - clEnumValN(RunLLCIA, "run-llc-ia", - "Compile with LLC with integrated assembler"), - clEnumValN(LLC_Safe, "llc-safe", "Use LLC for all"), - clEnumValN(CompileCustom, "compile-custom", - "Use -compile-command to define a command to " - "compile the bitcode. Useful to avoid linking."), - clEnumValN(Custom, "run-custom", - "Use -exec-command to define a command to execute " - "the bitcode. Useful for cross-compilation."), - clEnumValEnd), - cl::init(AutoPick)); - - cl::opt<OutputType> - 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(Custom, "safe-run-custom", - "Use -exec-command to define a command to execute " - "the bitcode. Useful for cross-compilation."), - clEnumValEnd), - cl::init(AutoPick)); - - cl::opt<std::string> - SafeInterpreterPath("safe-path", - cl::desc("Specify the path to the \"safe\" backend program"), - cl::init("")); - - cl::opt<bool> - AppendProgramExitCode("append-exit-code", - cl::desc("Append the exit code to the output so it gets diff'd too"), - cl::init(false)); - - cl::opt<std::string> - InputFile("input", cl::init("/dev/null"), - cl::desc("Filename to pipe in as stdin (default: /dev/null)")); - - cl::list<std::string> - AdditionalSOs("additional-so", - cl::desc("Additional shared objects to load " - "into executing programs")); - - cl::list<std::string> - AdditionalLinkerArgs("Xlinker", - cl::desc("Additional arguments to pass to the linker")); - - cl::opt<std::string> - CustomCompileCommand("compile-command", cl::init("llc"), - cl::desc("Command to compile the bitcode (use with -compile-custom) " - "(default: llc)")); - - cl::opt<std::string> - CustomExecCommand("exec-command", cl::init("simulate"), - cl::desc("Command to execute the bitcode (use with -run-custom) " - "(default: simulate)")); +// OutputType - Allow the user to specify the way code should be run, to test +// for miscompilation. +// +enum OutputType { + AutoPick, + RunLLI, + RunJIT, + RunLLC, + RunLLCIA, + LLC_Safe, + CompileCustom, + Custom +}; + +cl::opt<double> AbsTolerance("abs-tolerance", + cl::desc("Absolute error tolerated"), + cl::init(0.0)); +cl::opt<double> RelTolerance("rel-tolerance", + cl::desc("Relative error tolerated"), + cl::init(0.0)); + +cl::opt<OutputType> InterpreterSel( + cl::desc("Specify the \"test\" i.e. suspect back-end:"), + cl::values(clEnumValN(AutoPick, "auto", "Use best guess"), + clEnumValN(RunLLI, "run-int", "Execute with the interpreter"), + clEnumValN(RunJIT, "run-jit", "Execute with JIT"), + clEnumValN(RunLLC, "run-llc", "Compile with LLC"), + clEnumValN(RunLLCIA, "run-llc-ia", + "Compile with LLC with integrated assembler"), + clEnumValN(LLC_Safe, "llc-safe", "Use LLC for all"), + clEnumValN(CompileCustom, "compile-custom", + "Use -compile-command to define a command to " + "compile the bitcode. Useful to avoid linking."), + clEnumValN(Custom, "run-custom", + "Use -exec-command to define a command to execute " + "the bitcode. Useful for cross-compilation."), + clEnumValEnd), + cl::init(AutoPick)); + +cl::opt<OutputType> 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(Custom, "safe-run-custom", + "Use -exec-command to define a command to execute " + "the bitcode. Useful for cross-compilation."), + clEnumValEnd), + cl::init(AutoPick)); + +cl::opt<std::string> SafeInterpreterPath( + "safe-path", cl::desc("Specify the path to the \"safe\" backend program"), + cl::init("")); + +cl::opt<bool> AppendProgramExitCode( + "append-exit-code", + cl::desc("Append the exit code to the output so it gets diff'd too"), + cl::init(false)); + +cl::opt<std::string> + InputFile("input", cl::init("/dev/null"), + cl::desc("Filename to pipe in as stdin (default: /dev/null)")); + +cl::list<std::string> + AdditionalSOs("additional-so", cl::desc("Additional shared objects to load " + "into executing programs")); + +cl::list<std::string> AdditionalLinkerArgs( + "Xlinker", cl::desc("Additional arguments to pass to the linker")); + +cl::opt<std::string> CustomCompileCommand( + "compile-command", cl::init("llc"), + cl::desc("Command to compile the bitcode (use with -compile-custom) " + "(default: llc)")); + +cl::opt<std::string> CustomExecCommand( + "exec-command", cl::init("simulate"), + cl::desc("Command to execute the bitcode (use with -run-custom) " + "(default: simulate)")); } namespace llvm { - // Anything specified after the --args option are taken as arguments to the - // program being debugged. - cl::list<std::string> - InputArgv("args", cl::Positional, cl::desc("<program arguments>..."), - cl::ZeroOrMore, cl::PositionalEatsArgs); - - cl::opt<std::string> - OutputPrefix("output-prefix", cl::init("bugpoint"), - cl::desc("Prefix to use for outputs (default: 'bugpoint')")); +// Anything specified after the --args option are taken as arguments to the +// program being debugged. +cl::list<std::string> InputArgv("args", cl::Positional, + cl::desc("<program arguments>..."), + cl::ZeroOrMore, cl::PositionalEatsArgs); + +cl::opt<std::string> + OutputPrefix("output-prefix", cl::init("bugpoint"), + cl::desc("Prefix to use for outputs (default: 'bugpoint')")); } namespace { - cl::list<std::string> - ToolArgv("tool-args", cl::Positional, cl::desc("<tool arguments>..."), - cl::ZeroOrMore, cl::PositionalEatsArgs); - - cl::list<std::string> - SafeToolArgv("safe-tool-args", cl::Positional, - cl::desc("<safe-tool arguments>..."), - cl::ZeroOrMore, cl::PositionalEatsArgs); - - cl::opt<std::string> - CCBinary("gcc", cl::init(""), cl::desc("The gcc binary to use.")); - - cl::list<std::string> - CCToolArgv("gcc-tool-args", cl::Positional, - cl::desc("<gcc-tool arguments>..."), - cl::ZeroOrMore, cl::PositionalEatsArgs); +cl::list<std::string> ToolArgv("tool-args", cl::Positional, + cl::desc("<tool arguments>..."), cl::ZeroOrMore, + cl::PositionalEatsArgs); + +cl::list<std::string> SafeToolArgv("safe-tool-args", cl::Positional, + cl::desc("<safe-tool arguments>..."), + cl::ZeroOrMore, cl::PositionalEatsArgs); + +cl::opt<std::string> CCBinary("gcc", cl::init(""), + cl::desc("The gcc binary to use.")); + +cl::list<std::string> CCToolArgv("gcc-tool-args", cl::Positional, + cl::desc("<gcc-tool arguments>..."), + cl::ZeroOrMore, cl::PositionalEatsArgs); } //===----------------------------------------------------------------------===// @@ -159,19 +160,18 @@ bool BugDriver::initializeExecutionEnvironment() { case AutoPick: if (!Interpreter) { InterpreterSel = RunJIT; - Interpreter = AbstractInterpreter::createJIT(getToolName(), Message, - &ToolArgv); + Interpreter = + AbstractInterpreter::createJIT(getToolName(), Message, &ToolArgv); } if (!Interpreter) { InterpreterSel = RunLLC; - Interpreter = AbstractInterpreter::createLLC(getToolName(), Message, - CCBinary, &ToolArgv, - &CCToolArgv); + Interpreter = AbstractInterpreter::createLLC( + getToolName(), Message, CCBinary, &ToolArgv, &CCToolArgv); } if (!Interpreter) { InterpreterSel = RunLLI; - Interpreter = AbstractInterpreter::createLLI(getToolName(), Message, - &ToolArgv); + Interpreter = + AbstractInterpreter::createLLI(getToolName(), Message, &ToolArgv); } if (!Interpreter) { InterpreterSel = AutoPick; @@ -179,28 +179,27 @@ bool BugDriver::initializeExecutionEnvironment() { } break; case RunLLI: - Interpreter = AbstractInterpreter::createLLI(getToolName(), Message, - &ToolArgv); + Interpreter = + AbstractInterpreter::createLLI(getToolName(), Message, &ToolArgv); break; case RunLLC: case RunLLCIA: case LLC_Safe: - Interpreter = AbstractInterpreter::createLLC(getToolName(), Message, - CCBinary, &ToolArgv, - &CCToolArgv, - InterpreterSel == RunLLCIA); + Interpreter = AbstractInterpreter::createLLC( + getToolName(), Message, CCBinary, &ToolArgv, &CCToolArgv, + InterpreterSel == RunLLCIA); break; case RunJIT: - Interpreter = AbstractInterpreter::createJIT(getToolName(), Message, - &ToolArgv); + Interpreter = + AbstractInterpreter::createJIT(getToolName(), Message, &ToolArgv); break; case CompileCustom: - Interpreter = - AbstractInterpreter::createCustomCompiler(Message, CustomCompileCommand); + Interpreter = AbstractInterpreter::createCustomCompiler( + Message, CustomCompileCommand); break; case Custom: Interpreter = - AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand); + AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand); break; } if (!Interpreter) @@ -215,25 +214,19 @@ bool BugDriver::initializeExecutionEnvironment() { switch (SafeInterpreterSel) { case AutoPick: // In "llc-safe" mode, default to using LLC as the "safe" backend. - if (!SafeInterpreter && - InterpreterSel == LLC_Safe) { + if (!SafeInterpreter && InterpreterSel == LLC_Safe) { SafeInterpreterSel = RunLLC; SafeToolArgs.push_back("--relocation-model=pic"); - SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, - CCBinary, - &SafeToolArgs, - &CCToolArgv); + SafeInterpreter = AbstractInterpreter::createLLC( + Path.c_str(), Message, CCBinary, &SafeToolArgs, &CCToolArgv); } - if (!SafeInterpreter && - InterpreterSel != RunLLC && + if (!SafeInterpreter && InterpreterSel != RunLLC && InterpreterSel != RunJIT) { SafeInterpreterSel = RunLLC; SafeToolArgs.push_back("--relocation-model=pic"); - SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, - CCBinary, - &SafeToolArgs, - &CCToolArgv); + SafeInterpreter = AbstractInterpreter::createLLC( + Path.c_str(), Message, CCBinary, &SafeToolArgs, &CCToolArgv); } if (!SafeInterpreter) { SafeInterpreterSel = AutoPick; @@ -243,24 +236,29 @@ bool BugDriver::initializeExecutionEnvironment() { case RunLLC: case RunLLCIA: SafeToolArgs.push_back("--relocation-model=pic"); - SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, - CCBinary, &SafeToolArgs, - &CCToolArgv, - SafeInterpreterSel == RunLLCIA); + SafeInterpreter = AbstractInterpreter::createLLC( + Path.c_str(), Message, CCBinary, &SafeToolArgs, &CCToolArgv, + SafeInterpreterSel == RunLLCIA); break; case Custom: SafeInterpreter = - AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand); + AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand); break; default: Message = "Sorry, this back-end is not supported by bugpoint as the " "\"safe\" backend right now!\n"; break; } - if (!SafeInterpreter) { outs() << Message << "\nExiting.\n"; exit(1); } + if (!SafeInterpreter) { + outs() << Message << "\nExiting.\n"; + exit(1); + } cc = CC::create(Message, CCBinary, &CCToolArgv); - if (!cc) { outs() << Message << "\nExiting.\n"; exit(1); } + if (!cc) { + outs() << Message << "\nExiting.\n"; + exit(1); + } // If there was an error creating the selected interpreter, quit with error. return Interpreter == nullptr; @@ -294,18 +292,16 @@ void BugDriver::compileProgram(Module *M, std::string *Error) const { Interpreter->compileProgram(BitcodeFile.str(), Error, Timeout, MemoryLimit); } - /// executeProgram - This method runs "Program", capturing the output of the /// program to a file, returning the filename of the file. A recommended /// filename may be optionally specified. /// -std::string BugDriver::executeProgram(const Module *Program, - std::string OutputFile, - std::string BitcodeFile, - const std::string &SharedObj, - AbstractInterpreter *AI, - std::string *Error) const { - if (!AI) AI = Interpreter; +std::string +BugDriver::executeProgram(const Module *Program, std::string OutputFile, + std::string BitcodeFile, const std::string &SharedObj, + AbstractInterpreter *AI, std::string *Error) const { + if (!AI) + AI = Interpreter; assert(AI && "Interpreter should have been created already!"); bool CreatedBitcode = false; if (BitcodeFile.empty()) { @@ -315,15 +311,15 @@ std::string BugDriver::executeProgram(const Module *Program, std::error_code EC = sys::fs::createUniqueFile( OutputPrefix + "-test-program-%%%%%%%.bc", UniqueFD, UniqueFilename); if (EC) { - errs() << ToolName << ": Error making unique filename: " - << EC.message() << "!\n"; + errs() << ToolName << ": Error making unique filename: " << EC.message() + << "!\n"; exit(1); } BitcodeFile = UniqueFilename.str(); if (writeProgramToFile(BitcodeFile, UniqueFD, Program)) { - errs() << ToolName << ": Error emitting bitcode to file '" - << BitcodeFile << "'!\n"; + errs() << ToolName << ": Error emitting bitcode to file '" << BitcodeFile + << "'!\n"; exit(1); } CreatedBitcode = true; @@ -331,17 +327,17 @@ std::string BugDriver::executeProgram(const Module *Program, // Remove the temporary bitcode file when we are done. std::string BitcodePath(BitcodeFile); - FileRemover BitcodeFileRemover(BitcodePath, - CreatedBitcode && !SaveTemps); + FileRemover BitcodeFileRemover(BitcodePath, CreatedBitcode && !SaveTemps); - if (OutputFile.empty()) OutputFile = OutputPrefix + "-execution-output-%%%%%%%"; + if (OutputFile.empty()) + OutputFile = OutputPrefix + "-execution-output-%%%%%%%"; // Check to see if this is a valid output filename... SmallString<128> UniqueFile; std::error_code EC = sys::fs::createUniqueFile(OutputFile, UniqueFile); if (EC) { - errs() << ToolName << ": Error making unique filename: " - << EC.message() << "\n"; + errs() << ToolName << ": Error making unique filename: " << EC.message() + << "\n"; exit(1); } OutputFile = UniqueFile.str(); @@ -361,11 +357,15 @@ std::string BugDriver::executeProgram(const Module *Program, errs() << "<timeout>"; static bool FirstTimeout = true; if (FirstTimeout) { - outs() << "\n" - "*** Program execution timed out! This mechanism is designed to handle\n" - " programs stuck in infinite loops gracefully. The -timeout option\n" - " can be used to change the timeout threshold or disable it completely\n" - " (with -timeout=0). This message is only displayed once.\n"; + outs() + << "\n" + "*** Program execution timed out! This mechanism is designed to " + "handle\n" + " programs stuck in infinite loops gracefully. The -timeout " + "option\n" + " can be used to change the timeout threshold or disable it " + "completely\n" + " (with -timeout=0). This message is only displayed once.\n"; FirstTimeout = false; } } @@ -395,14 +395,13 @@ std::string BugDriver::compileSharedObject(const std::string &BitcodeFile, std::string OutputFile; // Using the known-good backend. - CC::FileType FT = SafeInterpreter->OutputCode(BitcodeFile, OutputFile, - Error); + CC::FileType FT = SafeInterpreter->OutputCode(BitcodeFile, OutputFile, Error); if (!Error.empty()) return ""; std::string SharedObjectFile; bool Failure = cc->MakeSharedObject(OutputFile, FT, SharedObjectFile, - AdditionalLinkerArgs, Error); + AdditionalLinkerArgs, Error); if (!Error.empty()) return ""; if (Failure) @@ -447,8 +446,7 @@ bool BugDriver::createReferenceFile(Module *M, const std::string &Filename) { /// bool BugDriver::diffProgram(const Module *Program, const std::string &BitcodeFile, - const std::string &SharedObject, - bool RemoveBitcode, + const std::string &SharedObject, bool RemoveBitcode, std::string *ErrMsg) const { // Execute the program, generating an output file... std::string Output( @@ -458,16 +456,14 @@ bool BugDriver::diffProgram(const Module *Program, std::string Error; bool FilesDifferent = false; - if (int Diff = DiffFilesWithTolerance(ReferenceOutputFile, - Output, + if (int Diff = DiffFilesWithTolerance(ReferenceOutputFile, Output, AbsTolerance, RelTolerance, &Error)) { if (Diff == 2) { errs() << "While diffing output: " << Error << '\n'; exit(1); } FilesDifferent = true; - } - else { + } else { // Remove the generated output if there are no differences. sys::fs::remove(Output); } @@ -478,7 +474,4 @@ bool BugDriver::diffProgram(const Module *Program, return FilesDifferent; } -bool BugDriver::isExecutingJIT() { - return InterpreterSel == RunJIT; -} - +bool BugDriver::isExecutingJIT() { return InterpreterSel == RunJIT; } diff --git a/llvm/tools/bugpoint/ExtractFunction.cpp b/llvm/tools/bugpoint/ExtractFunction.cpp index de596a57d83..d57613ec5e3 100644 --- a/llvm/tools/bugpoint/ExtractFunction.cpp +++ b/llvm/tools/bugpoint/ExtractFunction.cpp @@ -37,50 +37,49 @@ using namespace llvm; #define DEBUG_TYPE "bugpoint" namespace llvm { - bool DisableSimplifyCFG = false; - extern cl::opt<std::string> OutputPrefix; +bool DisableSimplifyCFG = false; +extern cl::opt<std::string> OutputPrefix; } // End llvm namespace namespace { - cl::opt<bool> - NoDCE ("disable-dce", - cl::desc("Do not use the -dce pass to reduce testcases")); - 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 nullptr; - - 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; - } +cl::opt<bool> NoDCE("disable-dce", + cl::desc("Do not use the -dce pass to reduce testcases")); +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 nullptr; - 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); - } + 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 nullptr; } -} // end anonymous namespace + return nullptr; +} +} // end anonymous namespace std::unique_ptr<Module> BugDriver::deleteInstructionFromProgram(const Instruction *I, @@ -92,10 +91,10 @@ BugDriver::deleteInstructionFromProgram(const Instruction *I, const Function *PF = PBB->getParent(); Module::iterator RFI = Clone->begin(); // Get iterator to corresponding fn - std::advance(RFI, std::distance(PF->getParent()->begin(), - Module::const_iterator(PF))); + std::advance( + RFI, std::distance(PF->getParent()->begin(), Module::const_iterator(PF))); - Function::iterator RBI = RFI->begin(); // Get iterator to corresponding BB + Function::iterator RBI = RFI->begin(); // Get iterator to corresponding BB std::advance(RBI, std::distance(PF->begin(), Function::const_iterator(PBB))); BasicBlock::iterator RI = RBI->begin(); // Get iterator to corresponding inst @@ -116,7 +115,7 @@ BugDriver::deleteInstructionFromProgram(const Instruction *I, if (Simplification > 1 && !NoDCE) Passes.push_back("dce"); if (Simplification && !DisableSimplifyCFG) - Passes.push_back("simplifycfg"); // Delete dead control flow + Passes.push_back("simplifycfg"); // Delete dead control flow Passes.push_back("verify"); std::unique_ptr<Module> New = runPassesOn(Clone, Passes); @@ -184,15 +183,16 @@ static void eliminateAliases(GlobalValue *GV) { // GlobalAlias MAY NOT reference declarations. for (;;) { // 1. Find aliases - SmallVector<GlobalAlias*,1> aliases; + SmallVector<GlobalAlias *, 1> aliases; Module *M = GV->getParent(); - for (Module::alias_iterator I=M->alias_begin(), E=M->alias_end(); I!=E; ++I) + for (Module::alias_iterator I = M->alias_begin(), E = M->alias_end(); + I != E; ++I) if (I->getAliasee()->stripPointerCasts() == GV) aliases.push_back(&*I); if (aliases.empty()) break; // 2. Resolve aliases - for (unsigned i=0, e=aliases.size(); i<e; ++i) { + for (unsigned i = 0, e = aliases.size(); i < e; ++i) { aliases[i]->replaceAllUsesWith(aliases[i]->getAliasee()); aliases[i]->eraseFromParent(); } @@ -202,7 +202,8 @@ static void eliminateAliases(GlobalValue *GV) { } // -// DeleteGlobalInitializer - "Remove" the global variable by deleting its initializer, +// DeleteGlobalInitializer - "Remove" the global variable by deleting its +// initializer, // making it external. // void llvm::DeleteGlobalInitializer(GlobalVariable *GV) { @@ -225,23 +226,20 @@ void llvm::DeleteFunctionBody(Function *F) { /// GetTorInit - Given a list of entries for static ctors/dtors, return them /// as a constant array. -static Constant *GetTorInit(std::vector<std::pair<Function*, int> > &TorList) { +static Constant *GetTorInit(std::vector<std::pair<Function *, int>> &TorList) { assert(!TorList.empty() && "Don't create empty tor list!"); - std::vector<Constant*> ArrayElts; + std::vector<Constant *> ArrayElts; Type *Int32Ty = Type::getInt32Ty(TorList[0].first->getContext()); StructType *STy = StructType::get(Int32Ty, TorList[0].first->getType(), nullptr); for (unsigned i = 0, e = TorList.size(); i != e; ++i) { - Constant *Elts[] = { - ConstantInt::get(Int32Ty, TorList[i].second), - TorList[i].first - }; + Constant *Elts[] = {ConstantInt::get(Int32Ty, TorList[i].second), + TorList[i].first}; ArrayElts.push_back(ConstantStruct::get(STy, Elts)); } - return ConstantArray::get(ArrayType::get(ArrayElts[0]->getType(), - ArrayElts.size()), - ArrayElts); + return ConstantArray::get( + ArrayType::get(ArrayElts[0]->getType(), ArrayElts.size()), ArrayElts); } /// SplitStaticCtorDtor - A module was recently split into two parts, M1/M2, and @@ -251,23 +249,26 @@ static Constant *GetTorInit(std::vector<std::pair<Function*, int> > &TorList) { static void SplitStaticCtorDtor(const char *GlobalName, Module *M1, Module *M2, ValueToValueMapTy &VMap) { GlobalVariable *GV = M1->getNamedGlobal(GlobalName); - if (!GV || GV->isDeclaration() || GV->hasLocalLinkage() || - !GV->use_empty()) return; - - std::vector<std::pair<Function*, int> > M1Tors, M2Tors; + if (!GV || GV->isDeclaration() || GV->hasLocalLinkage() || !GV->use_empty()) + return; + + std::vector<std::pair<Function *, int>> M1Tors, M2Tors; ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer()); - if (!InitList) return; - + if (!InitList) + return; + for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { - if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))){ - if (CS->getNumOperands() != 2) return; // Not array of 2-element structs. - + if (ConstantStruct *CS = + dyn_cast<ConstantStruct>(InitList->getOperand(i))) { + if (CS->getNumOperands() != 2) + return; // Not array of 2-element structs. + if (CS->getOperand(1)->isNullValue()) - break; // Found a null terminator, stop here. - + break; // Found a null terminator, stop here. + ConstantInt *CI = dyn_cast<ConstantInt>(CS->getOperand(0)); int Priority = CI ? CI->getSExtValue() : 0; - + Constant *FP = CS->getOperand(1); if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP)) if (CE->isCast()) @@ -283,13 +284,12 @@ static void SplitStaticCtorDtor(const char *GlobalName, Module *M1, Module *M2, } } } - + GV->eraseFromParent(); if (!M1Tors.empty()) { Constant *M1Init = GetTorInit(M1Tors); new GlobalVariable(*M1, M1Init->getType(), false, - GlobalValue::AppendingLinkage, - M1Init, GlobalName); + GlobalValue::AppendingLinkage, M1Init, GlobalName); } GV = M2->getNamedGlobal(GlobalName); @@ -300,8 +300,7 @@ static void SplitStaticCtorDtor(const char *GlobalName, Module *M1, Module *M2, if (!M2Tors.empty()) { Constant *M2Init = GetTorInit(M2Tors); new GlobalVariable(*M2, M2Init->getType(), false, - GlobalValue::AppendingLinkage, - M2Init, GlobalName); + GlobalValue::AppendingLinkage, M2Init, GlobalName); } } @@ -330,10 +329,9 @@ llvm::SplitFunctionsOutOfModule(Module *M, const std::vector<Function *> &F, DEBUG(TNOF->printAsOperand(errs(), false)); DEBUG(errs() << "\n"); TestFunctions.insert(cast<Function>(NewVMap[TNOF])); - DeleteFunctionBody(TNOF); // Function is now external in this module! + DeleteFunctionBody(TNOF); // Function is now external in this module! } - // Remove the Safe functions from the Test module for (Function &I : *New) if (!TestFunctions.count(&I)) @@ -348,8 +346,9 @@ llvm::SplitFunctionsOutOfModule(Module *M, const std::vector<Function *> &F, "the global '"; GV->printAsOperand(errs(), false); errs() << "' with an initializer that references blockaddresses " - "from safe function '" << SafeFn->getName() - << "' and from test function '" << TestFn->getName() << "'.\n"; + "from safe function '" + << SafeFn->getName() << "' and from test function '" + << TestFn->getName() << "'.\n"; exit(1); } DeleteGlobalInitializer(&I); // Delete the initializer to make it external @@ -387,12 +386,13 @@ BugDriver::extractMappedBlocksFromModule(const std::vector<BasicBlock *> &BBs, sys::RemoveFileOnSignal(Filename); tool_output_file BlocksToNotExtractFile(Filename.c_str(), FD); - for (std::vector<BasicBlock*>::const_iterator I = BBs.begin(), E = BBs.end(); + for (std::vector<BasicBlock *>::const_iterator I = BBs.begin(), E = BBs.end(); I != E; ++I) { BasicBlock *BB = *I; // 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"); + if (!BB->hasName()) + BB->setName("tmpbb"); BlocksToNotExtractFile.os() << BB->getParent()->getName() << " " << BB->getName() << "\n"; } diff --git a/llvm/tools/bugpoint/FindBugs.cpp b/llvm/tools/bugpoint/FindBugs.cpp index a0c859b7f33..3c345c5503c 100644 --- a/llvm/tools/bugpoint/FindBugs.cpp +++ b/llvm/tools/bugpoint/FindBugs.cpp @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// // -// This file defines an interface that allows bugpoint to choose different -// combinations of optimizations to run on the selected input. Bugpoint will +// This file defines an interface that allows bugpoint to choose different +// combinations of optimizations to run on the selected input. Bugpoint will // run these optimizations and record the success/failure of each. This way // we can hopefully spot bugs in the optimizations. // @@ -23,47 +23,48 @@ #include <ctime> using namespace llvm; -/// runManyPasses - Take the specified pass list and create different +/// runManyPasses - Take the specified pass list and create different /// combinations of passes to compile the program with. Compile the program with -/// each set and mark test to see if it compiled correctly. If the passes +/// each set and mark test to see if it compiled correctly. If the passes /// compiled correctly output nothing and rearrange the passes into a new order. -/// If the passes did not compile correctly, output the command required to +/// If the passes did not compile correctly, output the command required to /// recreate the failure. This returns true if a compiler error is found. /// bool BugDriver::runManyPasses(const std::vector<std::string> &AllPasses, std::string &ErrMsg) { setPassesToRun(AllPasses); outs() << "Starting bug finding procedure...\n\n"; - + // Creating a reference output if necessary - if (initializeExecutionEnvironment()) return false; - + if (initializeExecutionEnvironment()) + return false; + outs() << "\n"; if (ReferenceOutputFile.empty()) { outs() << "Generating reference output from raw program: \n"; if (!createReferenceFile(Program)) return false; } - + srand(time(nullptr)); - + unsigned num = 1; - while(1) { + while (1) { // // Step 1: Randomize the order of the optimizer passes. // std::random_shuffle(PassesToRun.begin(), PassesToRun.end()); - + // // Step 2: Run optimizer passes on the program and check for success. // outs() << "Running selected passes on program to test for crash: "; - for(int i = 0, e = PassesToRun.size(); i != e; i++) { + for (int i = 0, e = PassesToRun.size(); i != e; i++) { outs() << "-" << PassesToRun[i] << " "; } - + std::string Filename; - if(runPasses(Program, PassesToRun, Filename, false)) { + if (runPasses(Program, PassesToRun, Filename, false)) { outs() << "\n"; outs() << "Optimizer passes caused failure!\n\n"; debugOptimizerCrash(); @@ -71,7 +72,7 @@ bool BugDriver::runManyPasses(const std::vector<std::string> &AllPasses, } else { outs() << "Combination " << num << " optimized successfully!\n"; } - + // // Step 3: Compile the optimized code. // @@ -84,9 +85,9 @@ bool BugDriver::runManyPasses(const std::vector<std::string> &AllPasses, return debugCodeGeneratorCrash(ErrMsg); } outs() << '\n'; - + // - // Step 4: Run the program and compare its output to the reference + // Step 4: Run the program and compare its output to the reference // output (created above). // outs() << "*** Checking if passes caused miscompliation:\n"; @@ -103,12 +104,12 @@ bool BugDriver::runManyPasses(const std::vector<std::string> &AllPasses, return true; } outs() << "\n*** diff'd output matches!\n"; - + sys::fs::remove(Filename); - + outs() << "\n\n"; num++; - } //end while - + } // end while + // Unreachable. } diff --git a/llvm/tools/bugpoint/Miscompilation.cpp b/llvm/tools/bugpoint/Miscompilation.cpp index 40955ed3caa..9069e00acb9 100644 --- a/llvm/tools/bugpoint/Miscompilation.cpp +++ b/llvm/tools/bugpoint/Miscompilation.cpp @@ -15,7 +15,7 @@ #include "BugDriver.h" #include "ListReducer.h" #include "ToolRunner.h" -#include "llvm/Config/config.h" // for HAVE_LINK_R +#include "llvm/Config/config.h" // for HAVE_LINK_R #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Instructions.h" @@ -30,29 +30,30 @@ using namespace llvm; namespace llvm { - extern cl::opt<std::string> OutputPrefix; - extern cl::list<std::string> InputArgv; +extern cl::opt<std::string> OutputPrefix; +extern cl::list<std::string> InputArgv; } // end namespace llvm namespace { - 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", - cl::desc("Don't extract blocks when searching for miscompilations"), - cl::init(false)); - - class ReduceMiscompilingPasses : public ListReducer<std::string> { - BugDriver &BD; - public: - ReduceMiscompilingPasses(BugDriver &bd) : BD(bd) {} - - TestResult doTest(std::vector<std::string> &Prefix, - std::vector<std::string> &Suffix, - std::string &Error) override; - }; +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", + cl::desc("Don't extract blocks when searching for miscompilations"), + cl::init(false)); + +class ReduceMiscompilingPasses : public ListReducer<std::string> { + BugDriver &BD; + +public: + ReduceMiscompilingPasses(BugDriver &bd) : BD(bd) {} + + TestResult doTest(std::vector<std::string> &Prefix, + std::vector<std::string> &Suffix, + std::string &Error) override; +}; } // end anonymous namespace /// TestResult - After passes have been split into a test group and a control @@ -68,12 +69,12 @@ ReduceMiscompilingPasses::doTest(std::vector<std::string> &Prefix, << "' compiles correctly: "; std::string BitcodeResult; - if (BD.runPasses(BD.getProgram(), 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); + BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); exit(BD.debugOptimizerCrash()); } @@ -89,11 +90,12 @@ ReduceMiscompilingPasses::doTest(std::vector<std::string> &Prefix, << "no passes are run, nondeterministic program?\n"; exit(1); } - return KeepSuffix; // Miscompilation detected! + return KeepSuffix; // Miscompilation detected! } - outs() << " yup.\n"; // No miscompilation! + outs() << " yup.\n"; // No miscompilation! - if (Prefix.empty()) return NoFailure; + if (Prefix.empty()) + return NoFailure; // Next, see if the program is broken if we run the "prefix" passes first, // then separately run the "kept" passes. @@ -106,12 +108,12 @@ ReduceMiscompilingPasses::doTest(std::vector<std::string> &Prefix, // kept passes, we can update our bitcode file to include the result of the // prefix passes, then discard the prefix passes. // - if (BD.runPasses(BD.getProgram(), 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); - BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); + BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); exit(BD.debugOptimizerCrash()); } @@ -124,7 +126,7 @@ ReduceMiscompilingPasses::doTest(std::vector<std::string> &Prefix, sys::fs::remove(BitcodeResult); return KeepPrefix; } - outs() << " yup.\n"; // No miscompilation! + outs() << " yup.\n"; // No miscompilation! // Ok, so now we know that the prefix passes work, try running the suffix // passes on the result of the prefix passes. @@ -143,17 +145,17 @@ ReduceMiscompilingPasses::doTest(std::vector<std::string> &Prefix, return NoFailure; outs() << "Checking to see if '" << getPassesString(Suffix) - << "' passes compile correctly after the '" - << getPassesString(Prefix) << "' passes: "; + << "' passes compile correctly after the '" << getPassesString(Prefix) + << "' passes: "; std::unique_ptr<Module> OriginalInput( BD.swapProgramIn(PrefixOutput.release())); - if (BD.runPasses(BD.getProgram(), 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); + BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); exit(BD.debugOptimizerCrash()); } @@ -168,47 +170,46 @@ ReduceMiscompilingPasses::doTest(std::vector<std::string> &Prefix, } // Otherwise, we must not be running the bad pass anymore. - outs() << " yup.\n"; // No miscompilation! + outs() << " yup.\n"; // No miscompilation! // Restore orig program & free test. delete BD.swapProgramIn(OriginalInput.release()); return NoFailure; } namespace { - class ReduceMiscompilingFunctions : public ListReducer<Function*> { - BugDriver &BD; - bool (*TestFn)(BugDriver &, std::unique_ptr<Module>, - std::unique_ptr<Module>, std::string &); - - public: - ReduceMiscompilingFunctions(BugDriver &bd, - bool (*F)(BugDriver &, std::unique_ptr<Module>, - std::unique_ptr<Module>, - std::string &)) - : BD(bd), TestFn(F) {} - - TestResult doTest(std::vector<Function*> &Prefix, - std::vector<Function*> &Suffix, - std::string &Error) override { - if (!Suffix.empty()) { - bool Ret = TestFuncs(Suffix, Error); - if (!Error.empty()) - return InternalError; - if (Ret) - return KeepSuffix; - } - if (!Prefix.empty()) { - bool Ret = TestFuncs(Prefix, Error); - if (!Error.empty()) - return InternalError; - if (Ret) - return KeepPrefix; - } - return NoFailure; +class ReduceMiscompilingFunctions : public ListReducer<Function *> { + BugDriver &BD; + bool (*TestFn)(BugDriver &, std::unique_ptr<Module>, std::unique_ptr<Module>, + std::string &); + +public: + ReduceMiscompilingFunctions(BugDriver &bd, + bool (*F)(BugDriver &, std::unique_ptr<Module>, + std::unique_ptr<Module>, std::string &)) + : BD(bd), TestFn(F) {} + + TestResult doTest(std::vector<Function *> &Prefix, + std::vector<Function *> &Suffix, + std::string &Error) override { + if (!Suffix.empty()) { + bool Ret = TestFuncs(Suffix, Error); + if (!Error.empty()) + return InternalError; + if (Ret) + return KeepSuffix; + } + if (!Prefix.empty()) { + bool Ret = TestFuncs(Prefix, Error); + if (!Error.empty()) + return InternalError; + if (Ret) + return KeepPrefix; } + return NoFailure; + } - bool TestFuncs(const std::vector<Function*> &Prefix, std::string &Error); - }; + bool TestFuncs(const std::vector<Function *> &Prefix, std::string &Error); +}; } // end anonymous namespace /// Given two modules, link them together and run the program, checking to see @@ -236,12 +237,12 @@ static std::unique_ptr<Module> testMergedProgram(const BugDriver &BD, /// under consideration for miscompilation vs. those that are not, and test /// accordingly. Each group of functions becomes a separate Module. /// -bool ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function*> &Funcs, - std::string &Error) { +bool ReduceMiscompilingFunctions::TestFuncs( + const std::vector<Function *> &Funcs, std::string &Error) { // Test to see if the function is misoptimized if we ONLY run it on the // functions listed in Funcs. outs() << "Checking to see if the program is misoptimized when " - << (Funcs.size()==1 ? "this function is" : "these functions are") + << (Funcs.size() == 1 ? "this function is" : "these functions are") << " run through the pass" << (BD.getPassesToRun().size() == 1 ? "" : "es") << ":"; PrintFunctionList(Funcs); @@ -258,7 +259,7 @@ bool ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function*> &Funcs, Module *Clone = CloneModule(BD.getProgram(), VMap).release(); Module *Orig = BD.swapProgramIn(Clone); - std::vector<Function*> FuncsOnClone; + std::vector<Function *> FuncsOnClone; for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { Function *F = cast<Function>(VMap[Funcs[i]]); FuncsOnClone.push_back(F); @@ -301,7 +302,8 @@ static bool ExtractLoops(BugDriver &BD, std::string &Error) { bool MadeChange = false; while (1) { - if (BugpointIsInterrupted) return MadeChange; + if (BugpointIsInterrupted) + return MadeChange; ValueToValueMapTy VMap; std::unique_ptr<Module> ToNotOptimize = CloneModule(BD.getProgram(), VMap); @@ -353,8 +355,8 @@ static bool ExtractLoops(BugDriver &BD, BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to-le.bc", ToOptimizeLoopExtracted.get()); - errs() << "Please submit the " - << OutputPrefix << "-loop-extract-fail-*.bc files.\n"; + errs() << "Please submit the " << OutputPrefix + << "-loop-extract-fail-*.bc files.\n"; delete ToOptimize; return MadeChange; } @@ -383,7 +385,7 @@ static bool ExtractLoops(BugDriver &BD, // If the program is not still broken, then loop extraction did something // that masked the error. Stop loop extraction now. - std::vector<std::pair<std::string, FunctionType*> > MisCompFunctions; + std::vector<std::pair<std::string, FunctionType *>> MisCompFunctions; for (Function *F : MiscompiledFunctions) { MisCompFunctions.emplace_back(F->getName(), F->getFunctionType()); } @@ -406,9 +408,10 @@ static bool ExtractLoops(BugDriver &BD, outs() << "*** Loop extraction successful!\n"; - std::vector<std::pair<std::string, FunctionType*> > MisCompFunctions; + std::vector<std::pair<std::string, FunctionType *>> MisCompFunctions; for (Module::iterator I = ToOptimizeLoopExtracted->begin(), - E = ToOptimizeLoopExtracted->end(); I != E; ++I) + E = ToOptimizeLoopExtracted->end(); + I != E; ++I) if (!I->isDeclaration()) MisCompFunctions.emplace_back(I->getName(), I->getFunctionType()); @@ -436,46 +439,47 @@ static bool ExtractLoops(BugDriver &BD, } namespace { - class ReduceMiscompiledBlocks : public ListReducer<BasicBlock*> { - BugDriver &BD; - bool (*TestFn)(BugDriver &, std::unique_ptr<Module>, - std::unique_ptr<Module>, std::string &); - std::vector<Function*> FunctionsBeingTested; - public: - ReduceMiscompiledBlocks(BugDriver &bd, - bool (*F)(BugDriver &, std::unique_ptr<Module>, - std::unique_ptr<Module>, std::string &), - const std::vector<Function *> &Fns) - : BD(bd), TestFn(F), FunctionsBeingTested(Fns) {} - - TestResult doTest(std::vector<BasicBlock*> &Prefix, - std::vector<BasicBlock*> &Suffix, - std::string &Error) override { - if (!Suffix.empty()) { - bool Ret = TestFuncs(Suffix, Error); - if (!Error.empty()) - return InternalError; - if (Ret) - return KeepSuffix; - } - if (!Prefix.empty()) { - bool Ret = TestFuncs(Prefix, Error); - if (!Error.empty()) - return InternalError; - if (Ret) - return KeepPrefix; - } - return NoFailure; +class ReduceMiscompiledBlocks : public ListReducer<BasicBlock *> { + BugDriver &BD; + bool (*TestFn)(BugDriver &, std::unique_ptr<Module>, std::unique_ptr<Module>, + std::string &); + std::vector<Function *> FunctionsBeingTested; + +public: + ReduceMiscompiledBlocks(BugDriver &bd, + bool (*F)(BugDriver &, std::unique_ptr<Module>, + std::unique_ptr<Module>, std::string &), + const std::vector<Function *> &Fns) + : BD(bd), TestFn(F), FunctionsBeingTested(Fns) {} + + TestResult doTest(std::vector<BasicBlock *> &Prefix, + std::vector<BasicBlock *> &Suffix, + std::string &Error) override { + if (!Suffix.empty()) { + bool Ret = TestFuncs(Suffix, Error); + if (!Error.empty()) + return InternalError; + if (Ret) + return KeepSuffix; + } + if (!Prefix.empty()) { + bool Ret = TestFuncs(Prefix, Error); + if (!Error.empty()) + return InternalError; + if (Ret) + return KeepPrefix; } + return NoFailure; + } - bool TestFuncs(const std::vector<BasicBlock*> &BBs, std::string &Error); - }; + bool TestFuncs(const std::vector<BasicBlock *> &BBs, std::string &Error); +}; } // end anonymous namespace /// TestFuncs - Extract all blocks for the miscompiled functions except for the /// specified blocks. If the problem still exists, return true. /// -bool ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock*> &BBs, +bool ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock *> &BBs, std::string &Error) { // Test to see if the function is misoptimized if we ONLY run it on the // functions listed in Funcs. @@ -484,7 +488,8 @@ bool ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock*> &BBs, outs() << "but these " << BBs.size() << " blocks are extracted: "; for (unsigned i = 0, e = BBs.size() < 10 ? BBs.size() : 10; i != e; ++i) outs() << BBs[i]->getName() << " "; - if (BBs.size() > 10) outs() << "..."; + if (BBs.size() > 10) + outs() << "..."; } else { outs() << "blocks are extracted."; } @@ -494,8 +499,8 @@ bool ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock*> &BBs, ValueToValueMapTy VMap; Module *Clone = CloneModule(BD.getProgram(), VMap).release(); Module *Orig = BD.swapProgramIn(Clone); - std::vector<Function*> FuncsOnClone; - std::vector<BasicBlock*> BBsOnClone; + std::vector<Function *> FuncsOnClone; + std::vector<BasicBlock *> BBsOnClone; for (unsigned i = 0, e = FunctionsBeingTested.size(); i != e; ++i) { Function *F = cast<Function>(VMap[FunctionsBeingTested[i]]); FuncsOnClone.push_back(F); @@ -531,9 +536,10 @@ static bool ExtractBlocks(BugDriver &BD, std::string &), std::vector<Function *> &MiscompiledFunctions, std::string &Error) { - if (BugpointIsInterrupted) return false; + if (BugpointIsInterrupted) + return false; - std::vector<BasicBlock*> Blocks; + std::vector<BasicBlock *> Blocks; for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) for (BasicBlock &BB : *MiscompiledFunctions[i]) Blocks.push_back(&BB); @@ -545,14 +551,14 @@ static bool ExtractBlocks(BugDriver &BD, // Check to see if all blocks are extractible first. bool Ret = ReduceMiscompiledBlocks(BD, TestFn, MiscompiledFunctions) - .TestFuncs(std::vector<BasicBlock*>(), Error); + .TestFuncs(std::vector<BasicBlock *>(), Error); if (!Error.empty()) return false; if (Ret) { Blocks.clear(); } else { - ReduceMiscompiledBlocks(BD, TestFn, - MiscompiledFunctions).reduceList(Blocks, Error); + ReduceMiscompiledBlocks(BD, TestFn, MiscompiledFunctions) + .reduceList(Blocks, Error); if (!Error.empty()) return false; if (Blocks.size() == OldSize) @@ -578,9 +584,9 @@ static bool ExtractBlocks(BugDriver &BD, // together. delete ToExtract; - std::vector<std::pair<std::string, FunctionType*> > MisCompFunctions; - for (Module::iterator I = Extracted->begin(), E = Extracted->end(); - I != E; ++I) + std::vector<std::pair<std::string, FunctionType *>> MisCompFunctions; + for (Module::iterator I = Extracted->begin(), E = Extracted->end(); I != E; + ++I) if (!I->isDeclaration()) MisCompFunctions.emplace_back(I->getName(), I->getFunctionType()); @@ -614,7 +620,7 @@ DebugAMiscompilation(BugDriver &BD, // failure, see if we can pin down which functions are being // miscompiled... first build a list of all of the non-external functions in // the program. - std::vector<Function*> MiscompiledFunctions; + std::vector<Function *> MiscompiledFunctions; Module *Prog = BD.getProgram(); for (Function &F : *Prog) if (!F.isDeclaration()) @@ -622,8 +628,8 @@ DebugAMiscompilation(BugDriver &BD, // Do the reduction... if (!BugpointIsInterrupted) - ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions, - Error); + ReduceMiscompilingFunctions(BD, TestFn) + .reduceList(MiscompiledFunctions, Error); if (!Error.empty()) { errs() << "\n***Cannot reduce functions: "; return MiscompiledFunctions; @@ -648,8 +654,8 @@ DebugAMiscompilation(BugDriver &BD, // Do the reduction... if (!BugpointIsInterrupted) - ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions, - Error); + ReduceMiscompilingFunctions(BD, TestFn) + .reduceList(MiscompiledFunctions, Error); if (!Error.empty()) return MiscompiledFunctions; @@ -671,8 +677,8 @@ DebugAMiscompilation(BugDriver &BD, DisambiguateGlobalSymbols(BD.getProgram()); // Do the reduction... - ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions, - Error); + ReduceMiscompilingFunctions(BD, TestFn) + .reduceList(MiscompiledFunctions, Error); if (!Error.empty()) return MiscompiledFunctions; @@ -702,7 +708,7 @@ static bool TestOptimizer(BugDriver &BD, std::unique_ptr<Module> Test, errs() << " Error running this sequence of passes" << " on the input program!\n"; delete BD.swapProgramIn(Test.get()); - BD.EmitProgressBitcode(Test.get(), "pass-error", false); + BD.EmitProgressBitcode(Test.get(), "pass-error", false); return BD.debugOptimizerCrash(); } outs() << "done.\n"; @@ -739,7 +745,7 @@ void BugDriver::debugMiscompilation(std::string *Error) { EmitProgressBitcode(Program, "passinput"); std::vector<Function *> MiscompiledFunctions = - DebugAMiscompilation(*this, TestOptimizer, *Error); + DebugAMiscompilation(*this, TestOptimizer, *Error); if (!Error->empty()) return; @@ -753,11 +759,11 @@ void BugDriver::debugMiscompilation(std::string *Error) { outs() << " Non-optimized portion: "; EmitProgressBitcode(ToNotOptimize, "tonotoptimize", true); - delete ToNotOptimize; // Delete hacked module. + delete ToNotOptimize; // Delete hacked module. outs() << " Portion that is input to optimizer: "; EmitProgressBitcode(ToOptimize, "tooptimize"); - delete ToOptimize; // Delete hacked module. + delete ToOptimize; // Delete hacked module. } /// Get the specified modules ready for code generator testing. @@ -769,7 +775,8 @@ static void CleanupAndPrepareModules(BugDriver &BD, Test = BD.performFinalCleanups(Test.get()); // If we are executing the JIT, we have several nasty issues to take care of. - if (!BD.isExecutingJIT()) return; + if (!BD.isExecutingJIT()) + return; // First, if the main function is in the Safe module, we must add a stub to // the Test module to call into it. Thus, we create a new function `main' @@ -788,11 +795,12 @@ static void CleanupAndPrepareModules(BugDriver &BD, GlobalValue::ExternalLinkage, oldMain->getName(), Test.get()); // Set up and remember the argument list for the main function. - std::vector<Value*> args; - for (Function::arg_iterator - I = newMain->arg_begin(), E = newMain->arg_end(), - OI = oldMain->arg_begin(); I != E; ++I, ++OI) { - I->setName(OI->getName()); // Copy argument names from oldMain + std::vector<Value *> args; + for (Function::arg_iterator I = newMain->arg_begin(), + E = newMain->arg_end(), + OI = oldMain->arg_begin(); + I != E; ++I, ++OI) { + I->setName(OI->getName()); // Copy argument names from oldMain args.push_back(&*I); } @@ -811,11 +819,9 @@ static void CleanupAndPrepareModules(BugDriver &BD, // Add the resolver to the Safe module. // Prototype: void *getPointerToNamedFunction(const char* Name) - Constant *resolverFunc = - Safe->getOrInsertFunction("getPointerToNamedFunction", - Type::getInt8PtrTy(Safe->getContext()), - Type::getInt8PtrTy(Safe->getContext()), - (Type *)nullptr); + Constant *resolverFunc = Safe->getOrInsertFunction( + "getPointerToNamedFunction", Type::getInt8PtrTy(Safe->getContext()), + Type::getInt8PtrTy(Safe->getContext()), (Type *)nullptr); // Use the function we just added to get addresses of functions we need. for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) { @@ -827,21 +833,20 @@ static void CleanupAndPrepareModules(BugDriver &BD, if (TestFn && !TestFn->isDeclaration()) { // 1. Add a string constant with its name to the global file Constant *InitArray = - ConstantDataArray::getString(F->getContext(), F->getName()); - GlobalVariable *funcName = - new GlobalVariable(*Safe, InitArray->getType(), true /*isConstant*/, - GlobalValue::InternalLinkage, InitArray, - F->getName() + "_name"); + ConstantDataArray::getString(F->getContext(), F->getName()); + GlobalVariable *funcName = new GlobalVariable( + *Safe, InitArray->getType(), true /*isConstant*/, + GlobalValue::InternalLinkage, InitArray, F->getName() + "_name"); // 2. Use `GetElementPtr *funcName, 0, 0' to convert the string to an // sbyte* so it matches the signature of the resolver function. // GetElementPtr *funcName, ulong 0, ulong 0 - std::vector<Constant*> GEPargs(2, - Constant::getNullValue(Type::getInt32Ty(F->getContext()))); + std::vector<Constant *> GEPargs( + 2, Constant::getNullValue(Type::getInt32Ty(F->getContext()))); Value *GEP = ConstantExpr::getGetElementPtr(InitArray->getType(), funcName, GEPargs); - std::vector<Value*> ResolverArgs; + std::vector<Value *> ResolverArgs; ResolverArgs.push_back(GEP); // Rewrite uses of F in global initializers, etc. to uses of a wrapper @@ -849,23 +854,21 @@ static void CleanupAndPrepareModules(BugDriver &BD, if (!F->use_empty()) { // Create a new global to hold the cached function pointer. Constant *NullPtr = ConstantPointerNull::get(F->getType()); - GlobalVariable *Cache = - new GlobalVariable(*F->getParent(), F->getType(), - false, GlobalValue::InternalLinkage, - NullPtr,F->getName()+".fpcache"); + GlobalVariable *Cache = 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 FunctionType *FuncTy = F->getFunctionType(); - Function *FuncWrapper = Function::Create(FuncTy, - GlobalValue::InternalLinkage, - F->getName() + "_wrapper", - F->getParent()); - BasicBlock *EntryBB = BasicBlock::Create(F->getContext(), - "entry", FuncWrapper); - BasicBlock *DoCallBB = BasicBlock::Create(F->getContext(), - "usecache", FuncWrapper); - BasicBlock *LookupBB = BasicBlock::Create(F->getContext(), - "lookupfp", FuncWrapper); + Function *FuncWrapper = + Function::Create(FuncTy, GlobalValue::InternalLinkage, + F->getName() + "_wrapper", F->getParent()); + BasicBlock *EntryBB = + BasicBlock::Create(F->getContext(), "entry", FuncWrapper); + BasicBlock *DoCallBB = + BasicBlock::Create(F->getContext(), "usecache", FuncWrapper); + BasicBlock *LookupBB = + BasicBlock::Create(F->getContext(), "lookupfp", FuncWrapper); // Check to see if we already looked up the value. Value *CachedVal = new LoadInst(Cache, "fpcache", EntryBB); @@ -876,26 +879,25 @@ static void CleanupAndPrepareModules(BugDriver &BD, // Resolve the call to function F via the JIT API: // // call resolver(GetElementPtr...) - CallInst *Resolver = - CallInst::Create(resolverFunc, ResolverArgs, "resolver", LookupBB); + CallInst *Resolver = CallInst::Create(resolverFunc, ResolverArgs, + "resolver", LookupBB); // Cast the result from the resolver to correctly-typed function. - CastInst *CastedResolver = - new BitCastInst(Resolver, - PointerType::getUnqual(F->getFunctionType()), - "resolverCast", LookupBB); + CastInst *CastedResolver = new BitCastInst( + Resolver, PointerType::getUnqual(F->getFunctionType()), + "resolverCast", LookupBB); // Save the value in our cache. new StoreInst(CastedResolver, Cache, LookupBB); BranchInst::Create(DoCallBB, LookupBB); - PHINode *FuncPtr = PHINode::Create(NullPtr->getType(), 2, - "fp", DoCallBB); + PHINode *FuncPtr = + PHINode::Create(NullPtr->getType(), 2, "fp", DoCallBB); FuncPtr->addIncoming(CastedResolver, LookupBB); FuncPtr->addIncoming(CachedVal, EntryBB); // Save the argument list. - std::vector<Value*> Args; + std::vector<Value *> Args; for (Argument &A : FuncWrapper->args()) Args.push_back(&A); @@ -904,9 +906,9 @@ static void CleanupAndPrepareModules(BugDriver &BD, CallInst::Create(FuncPtr, Args, "", DoCallBB); ReturnInst::Create(F->getContext(), DoCallBB); } else { - CallInst *Call = CallInst::Create(FuncPtr, Args, - "retval", DoCallBB); - ReturnInst::Create(F->getContext(),Call, DoCallBB); + CallInst *Call = + CallInst::Create(FuncPtr, Args, "retval", DoCallBB); + ReturnInst::Create(F->getContext(), Call, DoCallBB); } // Use the wrapper function instead of the old function @@ -936,8 +938,8 @@ static bool TestCodeGenerator(BugDriver &BD, std::unique_ptr<Module> Test, std::error_code EC = sys::fs::createTemporaryFile("bugpoint.test", "bc", TestModuleFD, TestModuleBC); if (EC) { - errs() << BD.getToolName() << "Error making unique filename: " - << EC.message() << "\n"; + errs() << BD.getToolName() + << "Error making unique filename: " << EC.message() << "\n"; exit(1); } if (BD.writeProgramToFile(TestModuleBC.str(), TestModuleFD, Test.get())) { @@ -954,14 +956,13 @@ static bool TestCodeGenerator(BugDriver &BD, std::unique_ptr<Module> Test, EC = sys::fs::createTemporaryFile("bugpoint.safe", "bc", SafeModuleFD, SafeModuleBC); if (EC) { - errs() << BD.getToolName() << "Error making unique filename: " - << EC.message() << "\n"; + errs() << BD.getToolName() + << "Error making unique filename: " << EC.message() << "\n"; exit(1); } if (BD.writeProgramToFile(SafeModuleBC.str(), SafeModuleFD, Safe.get())) { - errs() << "Error writing bitcode to `" << SafeModuleBC - << "'\nExiting."; + errs() << "Error writing bitcode to `" << SafeModuleBC << "'\nExiting."; exit(1); } @@ -991,9 +992,9 @@ static bool TestCodeGenerator(BugDriver &BD, std::unique_ptr<Module> Test, /// debugCodeGenerator - debug errors in LLC, LLI, or CBE. /// bool BugDriver::debugCodeGenerator(std::string *Error) { - if ((void*)SafeInterpreter == (void*)Interpreter) { - std::string Result = executeProgramSafely(Program, "bugpoint.safe.out", - Error); + if ((void *)SafeInterpreter == (void *)Interpreter) { + std::string Result = + executeProgramSafely(Program, "bugpoint.safe.out", Error); if (Error->empty()) { outs() << "\n*** The \"safe\" i.e. 'known good' backend cannot match " << "the reference diff. This may be due to a\n front-end " @@ -1001,16 +1002,15 @@ bool BugDriver::debugCodeGenerator(std::string *Error) { << "happen if bugpoint isn't running the program with the " << "right flags or input.\n I left the result of executing " << "the program with the \"safe\" backend in this file for " - << "you: '" - << Result << "'.\n"; + << "you: '" << Result << "'.\n"; } return true; } DisambiguateGlobalSymbols(Program); - std::vector<Function*> Funcs = DebugAMiscompilation(*this, TestCodeGenerator, - *Error); + std::vector<Function *> Funcs = + DebugAMiscompilation(*this, TestCodeGenerator, *Error); if (!Error->empty()) return true; @@ -1028,14 +1028,13 @@ bool BugDriver::debugCodeGenerator(std::string *Error) { std::error_code EC = sys::fs::createTemporaryFile("bugpoint.test", "bc", TestModuleFD, TestModuleBC); if (EC) { - errs() << getToolName() << "Error making unique filename: " - << EC.message() << "\n"; + errs() << getToolName() << "Error making unique filename: " << EC.message() + << "\n"; exit(1); } if (writeProgramToFile(TestModuleBC.str(), TestModuleFD, ToCodeGen.get())) { - errs() << "Error writing bitcode to `" << TestModuleBC - << "'\nExiting."; + errs() << "Error writing bitcode to `" << TestModuleBC << "'\nExiting."; exit(1); } @@ -1045,15 +1044,14 @@ bool BugDriver::debugCodeGenerator(std::string *Error) { EC = sys::fs::createTemporaryFile("bugpoint.safe", "bc", SafeModuleFD, SafeModuleBC); if (EC) { - errs() << getToolName() << "Error making unique filename: " - << EC.message() << "\n"; + errs() << getToolName() << "Error making unique filename: " << EC.message() + << "\n"; exit(1); } if (writeProgramToFile(SafeModuleBC.str(), SafeModuleFD, ToNotCodeGen.get())) { - errs() << "Error writing bitcode to `" << SafeModuleBC - << "'\nExiting."; + errs() << "Error writing bitcode to `" << SafeModuleBC << "'\nExiting."; exit(1); } std::string SharedObject = compileSharedObject(SafeModuleBC.str(), *Error); @@ -1064,11 +1062,10 @@ bool BugDriver::debugCodeGenerator(std::string *Error) { if (isExecutingJIT()) { outs() << " lli -load " << SharedObject << " " << TestModuleBC; } else { - outs() << " llc " << TestModuleBC << " -o " << TestModuleBC - << ".s\n"; - outs() << " cc " << SharedObject << " " << TestModuleBC.str() - << ".s -o " << TestModuleBC << ".exe"; -#if defined (HAVE_LINK_R) + outs() << " llc " << TestModuleBC << " -o " << TestModuleBC << ".s\n"; + outs() << " cc " << SharedObject << " " << TestModuleBC.str() << ".s -o " + << TestModuleBC << ".exe"; +#if defined(HAVE_LINK_R) outs() << " -Wl,-R."; #endif outs() << "\n"; @@ -1081,9 +1078,9 @@ bool BugDriver::debugCodeGenerator(std::string *Error) { << SafeModuleBC.str() << " -o temporary.c\n" << " cc -xc temporary.c -O2 -o " << SharedObject; if (TargetTriple.getArch() == Triple::sparc) - outs() << " -G"; // Compile a shared library, `-G' for Sparc + outs() << " -G"; // Compile a shared library, `-G' for Sparc else - outs() << " -fPIC -shared"; // `-shared' for Linux/X86, maybe others + outs() << " -fPIC -shared"; // `-shared' for Linux/X86, maybe others outs() << " -fno-strict-aliasing\n"; diff --git a/llvm/tools/bugpoint/OptimizerDriver.cpp b/llvm/tools/bugpoint/OptimizerDriver.cpp index 2cc2f4471a5..7952ab1ac73 100644 --- a/llvm/tools/bugpoint/OptimizerDriver.cpp +++ b/llvm/tools/bugpoint/OptimizerDriver.cpp @@ -39,7 +39,7 @@ using namespace llvm; #define DEBUG_TYPE "bugpoint" namespace llvm { - extern cl::opt<std::string> OutputPrefix; +extern cl::opt<std::string> OutputPrefix; } static cl::opt<bool> PreserveBitcodeUseListOrder( @@ -48,12 +48,12 @@ static cl::opt<bool> PreserveBitcodeUseListOrder( cl::init(true), cl::Hidden); namespace { - // ChildOutput - This option captures the name of the child output file that - // is set up by the parent bugpoint process - cl::opt<std::string> ChildOutput("child-output", cl::ReallyHidden); - cl::opt<std::string> OptCmd("opt-command", cl::init(""), - cl::desc("Path to opt. (default: search path " - "for 'opt'.)")); +// ChildOutput - This option captures the name of the child output file that +// is set up by the parent bugpoint process +cl::opt<std::string> ChildOutput("child-output", cl::ReallyHidden); +cl::opt<std::string> OptCmd("opt-command", cl::init(""), + cl::desc("Path to opt. (default: search path " + "for 'opt'.)")); } /// writeProgramToFile - This writes the current "Program" to the named bitcode @@ -84,26 +84,26 @@ bool BugDriver::writeProgramToFile(const std::string &Filename, return true; } - /// EmitProgressBitcode - This function is used to output the current Program /// to a file named "bugpoint-ID.bc". /// -void BugDriver::EmitProgressBitcode(const Module *M, - const std::string &ID, - bool NoFlyer) const { +void BugDriver::EmitProgressBitcode(const Module *M, const std::string &ID, + bool NoFlyer) const { // Output the input to the current pass to a bitcode file, emit a message // telling the user how to reproduce it: opt -foo blah.bc // std::string Filename = OutputPrefix + "-" + ID + ".bc"; if (writeProgramToFile(Filename, M)) { - errs() << "Error opening file '" << Filename << "' for writing!\n"; + errs() << "Error opening file '" << Filename << "' for writing!\n"; return; } outs() << "Emitted bitcode to '" << Filename << "'\n"; - if (NoFlyer || PassesToRun.empty()) return; + if (NoFlyer || PassesToRun.empty()) + return; outs() << "\n*** You can reproduce the problem with: "; - if (UseValgrind) outs() << "valgrind "; + if (UseValgrind) + outs() << "valgrind "; outs() << "opt " << Filename; for (unsigned i = 0, e = PluginLoader::getNumPlugins(); i != e; ++i) { outs() << " -load " << PluginLoader::getPlugin(i); @@ -111,8 +111,9 @@ void BugDriver::EmitProgressBitcode(const Module *M, outs() << " " << getPassesString(PassesToRun) << "\n"; } -cl::opt<bool> SilencePasses("silence-passes", - cl::desc("Suppress output of running passes (both stdout and stderr)")); +cl::opt<bool> SilencePasses( + "silence-passes", + cl::desc("Suppress output of running passes (both stdout and stderr)")); static cl::list<std::string> OptArgs("opt-args", cl::Positional, cl::desc("<opt arguments>..."), @@ -130,15 +131,15 @@ bool BugDriver::runPasses(Module *Program, const std::vector<std::string> &Passes, std::string &OutputFilename, bool DeleteOutput, bool Quiet, unsigned NumExtraArgs, - const char * const *ExtraArgs) const { + const char *const *ExtraArgs) const { // setup the output file name outs().flush(); SmallString<128> UniqueFilename; std::error_code EC = sys::fs::createUniqueFile( OutputPrefix + "-output-%%%%%%%.bc", UniqueFilename); if (EC) { - errs() << getToolName() << ": Error making unique filename: " - << EC.message() << "\n"; + errs() << getToolName() + << ": Error making unique filename: " << EC.message() << "\n"; return 1; } OutputFilename = UniqueFilename.str(); @@ -149,8 +150,8 @@ bool BugDriver::runPasses(Module *Program, EC = sys::fs::createUniqueFile(OutputPrefix + "-input-%%%%%%%.bc", InputFD, InputFilename); if (EC) { - errs() << getToolName() << ": Error making unique filename: " - << EC.message() << "\n"; + errs() << getToolName() + << ": Error making unique filename: " << EC.message() << "\n"; return 1; } @@ -193,7 +194,7 @@ bool BugDriver::runPasses(Module *Program, InFile.keep(); // setup the child process' arguments - SmallVector<const char*, 8> Args; + SmallVector<const char *, 8> Args; if (UseValgrind) { Args.push_back("valgrind"); Args.push_back("--error-exitcode=1"); @@ -208,14 +209,16 @@ bool BugDriver::runPasses(Module *Program, Args.push_back(OptArgs[i].c_str()); std::vector<std::string> pass_args; for (unsigned i = 0, e = PluginLoader::getNumPlugins(); i != e; ++i) { - pass_args.push_back( std::string("-load")); - pass_args.push_back( PluginLoader::getPlugin(i)); + pass_args.push_back(std::string("-load")); + pass_args.push_back(PluginLoader::getPlugin(i)); } for (std::vector<std::string>::const_iterator I = Passes.begin(), - E = Passes.end(); I != E; ++I ) - pass_args.push_back( std::string("-") + (*I) ); + E = Passes.end(); + I != E; ++I) + pass_args.push_back(std::string("-") + (*I)); for (std::vector<std::string>::const_iterator I = pass_args.begin(), - E = pass_args.end(); I != E; ++I ) + E = pass_args.end(); + I != E; ++I) Args.push_back(I->c_str()); Args.push_back(InputFilename.c_str()); for (unsigned i = 0; i < NumExtraArgs; ++i) @@ -223,10 +226,9 @@ bool BugDriver::runPasses(Module *Program, Args.push_back(nullptr); DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i = 0, e = Args.size()-1; i != e; ++i) - errs() << " " << Args[i]; - errs() << "\n"; - ); + for (unsigned i = 0, e = Args.size() - 1; i != e; ++i) errs() + << " " << Args[i]; + errs() << "\n";); // Redirect stdout and stderr to nowhere if SilencePasses is given StringRef Nowhere; @@ -264,21 +266,19 @@ bool BugDriver::runPasses(Module *Program, return result != 0; } - std::unique_ptr<Module> BugDriver::runPassesOn(Module *M, const std::vector<std::string> &Passes, - unsigned NumExtraArgs, - const char *const *ExtraArgs) { + unsigned NumExtraArgs, const char *const *ExtraArgs) { std::string BitcodeResult; - if (runPasses(M, Passes, BitcodeResult, false/*delete*/, true/*quiet*/, + if (runPasses(M, Passes, BitcodeResult, false /*delete*/, true /*quiet*/, NumExtraArgs, ExtraArgs)) { return nullptr; } std::unique_ptr<Module> Ret = parseInputFile(BitcodeResult, Context); if (!Ret) { - errs() << getToolName() << ": Error reading bitcode file '" - << BitcodeResult << "'!\n"; + errs() << getToolName() << ": Error reading bitcode file '" << BitcodeResult + << "'!\n"; exit(1); } sys::fs::remove(BitcodeResult); diff --git a/llvm/tools/bugpoint/ToolRunner.cpp b/llvm/tools/bugpoint/ToolRunner.cpp index 4af4b10c4d7..98bc4d846b6 100644 --- a/llvm/tools/bugpoint/ToolRunner.cpp +++ b/llvm/tools/bugpoint/ToolRunner.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "ToolRunner.h" -#include "llvm/Config/config.h" // for HAVE_LINK_R +#include "llvm/Config/config.h" // for HAVE_LINK_R #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FileSystem.h" @@ -27,46 +27,40 @@ using namespace llvm; #define DEBUG_TYPE "toolrunner" namespace llvm { - cl::opt<bool> - SaveTemps("save-temps", cl::init(false), cl::desc("Save temporary files")); +cl::opt<bool> SaveTemps("save-temps", cl::init(false), + cl::desc("Save temporary files")); } namespace { - cl::opt<std::string> - RemoteClient("remote-client", - cl::desc("Remote execution client (rsh/ssh)")); +cl::opt<std::string> + RemoteClient("remote-client", + cl::desc("Remote execution client (rsh/ssh)")); - cl::opt<std::string> - RemoteHost("remote-host", - cl::desc("Remote execution (rsh/ssh) host")); +cl::opt<std::string> RemoteHost("remote-host", + cl::desc("Remote execution (rsh/ssh) host")); - cl::opt<std::string> - RemotePort("remote-port", - cl::desc("Remote execution (rsh/ssh) port")); +cl::opt<std::string> RemotePort("remote-port", + cl::desc("Remote execution (rsh/ssh) port")); - cl::opt<std::string> - RemoteUser("remote-user", - cl::desc("Remote execution (rsh/ssh) user id")); +cl::opt<std::string> RemoteUser("remote-user", + cl::desc("Remote execution (rsh/ssh) user id")); - cl::opt<std::string> - RemoteExtra("remote-extra-options", - cl::desc("Remote execution (rsh/ssh) extra options")); +cl::opt<std::string> + RemoteExtra("remote-extra-options", + cl::desc("Remote execution (rsh/ssh) extra options")); } /// RunProgramWithTimeout - This function provides an alternate interface /// to the sys::Program::ExecuteAndWait interface. /// @see sys::Program::ExecuteAndWait -static int RunProgramWithTimeout(StringRef ProgramPath, - const char **Args, - StringRef StdInFile, - StringRef StdOutFile, - StringRef StdErrFile, - unsigned NumSeconds = 0, +static int RunProgramWithTimeout(StringRef ProgramPath, const char **Args, + StringRef StdInFile, StringRef StdOutFile, + StringRef StdErrFile, unsigned NumSeconds = 0, unsigned MemoryLimit = 0, std::string *ErrMsg = nullptr) { - const StringRef *Redirects[3] = { &StdInFile, &StdOutFile, &StdErrFile }; - return sys::ExecuteAndWait(ProgramPath, Args, nullptr, Redirects, - NumSeconds, MemoryLimit, ErrMsg); + const StringRef *Redirects[3] = {&StdInFile, &StdOutFile, &StdErrFile}; + return sys::ExecuteAndWait(ProgramPath, Args, nullptr, Redirects, NumSeconds, + MemoryLimit, ErrMsg); } /// RunProgramRemotelyWithTimeout - This function runs the given program @@ -76,13 +70,12 @@ static int RunProgramWithTimeout(StringRef ProgramPath, /// code otherwise. /// @see sys::Program::ExecuteAndWait static int RunProgramRemotelyWithTimeout(StringRef RemoteClientPath, - const char **Args, - StringRef StdInFile, + const char **Args, StringRef StdInFile, StringRef StdOutFile, StringRef StdErrFile, unsigned NumSeconds = 0, unsigned MemoryLimit = 0) { - const StringRef *Redirects[3] = { &StdInFile, &StdOutFile, &StdErrFile }; + const StringRef *Redirects[3] = {&StdInFile, &StdOutFile, &StdErrFile}; // Run the program remotely with the remote client int ReturnCode = sys::ExecuteAndWait(RemoteClientPath, Args, nullptr, @@ -112,7 +105,7 @@ static int RunProgramRemotelyWithTimeout(StringRef RemoteClientPath, return ReturnCode; } -static std::string ProcessFailure(StringRef ProgPath, const char** Args, +static std::string ProcessFailure(StringRef ProgPath, const char **Args, unsigned Timeout = 0, unsigned MemoryLimit = 0) { std::ostringstream OS; @@ -151,44 +144,41 @@ static std::string ProcessFailure(StringRef ProgPath, const char** Args, // LLI Implementation of AbstractIntepreter interface // namespace { - class LLI : public AbstractInterpreter { - std::string LLIPath; // The path to the LLI executable - std::vector<std::string> ToolArgs; // Args to pass to LLI - public: - LLI(const std::string &Path, const std::vector<std::string> *Args) +class LLI : public AbstractInterpreter { + std::string LLIPath; // The path to the LLI executable + std::vector<std::string> ToolArgs; // Args to pass to LLI +public: + LLI(const std::string &Path, const std::vector<std::string> *Args) : LLIPath(Path) { - ToolArgs.clear (); - if (Args) { ToolArgs = *Args; } + ToolArgs.clear(); + if (Args) { + ToolArgs = *Args; } + } - int 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> &CCArgs, - const std::vector<std::string> &SharedLibs = - std::vector<std::string>(), - unsigned Timeout = 0, - unsigned MemoryLimit = 0) override; - }; + int 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> &CCArgs, + const std::vector<std::string> &SharedLibs = std::vector<std::string>(), + unsigned Timeout = 0, unsigned MemoryLimit = 0) override; +}; } int LLI::ExecuteProgram(const std::string &Bitcode, const std::vector<std::string> &Args, const std::string &InputFile, - const std::string &OutputFile, - std::string *Error, + const std::string &OutputFile, std::string *Error, const std::vector<std::string> &CCArgs, const std::vector<std::string> &SharedLibs, - unsigned Timeout, - unsigned MemoryLimit) { - std::vector<const char*> LLIArgs; + unsigned Timeout, unsigned MemoryLimit) { + std::vector<const char *> LLIArgs; LLIArgs.push_back(LLIPath.c_str()); LLIArgs.push_back("-force-interpreter=true"); for (std::vector<std::string>::const_iterator i = SharedLibs.begin(), - e = SharedLibs.end(); i != e; ++i) { + e = SharedLibs.end(); + i != e; ++i) { LLIArgs.push_back("-load"); LLIArgs.push_back((*i).c_str()); } @@ -199,26 +189,25 @@ int LLI::ExecuteProgram(const std::string &Bitcode, LLIArgs.push_back(Bitcode.c_str()); // Add optional parameters to the running program from Argv - for (unsigned i=0, e = Args.size(); i != e; ++i) + for (unsigned i = 0, e = Args.size(); i != e; ++i) LLIArgs.push_back(Args[i].c_str()); LLIArgs.push_back(nullptr); - outs() << "<lli>"; outs().flush(); + outs() << "<lli>"; + outs().flush(); DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i=0, e = LLIArgs.size()-1; i != e; ++i) - errs() << " " << LLIArgs[i]; - errs() << "\n"; - ); - return RunProgramWithTimeout(LLIPath, &LLIArgs[0], - InputFile, OutputFile, OutputFile, - Timeout, MemoryLimit, Error); + for (unsigned i = 0, e = LLIArgs.size() - 1; i != e; ++i) errs() + << " " << LLIArgs[i]; + errs() << "\n";); + return RunProgramWithTimeout(LLIPath, &LLIArgs[0], InputFile, OutputFile, + OutputFile, Timeout, MemoryLimit, Error); } -void AbstractInterpreter::anchor() { } +void AbstractInterpreter::anchor() {} #if defined(LLVM_ON_UNIX) const char EXESuffix[] = ""; -#elif defined (LLVM_ON_WIN32) +#elif defined(LLVM_ON_WIN32) const char EXESuffix[] = "exe"; #endif @@ -248,11 +237,11 @@ static std::string PrependMainExecutablePath(const std::string &ExeName, } // LLI create method - Try to find the LLI executable -AbstractInterpreter *AbstractInterpreter::createLLI(const char *Argv0, - std::string &Message, - const std::vector<std::string> *ToolArgs) { +AbstractInterpreter * +AbstractInterpreter::createLLI(const char *Argv0, std::string &Message, + const std::vector<std::string> *ToolArgs) { std::string LLIPath = - PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t) & createLLI); + PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createLLI); if (!LLIPath.empty()) { Message = "Found lli: " + LLIPath + "\n"; return new LLI(LLIPath, ToolArgs); @@ -269,42 +258,36 @@ AbstractInterpreter *AbstractInterpreter::createLLI(const char *Argv0, // example, to compile a bitcode fragment without linking or executing, then // using a custom wrapper script to check for compiler errors. namespace { - class CustomCompiler : public AbstractInterpreter { - std::string CompilerCommand; - std::vector<std::string> CompilerArgs; - public: - CustomCompiler(const std::string &CompilerCmd, - std::vector<std::string> CompArgs) - : CompilerCommand(CompilerCmd), CompilerArgs(std::move(CompArgs)) {} - - void compileProgram(const std::string &Bitcode, - std::string *Error, - unsigned Timeout = 0, - unsigned MemoryLimit = 0) override; - - int 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> &CCArgs = - std::vector<std::string>(), - const std::vector<std::string> &SharedLibs = - std::vector<std::string>(), - unsigned Timeout = 0, - unsigned MemoryLimit = 0) override { - *Error = "Execution not supported with -compile-custom"; - return -1; - } - }; +class CustomCompiler : public AbstractInterpreter { + std::string CompilerCommand; + std::vector<std::string> CompilerArgs; + +public: + CustomCompiler(const std::string &CompilerCmd, + std::vector<std::string> CompArgs) + : CompilerCommand(CompilerCmd), CompilerArgs(std::move(CompArgs)) {} + + void compileProgram(const std::string &Bitcode, std::string *Error, + unsigned Timeout = 0, unsigned MemoryLimit = 0) override; + + int 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> &CCArgs = std::vector<std::string>(), + const std::vector<std::string> &SharedLibs = std::vector<std::string>(), + unsigned Timeout = 0, unsigned MemoryLimit = 0) override { + *Error = "Execution not supported with -compile-custom"; + return -1; + } +}; } void CustomCompiler::compileProgram(const std::string &Bitcode, - std::string *Error, - unsigned Timeout, + std::string *Error, unsigned Timeout, unsigned MemoryLimit) { - std::vector<const char*> ProgramArgs; + std::vector<const char *> ProgramArgs; ProgramArgs.push_back(CompilerCommand.c_str()); for (std::size_t i = 0; i < CompilerArgs.size(); ++i) @@ -316,11 +299,10 @@ void CustomCompiler::compileProgram(const std::string &Bitcode, for (unsigned i = 0, e = CompilerArgs.size(); i != e; ++i) ProgramArgs.push_back(CompilerArgs[i].c_str()); - if (RunProgramWithTimeout(CompilerCommand, &ProgramArgs[0], - "", "", "", - Timeout, MemoryLimit, Error)) - *Error = ProcessFailure(CompilerCommand, &ProgramArgs[0], - Timeout, MemoryLimit); + if (RunProgramWithTimeout(CompilerCommand, &ProgramArgs[0], "", "", "", + Timeout, MemoryLimit, Error)) + *Error = + ProcessFailure(CompilerCommand, &ProgramArgs[0], Timeout, MemoryLimit); } //===---------------------------------------------------------------------===// @@ -330,38 +312,34 @@ void CustomCompiler::compileProgram(const std::string &Bitcode, // for example, to invoke a cross compiler for code generation followed by // a simulator that executes the generated binary. namespace { - class CustomExecutor : public AbstractInterpreter { - std::string ExecutionCommand; - std::vector<std::string> ExecutorArgs; - public: - CustomExecutor(const std::string &ExecutionCmd, - std::vector<std::string> ExecArgs) - : ExecutionCommand(ExecutionCmd), ExecutorArgs(std::move(ExecArgs)) {} - - int 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> &CCArgs, - const std::vector<std::string> &SharedLibs = - std::vector<std::string>(), - unsigned Timeout = 0, - unsigned MemoryLimit = 0) override; - }; +class CustomExecutor : public AbstractInterpreter { + std::string ExecutionCommand; + std::vector<std::string> ExecutorArgs; + +public: + CustomExecutor(const std::string &ExecutionCmd, + std::vector<std::string> ExecArgs) + : ExecutionCommand(ExecutionCmd), ExecutorArgs(std::move(ExecArgs)) {} + + int 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> &CCArgs, + const std::vector<std::string> &SharedLibs = std::vector<std::string>(), + unsigned Timeout = 0, unsigned MemoryLimit = 0) override; +}; } int CustomExecutor::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> &CCArgs, - const std::vector<std::string> &SharedLibs, - unsigned Timeout, - unsigned MemoryLimit) { - - std::vector<const char*> ProgramArgs; + const std::vector<std::string> &Args, + const std::string &InputFile, + const std::string &OutputFile, + std::string *Error, + const std::vector<std::string> &CCArgs, + const std::vector<std::string> &SharedLibs, + unsigned Timeout, unsigned MemoryLimit) { + + std::vector<const char *> ProgramArgs; ProgramArgs.push_back(ExecutionCommand.c_str()); for (std::size_t i = 0; i < ExecutorArgs.size(); ++i) @@ -373,10 +351,9 @@ int CustomExecutor::ExecuteProgram(const std::string &Bitcode, for (unsigned i = 0, e = Args.size(); i != e; ++i) ProgramArgs.push_back(Args[i].c_str()); - return RunProgramWithTimeout( - ExecutionCommand, - &ProgramArgs[0], InputFile, OutputFile, - OutputFile, Timeout, MemoryLimit, Error); + return RunProgramWithTimeout(ExecutionCommand, &ProgramArgs[0], InputFile, + OutputFile, OutputFile, Timeout, MemoryLimit, + Error); } // Tokenize the CommandLine to the command and the args to allow @@ -400,9 +377,9 @@ static void lexCommand(std::string &Message, const std::string &CommandLine, while (std::string::npos != pos || std::string::npos != lastPos) { std::string token = CommandLine.substr(lastPos, pos - lastPos); if (Command == "") - Command = token; + Command = token; else - Args.push_back(token); + Args.push_back(token); // Skip delimiters. Note the "not_of" lastPos = CommandLine.find_first_not_of(delimiters, pos); // Find next "non-delimiter" @@ -411,9 +388,8 @@ static void lexCommand(std::string &Message, const std::string &CommandLine, auto Path = sys::findProgramByName(Command); if (!Path) { - Message = - std::string("Cannot find '") + Command + - "' in PATH: " + Path.getError().message() + "\n"; + Message = std::string("Cannot find '") + Command + "' in PATH: " + + Path.getError().message() + "\n"; return; } CmdPath = *Path; @@ -424,8 +400,7 @@ static void lexCommand(std::string &Message, const std::string &CommandLine, // Custom execution environment create method, takes the execution command // as arguments AbstractInterpreter *AbstractInterpreter::createCustomCompiler( - std::string &Message, - const std::string &CompileCommandLine) { + std::string &Message, const std::string &CompileCommandLine) { std::string CmdPath; std::vector<std::string> Args; @@ -438,10 +413,9 @@ AbstractInterpreter *AbstractInterpreter::createCustomCompiler( // Custom execution environment create method, takes the execution command // as arguments -AbstractInterpreter *AbstractInterpreter::createCustomExecutor( - std::string &Message, - const std::string &ExecCommandLine) { - +AbstractInterpreter * +AbstractInterpreter::createCustomExecutor(std::string &Message, + const std::string &ExecCommandLine) { std::string CmdPath; std::vector<std::string> Args; @@ -456,8 +430,8 @@ AbstractInterpreter *AbstractInterpreter::createCustomExecutor( // LLC Implementation of AbstractIntepreter interface // CC::FileType LLC::OutputCode(const std::string &Bitcode, - std::string &OutputAsmFile, std::string &Error, - unsigned Timeout, unsigned MemoryLimit) { + std::string &OutputAsmFile, std::string &Error, + unsigned Timeout, unsigned MemoryLimit) { const char *Suffix = (UseIntegratedAssembler ? ".llc.o" : ".llc.s"); SmallString<128> UniqueFile; @@ -477,25 +451,22 @@ CC::FileType LLC::OutputCode(const std::string &Bitcode, LLCArgs.push_back("-o"); LLCArgs.push_back(OutputAsmFile.c_str()); // Output to the Asm file - LLCArgs.push_back(Bitcode.c_str()); // This is the input bitcode + LLCArgs.push_back(Bitcode.c_str()); // This is the input bitcode if (UseIntegratedAssembler) LLCArgs.push_back("-filetype=obj"); - LLCArgs.push_back (nullptr); + LLCArgs.push_back(nullptr); outs() << (UseIntegratedAssembler ? "<llc-ia>" : "<llc>"); 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], - "", "", "", - Timeout, MemoryLimit)) - Error = ProcessFailure(LLCPath, &LLCArgs[0], - Timeout, MemoryLimit); + for (unsigned i = 0, e = LLCArgs.size() - 1; i != e; ++i) errs() + << " " << LLCArgs[i]; + errs() << "\n";); + if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], "", "", "", Timeout, + MemoryLimit)) + Error = ProcessFailure(LLCPath, &LLCArgs[0], Timeout, MemoryLimit); return UseIntegratedAssembler ? CC::ObjectFile : CC::AsmFile; } @@ -509,37 +480,33 @@ void LLC::compileProgram(const std::string &Bitcode, std::string *Error, int LLC::ExecuteProgram(const std::string &Bitcode, const std::vector<std::string> &Args, const std::string &InputFile, - const std::string &OutputFile, - std::string *Error, + const std::string &OutputFile, std::string *Error, const std::vector<std::string> &ArgsForCC, const std::vector<std::string> &SharedLibs, - unsigned Timeout, - unsigned MemoryLimit) { + unsigned Timeout, unsigned MemoryLimit) { std::string OutputAsmFile; - CC::FileType FileKind = OutputCode(Bitcode, OutputAsmFile, *Error, Timeout, - MemoryLimit); + CC::FileType FileKind = + OutputCode(Bitcode, OutputAsmFile, *Error, Timeout, MemoryLimit); FileRemover OutFileRemover(OutputAsmFile, !SaveTemps); std::vector<std::string> CCArgs(ArgsForCC); CCArgs.insert(CCArgs.end(), SharedLibs.begin(), SharedLibs.end()); // Assuming LLC worked, compile the result with CC and run it. - return cc->ExecuteProgram(OutputAsmFile, Args, FileKind, - InputFile, OutputFile, Error, CCArgs, - Timeout, MemoryLimit); + return cc->ExecuteProgram(OutputAsmFile, Args, FileKind, InputFile, + OutputFile, Error, CCArgs, Timeout, MemoryLimit); } /// createLLC - Try to find the LLC executable /// -LLC *AbstractInterpreter::createLLC(const char *Argv0, - std::string &Message, +LLC *AbstractInterpreter::createLLC(const char *Argv0, std::string &Message, const std::string &CCBinary, const std::vector<std::string> *Args, const std::vector<std::string> *CCArgs, bool UseIntegratedAssembler) { std::string LLCPath = - PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t) & createLLC); + PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createLLC); if (LLCPath.empty()) { Message = "Cannot find `llc' in executable directory!\n"; return nullptr; @@ -558,41 +525,37 @@ LLC *AbstractInterpreter::createLLC(const char *Argv0, // JIT Implementation of AbstractIntepreter interface // namespace { - class JIT : public AbstractInterpreter { - std::string LLIPath; // The path to the LLI executable - std::vector<std::string> ToolArgs; // Args to pass to LLI - public: - JIT(const std::string &Path, const std::vector<std::string> *Args) +class JIT : public AbstractInterpreter { + std::string LLIPath; // The path to the LLI executable + std::vector<std::string> ToolArgs; // Args to pass to LLI +public: + JIT(const std::string &Path, const std::vector<std::string> *Args) : LLIPath(Path) { - ToolArgs.clear (); - if (Args) { ToolArgs = *Args; } + ToolArgs.clear(); + if (Args) { + ToolArgs = *Args; } + } - int 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> &CCArgs = - std::vector<std::string>(), - const std::vector<std::string> &SharedLibs = - std::vector<std::string>(), - unsigned Timeout = 0, - unsigned MemoryLimit = 0) override; - }; + int 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> &CCArgs = std::vector<std::string>(), + const std::vector<std::string> &SharedLibs = std::vector<std::string>(), + unsigned Timeout = 0, unsigned MemoryLimit = 0) override; +}; } int JIT::ExecuteProgram(const std::string &Bitcode, const std::vector<std::string> &Args, const std::string &InputFile, - const std::string &OutputFile, - std::string *Error, + const std::string &OutputFile, std::string *Error, const std::vector<std::string> &CCArgs, const std::vector<std::string> &SharedLibs, - unsigned Timeout, - unsigned MemoryLimit) { + unsigned Timeout, unsigned MemoryLimit) { // Construct a vector of parameters, incorporating those from the command-line - std::vector<const char*> JITArgs; + std::vector<const char *> JITArgs; JITArgs.push_back(LLIPath.c_str()); JITArgs.push_back("-force-interpreter=false"); @@ -606,28 +569,28 @@ int JIT::ExecuteProgram(const std::string &Bitcode, } JITArgs.push_back(Bitcode.c_str()); // Add optional parameters to the running program from Argv - for (unsigned i=0, e = Args.size(); i != e; ++i) + for (unsigned i = 0, e = Args.size(); i != e; ++i) JITArgs.push_back(Args[i].c_str()); JITArgs.push_back(nullptr); - outs() << "<jit>"; outs().flush(); + outs() << "<jit>"; + outs().flush(); DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i=0, e = JITArgs.size()-1; i != e; ++i) - errs() << " " << JITArgs[i]; - errs() << "\n"; - ); + for (unsigned i = 0, e = JITArgs.size() - 1; i != e; ++i) errs() + << " " << JITArgs[i]; + errs() << "\n";); DEBUG(errs() << "\nSending output to " << OutputFile << "\n"); - return RunProgramWithTimeout(LLIPath, &JITArgs[0], - InputFile, OutputFile, OutputFile, - Timeout, MemoryLimit, Error); + return RunProgramWithTimeout(LLIPath, &JITArgs[0], InputFile, OutputFile, + OutputFile, Timeout, MemoryLimit, Error); } /// createJIT - Try to find the LLI executable /// -AbstractInterpreter *AbstractInterpreter::createJIT(const char *Argv0, - std::string &Message, const std::vector<std::string> *Args) { +AbstractInterpreter * +AbstractInterpreter::createJIT(const char *Argv0, std::string &Message, + const std::vector<std::string> *Args) { std::string LLIPath = - PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t) & createJIT); + PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createJIT); if (!LLIPath.empty()) { Message = "Found lli: " + LLIPath + "\n"; return new JIT(LLIPath, Args); @@ -641,9 +604,10 @@ AbstractInterpreter *AbstractInterpreter::createJIT(const char *Argv0, // CC abstraction // -static bool IsARMArchitecture(std::vector<const char*> Args) { - for (std::vector<const char*>::const_iterator - I = Args.begin(), E = Args.end(); I != E; ++I) { +static bool IsARMArchitecture(std::vector<const char *> Args) { + for (std::vector<const char *>::const_iterator I = Args.begin(), + E = Args.end(); + I != E; ++I) { if (StringRef(*I).equals_lower("-arch")) { ++I; if (I != E && StringRef(*I).startswith_lower("arm")) @@ -655,23 +619,21 @@ static bool IsARMArchitecture(std::vector<const char*> Args) { } int CC::ExecuteProgram(const std::string &ProgramFile, - const std::vector<std::string> &Args, - FileType fileType, - const std::string &InputFile, - const std::string &OutputFile, - std::string *Error, - const std::vector<std::string> &ArgsForCC, - unsigned Timeout, - unsigned MemoryLimit) { - std::vector<const char*> CCArgs; + const std::vector<std::string> &Args, FileType fileType, + const std::string &InputFile, + const std::string &OutputFile, std::string *Error, + const std::vector<std::string> &ArgsForCC, + unsigned Timeout, unsigned MemoryLimit) { + std::vector<const char *> CCArgs; CCArgs.push_back(CCPath.c_str()); if (TargetTriple.getArch() == Triple::x86) CCArgs.push_back("-m32"); - for (std::vector<std::string>::const_iterator - I = ccArgs.begin(), E = ccArgs.end(); I != E; ++I) + for (std::vector<std::string>::const_iterator I = ccArgs.begin(), + E = ccArgs.end(); + I != E; ++I) CCArgs.push_back(I->c_str()); // Specify -x explicitly in case the extension is wonky @@ -691,7 +653,7 @@ int CC::ExecuteProgram(const std::string &ProgramFile, } } - CCArgs.push_back(ProgramFile.c_str()); // Specify the input filename. + CCArgs.push_back(ProgramFile.c_str()); // Specify the input filename. CCArgs.push_back("-x"); CCArgs.push_back("none"); @@ -713,27 +675,27 @@ int CC::ExecuteProgram(const std::string &ProgramFile, for (unsigned i = 0, e = ArgsForCC.size(); i != e; ++i) CCArgs.push_back(ArgsForCC[i].c_str()); - CCArgs.push_back("-lm"); // Hard-code the math library... - CCArgs.push_back("-O2"); // Optimize the program a bit... -#if defined (HAVE_LINK_R) - CCArgs.push_back("-Wl,-R."); // Search this dir for .so files + CCArgs.push_back("-lm"); // Hard-code the math library... + CCArgs.push_back("-O2"); // Optimize the program a bit... +#if defined(HAVE_LINK_R) + CCArgs.push_back("-Wl,-R."); // Search this dir for .so files #endif if (TargetTriple.getArch() == Triple::sparc) CCArgs.push_back("-mcpu=v9"); - CCArgs.push_back(nullptr); // NULL terminator + CCArgs.push_back(nullptr); // NULL terminator - outs() << "<CC>"; outs().flush(); + outs() << "<CC>"; + outs().flush(); DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i = 0, e = CCArgs.size()-1; i != e; ++i) - errs() << " " << CCArgs[i]; - errs() << "\n"; - ); + for (unsigned i = 0, e = CCArgs.size() - 1; i != e; ++i) errs() + << " " << CCArgs[i]; + errs() << "\n";); if (RunProgramWithTimeout(CCPath, &CCArgs[0], "", "", "")) { *Error = ProcessFailure(CCPath, &CCArgs[0]); return -1; } - std::vector<const char*> ProgramArgs; + std::vector<const char *> ProgramArgs; // Declared here so that the destructor only runs after // ProgramArgs is used. @@ -758,7 +720,7 @@ int CC::ExecuteProgram(const std::string &ProgramFile, // Full path to the binary. We need to cd to the exec directory because // there is a dylib there that the exec expects to find in the CWD - char* env_pwd = getenv("PWD"); + char *env_pwd = getenv("PWD"); Exec = "cd "; Exec += env_pwd; Exec += "; ./"; @@ -769,15 +731,15 @@ int CC::ExecuteProgram(const std::string &ProgramFile, // Add optional parameters to the running program from Argv for (unsigned i = 0, e = Args.size(); i != e; ++i) ProgramArgs.push_back(Args[i].c_str()); - ProgramArgs.push_back(nullptr); // NULL terminator + ProgramArgs.push_back(nullptr); // NULL terminator // Now that we have a binary, run it! - outs() << "<program>"; outs().flush(); + outs() << "<program>"; + outs().flush(); DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i = 0, e = ProgramArgs.size()-1; i != e; ++i) - errs() << " " << ProgramArgs[i]; - errs() << "\n"; - ); + for (unsigned i = 0, e = ProgramArgs.size() - 1; i != e; ++i) errs() + << " " << ProgramArgs[i]; + errs() << "\n";); FileRemover OutputBinaryRemover(OutputBinary.str(), !SaveTemps); @@ -796,17 +758,18 @@ int CC::ExecuteProgram(const std::string &ProgramFile, } return ExitCode; } else { - outs() << "<run remotely>"; outs().flush(); - return RunProgramRemotelyWithTimeout(RemoteClientPath, - &ProgramArgs[0], InputFile, OutputFile, - OutputFile, Timeout, MemoryLimit); + outs() << "<run remotely>"; + outs().flush(); + return RunProgramRemotelyWithTimeout(RemoteClientPath, &ProgramArgs[0], + InputFile, OutputFile, OutputFile, + Timeout, MemoryLimit); } } int CC::MakeSharedObject(const std::string &InputFile, FileType fileType, - std::string &OutputFile, - const std::vector<std::string> &ArgsForCC, - std::string &Error) { + std::string &OutputFile, + const std::vector<std::string> &ArgsForCC, + std::string &Error) { SmallString<128> UniqueFilename; std::error_code EC = sys::fs::createUniqueFile( InputFile + "-%%%%%%%" + LTDL_SHLIB_EXT, UniqueFilename); @@ -816,15 +779,16 @@ int CC::MakeSharedObject(const std::string &InputFile, FileType fileType, } OutputFile = UniqueFilename.str(); - std::vector<const char*> CCArgs; + std::vector<const char *> CCArgs; CCArgs.push_back(CCPath.c_str()); if (TargetTriple.getArch() == Triple::x86) CCArgs.push_back("-m32"); - for (std::vector<std::string>::const_iterator - I = ccArgs.begin(), E = ccArgs.end(); I != E; ++I) + for (std::vector<std::string>::const_iterator I = ccArgs.begin(), + E = ccArgs.end(); + I != E; ++I) CCArgs.push_back(I->c_str()); // Compile the C/asm file into a shared object @@ -833,25 +797,25 @@ int CC::MakeSharedObject(const std::string &InputFile, FileType fileType, CCArgs.push_back(fileType == AsmFile ? "assembler" : "c"); } CCArgs.push_back("-fno-strict-aliasing"); - CCArgs.push_back(InputFile.c_str()); // Specify the input filename. + CCArgs.push_back(InputFile.c_str()); // Specify the input filename. CCArgs.push_back("-x"); CCArgs.push_back("none"); if (TargetTriple.getArch() == Triple::sparc) - CCArgs.push_back("-G"); // Compile a shared library, `-G' for Sparc + CCArgs.push_back("-G"); // Compile a shared library, `-G' for Sparc else if (TargetTriple.isOSDarwin()) { // link all source files into a single module in data segment, rather than // generating blocks. dynamic_lookup requires that you set // MACOSX_DEPLOYMENT_TARGET=10.3 in your env. FIXME: it would be better for // bugpoint to just pass that in the environment of CC. CCArgs.push_back("-single_module"); - CCArgs.push_back("-dynamiclib"); // `-dynamiclib' for MacOS X/PowerPC + CCArgs.push_back("-dynamiclib"); // `-dynamiclib' for MacOS X/PowerPC CCArgs.push_back("-undefined"); CCArgs.push_back("dynamic_lookup"); } else - CCArgs.push_back("-shared"); // `-shared' for Linux/X86, maybe others + CCArgs.push_back("-shared"); // `-shared' for Linux/X86, maybe others if (TargetTriple.getArch() == Triple::x86_64) - CCArgs.push_back("-fPIC"); // Requires shared objs to contain PIC + CCArgs.push_back("-fPIC"); // Requires shared objs to contain PIC if (TargetTriple.getArch() == Triple::sparc) CCArgs.push_back("-mcpu=v9"); @@ -860,24 +824,20 @@ int CC::MakeSharedObject(const std::string &InputFile, FileType fileType, CCArgs.push_back(OutputFile.c_str()); // Output to the right filename. CCArgs.push_back("-O2"); // Optimize the program a bit. - - // Add any arguments intended for CC. We locate them here because this is // most likely -L and -l options that need to come before other libraries but // after the source. Other options won't be sensitive to placement on the // command line, so this should be safe. for (unsigned i = 0, e = ArgsForCC.size(); i != e; ++i) CCArgs.push_back(ArgsForCC[i].c_str()); - CCArgs.push_back(nullptr); // NULL terminator + CCArgs.push_back(nullptr); // NULL terminator - - - outs() << "<CC>"; outs().flush(); + outs() << "<CC>"; + outs().flush(); DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i = 0, e = CCArgs.size()-1; i != e; ++i) - errs() << " " << CCArgs[i]; - errs() << "\n"; - ); + for (unsigned i = 0, e = CCArgs.size() - 1; i != e; ++i) errs() + << " " << CCArgs[i]; + errs() << "\n";); if (RunProgramWithTimeout(CCPath, &CCArgs[0], "", "", "")) { Error = ProcessFailure(CCPath, &CCArgs[0]); return 1; @@ -887,9 +847,8 @@ int CC::MakeSharedObject(const std::string &InputFile, FileType fileType, /// create - Try to find the CC executable /// -CC *CC::create(std::string &Message, - const std::string &CCBinary, - const std::vector<std::string> *Args) { +CC *CC::create(std::string &Message, const std::string &CCBinary, + const std::vector<std::string> *Args) { auto CCPath = sys::findProgramByName(CCBinary); if (!CCPath) { Message = "Cannot find `" + CCBinary + "' in PATH: " + diff --git a/llvm/tools/bugpoint/ToolRunner.h b/llvm/tools/bugpoint/ToolRunner.h index 3accd70ed4c..3e5d83d2e1c 100644 --- a/llvm/tools/bugpoint/ToolRunner.h +++ b/llvm/tools/bugpoint/ToolRunner.h @@ -36,20 +36,21 @@ class LLC; // CC abstraction // class CC { - std::string CCPath; // The path to the cc executable. - std::string RemoteClientPath; // The path to the rsh / ssh executable. + std::string CCPath; // The path to the cc executable. + std::string RemoteClientPath; // The path to the rsh / ssh executable. std::vector<std::string> ccArgs; // CC-specific arguments. CC(StringRef ccPath, StringRef RemotePath, - const std::vector<std::string> *CCArgs) - : CCPath(ccPath), RemoteClientPath(RemotePath) { - if (CCArgs) ccArgs = *CCArgs; + const std::vector<std::string> *CCArgs) + : CCPath(ccPath), RemoteClientPath(RemotePath) { + if (CCArgs) + ccArgs = *CCArgs; } + public: enum FileType { AsmFile, ObjectFile, CFile }; - static CC *create(std::string &Message, - const std::string &CCBinary, - const std::vector<std::string> *Args); + static CC *create(std::string &Message, const std::string &CCBinary, + const std::vector<std::string> *Args); /// ExecuteProgram - Execute the program specified by "ProgramFile" (which is /// either a .s file, or a .c file, specified by FileType), with the specified @@ -58,16 +59,12 @@ public: /// option specifies optional native shared objects that can be loaded into /// the program for execution. /// - int ExecuteProgram(const std::string &ProgramFile, - const std::vector<std::string> &Args, - FileType fileType, - const std::string &InputFile, - const std::string &OutputFile, - std::string *Error = nullptr, - const std::vector<std::string> &CCArgs = - std::vector<std::string>(), - unsigned Timeout = 0, - unsigned MemoryLimit = 0); + int ExecuteProgram( + const std::string &ProgramFile, const std::vector<std::string> &Args, + FileType fileType, const std::string &InputFile, + const std::string &OutputFile, std::string *Error = nullptr, + const std::vector<std::string> &CCArgs = std::vector<std::string>(), + unsigned Timeout = 0, unsigned MemoryLimit = 0); /// MakeSharedObject - This compiles the specified file (which is either a .c /// file or a .s file) into a shared object. @@ -78,7 +75,6 @@ public: std::string &Error); }; - //===---------------------------------------------------------------------===// /// AbstractInterpreter Class - Subclasses of this class are used to execute /// LLVM bitcode in a variety of ways. This abstract interface hides this @@ -86,30 +82,30 @@ public: /// class AbstractInterpreter { virtual void anchor(); + public: static LLC *createLLC(const char *Argv0, std::string &Message, - const std::string &CCBinary, + const std::string &CCBinary, const std::vector<std::string> *Args = nullptr, const std::vector<std::string> *CCArgs = nullptr, bool UseIntegratedAssembler = false); - static AbstractInterpreter* + static AbstractInterpreter * createLLI(const char *Argv0, std::string &Message, const std::vector<std::string> *Args = nullptr); - static AbstractInterpreter* + static AbstractInterpreter * createJIT(const char *Argv0, std::string &Message, const std::vector<std::string> *Args = nullptr); - static AbstractInterpreter* + static AbstractInterpreter * createCustomCompiler(std::string &Message, const std::string &CompileCommandLine); - static AbstractInterpreter* + static AbstractInterpreter * createCustomExecutor(std::string &Message, const std::string &ExecCommandLine); - virtual ~AbstractInterpreter() {} /// compileProgram - Compile the specified program from bitcode to executable @@ -123,9 +119,9 @@ public: /// fails, it sets Error, otherwise, this function returns the type of code /// emitted. virtual CC::FileType OutputCode(const std::string &Bitcode, - std::string &OutFile, std::string &Error, - unsigned Timeout = 0, - unsigned MemoryLimit = 0) { + std::string &OutFile, std::string &Error, + unsigned Timeout = 0, + unsigned MemoryLimit = 0) { Error = "OutputCode not supported by this AbstractInterpreter!"; return CC::AsmFile; } @@ -135,17 +131,13 @@ public: /// returns false if a problem was encountered that prevented execution of /// the program. /// - virtual int 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> &CCArgs = - std::vector<std::string>(), - const std::vector<std::string> &SharedLibs = - std::vector<std::string>(), - unsigned Timeout = 0, - unsigned MemoryLimit = 0) = 0; + virtual int 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> &CCArgs = std::vector<std::string>(), + const std::vector<std::string> &SharedLibs = std::vector<std::string>(), + unsigned Timeout = 0, unsigned MemoryLimit = 0) = 0; }; //===---------------------------------------------------------------------===// @@ -156,14 +148,15 @@ class LLC : public AbstractInterpreter { std::vector<std::string> ToolArgs; // Extra args to pass to LLC. CC *cc; bool UseIntegratedAssembler; + public: - LLC(const std::string &llcPath, CC *cc, - const std::vector<std::string> *Args, + LLC(const std::string &llcPath, CC *cc, const std::vector<std::string> *Args, bool useIntegratedAssembler) - : LLCPath(llcPath), cc(cc), - UseIntegratedAssembler(useIntegratedAssembler) { + : LLCPath(llcPath), cc(cc), + UseIntegratedAssembler(useIntegratedAssembler) { ToolArgs.clear(); - if (Args) ToolArgs = *Args; + if (Args) + ToolArgs = *Args; } ~LLC() override { delete cc; } @@ -173,26 +166,21 @@ public: void compileProgram(const std::string &Bitcode, std::string *Error, unsigned Timeout = 0, unsigned MemoryLimit = 0) override; - int 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> &CCArgs = - std::vector<std::string>(), - const std::vector<std::string> &SharedLibs = - std::vector<std::string>(), - unsigned Timeout = 0, - unsigned MemoryLimit = 0) override; + int 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> &CCArgs = std::vector<std::string>(), + const std::vector<std::string> &SharedLibs = std::vector<std::string>(), + unsigned Timeout = 0, unsigned MemoryLimit = 0) override; /// OutputCode - Compile the specified program from bitcode to code /// understood by the CC driver (either C or asm). If the code generator /// fails, it sets Error, otherwise, this function returns the type of code /// emitted. - CC::FileType OutputCode(const std::string &Bitcode, - std::string &OutFile, std::string &Error, - unsigned Timeout = 0, - unsigned MemoryLimit = 0) override; + CC::FileType OutputCode(const std::string &Bitcode, std::string &OutFile, + std::string &Error, unsigned Timeout = 0, + unsigned MemoryLimit = 0) override; }; } // End llvm namespace diff --git a/llvm/tools/bugpoint/bugpoint.cpp b/llvm/tools/bugpoint/bugpoint.cpp index 25c0e4176b2..fa4243fd057 100644 --- a/llvm/tools/bugpoint/bugpoint.cpp +++ b/llvm/tools/bugpoint/bugpoint.cpp @@ -30,84 +30,82 @@ #include "llvm/Transforms/IPO/AlwaysInliner.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" -//Enable this macro to debug bugpoint itself. +// Enable this macro to debug bugpoint itself. //#define DEBUG_BUGPOINT 1 using namespace llvm; static cl::opt<bool> -FindBugs("find-bugs", cl::desc("Run many different optimization sequences " - "on program to find bugs"), cl::init(false)); + FindBugs("find-bugs", cl::desc("Run many different optimization sequences " + "on program to find bugs"), + cl::init(false)); static cl::list<std::string> -InputFilenames(cl::Positional, cl::OneOrMore, - cl::desc("<input llvm ll/bc files>")); + InputFilenames(cl::Positional, cl::OneOrMore, + cl::desc("<input llvm ll/bc files>")); -static cl::opt<unsigned> -TimeoutValue("timeout", cl::init(300), cl::value_desc("seconds"), - cl::desc("Number of seconds program is allowed to run before it " - "is killed (default is 300s), 0 disables timeout")); +static cl::opt<unsigned> TimeoutValue( + "timeout", cl::init(300), cl::value_desc("seconds"), + cl::desc("Number of seconds program is allowed to run before it " + "is killed (default is 300s), 0 disables timeout")); static cl::opt<int> -MemoryLimit("mlimit", cl::init(-1), cl::value_desc("MBytes"), - cl::desc("Maximum amount of memory to use. 0 disables check." - " Defaults to 400MB (800MB under valgrind).")); + MemoryLimit("mlimit", cl::init(-1), cl::value_desc("MBytes"), + cl::desc("Maximum amount of memory to use. 0 disables check." + " Defaults to 400MB (800MB under valgrind).")); static cl::opt<bool> -UseValgrind("enable-valgrind", - cl::desc("Run optimizations through valgrind")); + UseValgrind("enable-valgrind", + cl::desc("Run optimizations through valgrind")); // The AnalysesList is automatically populated with registered Passes by the // PassNameParser. // -static cl::list<const PassInfo*, bool, PassNameParser> -PassList(cl::desc("Passes available:"), cl::ZeroOrMore); +static cl::list<const PassInfo *, bool, PassNameParser> + PassList(cl::desc("Passes available:"), cl::ZeroOrMore); static cl::opt<bool> -StandardLinkOpts("std-link-opts", - cl::desc("Include the standard link time optimizations")); + StandardLinkOpts("std-link-opts", + cl::desc("Include the standard link time optimizations")); static cl::opt<bool> -OptLevelO1("O1", - cl::desc("Optimization level 1. Identical to 'opt -O1'")); + OptLevelO1("O1", cl::desc("Optimization level 1. Identical to 'opt -O1'")); static cl::opt<bool> -OptLevelO2("O2", - cl::desc("Optimization level 2. Identical to 'opt -O2'")); + OptLevelO2("O2", cl::desc("Optimization level 2. Identical to 'opt -O2'")); -static cl::opt<bool> -OptLevelOs("Os", - cl::desc("Like -O2 with extra optimizations for size. Similar to clang -Os")); +static cl::opt<bool> OptLevelOs( + "Os", + cl::desc( + "Like -O2 with extra optimizations for size. Similar to clang -Os")); static cl::opt<bool> -OptLevelO3("O3", - cl::desc("Optimization level 3. Identical to 'opt -O3'")); + OptLevelO3("O3", cl::desc("Optimization level 3. Identical to 'opt -O3'")); static cl::opt<std::string> -OverrideTriple("mtriple", cl::desc("Override target triple for module")); + OverrideTriple("mtriple", cl::desc("Override target triple for module")); /// BugpointIsInterrupted - Set to true when the user presses ctrl-c. bool llvm::BugpointIsInterrupted = false; #ifndef DEBUG_BUGPOINT -static void BugpointInterruptFunction() { - BugpointIsInterrupted = true; -} +static void BugpointInterruptFunction() { BugpointIsInterrupted = true; } #endif // Hack to capture a pass list. namespace { - class AddToDriver : public legacy::FunctionPassManager { - BugDriver &D; - public: - AddToDriver(BugDriver &_D) : FunctionPassManager(nullptr), D(_D) {} - - void add(Pass *P) override { - const void *ID = P->getPassID(); - const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(ID); - D.addPass(PI->getPassArgument()); - } - }; +class AddToDriver : public legacy::FunctionPassManager { + BugDriver &D; + +public: + AddToDriver(BugDriver &_D) : FunctionPassManager(nullptr), D(_D) {} + + void add(Pass *P) override { + const void *ID = P->getPassID(); + const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(ID); + D.addPass(PI->getPassArgument()); + } +}; } #ifdef LINK_POLLY_INTO_TOOLS @@ -120,7 +118,7 @@ int main(int argc, char **argv) { #ifndef DEBUG_BUGPOINT llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); llvm::PrettyStackTraceProgram X(argc, argv); - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. #endif // Initialize passes @@ -165,9 +163,10 @@ int main(int argc, char **argv) { MemoryLimit = 400; } - BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit, - UseValgrind, Context); - if (D.addSources(InputFilenames)) return 1; + BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit, UseValgrind, + Context); + if (D.addSources(InputFilenames)) + return 1; AddToDriver PM(D); @@ -192,8 +191,8 @@ int main(int argc, char **argv) { for (const PassInfo *PI : PassList) D.addPass(PI->getPassArgument()); - // Bugpoint has the ability of generating a plethora of core files, so to - // avoid filling up the disk, we prevent it +// Bugpoint has the ability of generating a plethora of core files, so to +// avoid filling up the disk, we prevent it #ifndef DEBUG_BUGPOINT sys::Process::PreventCoreFiles(); #endif |