summaryrefslogtreecommitdiff
path: root/tools/bugpoint
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-04-16 16:01:22 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-04-16 16:01:22 +0000
commit71d5a2540a98c81f5bcaeb48805e0e2881f530ef (patch)
tree5343938942df402b49ec7300a1c25a2d4ccd5821 /tools/bugpoint
parent31bbf64f3a4974a2d6c8b3b27ad2f519caf74057 (diff)
downloadsrc-test2-71d5a2540a98c81f5bcaeb48805e0e2881f530ef.tar.gz
src-test2-71d5a2540a98c81f5bcaeb48805e0e2881f530ef.zip
Notes
Diffstat (limited to 'tools/bugpoint')
-rw-r--r--tools/bugpoint/CrashDebugger.cpp8
-rw-r--r--tools/bugpoint/ExtractFunction.cpp1
-rw-r--r--tools/bugpoint/FindBugs.cpp6
-rw-r--r--tools/bugpoint/ListReducer.h5
-rw-r--r--tools/bugpoint/Miscompilation.cpp25
-rw-r--r--tools/bugpoint/ToolRunner.cpp67
-rw-r--r--tools/bugpoint/bugpoint.cpp3
7 files changed, 73 insertions, 42 deletions
diff --git a/tools/bugpoint/CrashDebugger.cpp b/tools/bugpoint/CrashDebugger.cpp
index 0cae0669477f..2fd8699c5fc8 100644
--- a/tools/bugpoint/CrashDebugger.cpp
+++ b/tools/bugpoint/CrashDebugger.cpp
@@ -731,7 +731,8 @@ bool ReduceCrashingInstructions::TestInsts(
for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E;) {
Instruction *Inst = &*I++;
if (!Instructions.count(Inst) && !isa<TerminatorInst>(Inst) &&
- !Inst->isEHPad() && !Inst->getType()->isTokenTy()) {
+ !Inst->isEHPad() && !Inst->getType()->isTokenTy() &&
+ !Inst->isSwiftError()) {
if (!Inst->getType()->isVoidTy())
Inst->replaceAllUsesWith(UndefValue::get(Inst->getType()));
Inst->eraseFromParent();
@@ -1015,7 +1016,8 @@ static Error ReduceInsts(BugDriver &BD,
// TODO: Should this be some kind of interrupted error?
return Error::success();
- if (I->isEHPad() || I->getType()->isTokenTy())
+ if (I->isEHPad() || I->getType()->isTokenTy() ||
+ I->isSwiftError())
continue;
outs() << "Checking instruction: " << *I;
@@ -1111,7 +1113,7 @@ static Error DebugACrash(BugDriver &BD,
BD.EmitProgressBitcode(BD.getProgram(), "reduced-blocks");
}
- if (!DisableSimplifyCFG & !BugpointIsInterrupted) {
+ if (!DisableSimplifyCFG && !BugpointIsInterrupted) {
std::vector<const BasicBlock *> Blocks;
for (Function &F : *BD.getProgram())
for (BasicBlock &BB : F)
diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp
index d57613ec5e37..82c61b6e1be7 100644
--- a/tools/bugpoint/ExtractFunction.cpp
+++ b/tools/bugpoint/ExtractFunction.cpp
@@ -209,6 +209,7 @@ static void eliminateAliases(GlobalValue *GV) {
void llvm::DeleteGlobalInitializer(GlobalVariable *GV) {
eliminateAliases(GV);
GV->setInitializer(nullptr);
+ GV->setComdat(nullptr);
}
// DeleteFunctionBody - "Remove" the function by deleting all of its basic
diff --git a/tools/bugpoint/FindBugs.cpp b/tools/bugpoint/FindBugs.cpp
index 156f4d0d78fe..3093169ba8b0 100644
--- a/tools/bugpoint/FindBugs.cpp
+++ b/tools/bugpoint/FindBugs.cpp
@@ -21,6 +21,7 @@
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <ctime>
+#include <random>
using namespace llvm;
Error
@@ -39,14 +40,13 @@ BugDriver::runManyPasses(const std::vector<std::string> &AllPasses) {
return E;
}
- srand(time(nullptr));
-
+ std::mt19937 randomness(std::random_device{}());
unsigned num = 1;
while (1) {
//
// Step 1: Randomize the order of the optimizer passes.
//
- std::random_shuffle(PassesToRun.begin(), PassesToRun.end());
+ std::shuffle(PassesToRun.begin(), PassesToRun.end(), randomness);
//
// Step 2: Run optimizer passes on the program and check for success.
diff --git a/tools/bugpoint/ListReducer.h b/tools/bugpoint/ListReducer.h
index dcfa11d06927..0f9db022d555 100644
--- a/tools/bugpoint/ListReducer.h
+++ b/tools/bugpoint/ListReducer.h
@@ -19,6 +19,7 @@
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstdlib>
+#include <random>
#include <vector>
namespace llvm {
@@ -46,7 +47,7 @@ template <typename ElTy> struct ListReducer {
/// that bugpoint does.
Expected<bool> reduceList(std::vector<ElTy> &TheList) {
std::vector<ElTy> empty;
- std::srand(0x6e5ea738); // Seed the random number generator
+ std::mt19937 randomness(0x6e5ea738); // Seed the random number generator
Expected<TestResult> Result = doTest(TheList, empty);
if (Error E = Result.takeError())
return std::move(E);
@@ -92,7 +93,7 @@ template <typename ElTy> struct ListReducer {
// distribution (improving the speed of convergence).
if (ShufflingEnabled && NumOfIterationsWithoutProgress > MaxIterations) {
std::vector<ElTy> ShuffledList(TheList);
- std::random_shuffle(ShuffledList.begin(), ShuffledList.end());
+ std::shuffle(ShuffledList.begin(), ShuffledList.end(), randomness);
errs() << "\n\n*** Testing shuffled set...\n\n";
// Check that random shuffle doesn't lose the bug
Expected<TestResult> Result = doTest(ShuffledList, empty);
diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp
index 792fab07bf11..80f4cea23481 100644
--- a/tools/bugpoint/Miscompilation.cpp
+++ b/tools/bugpoint/Miscompilation.cpp
@@ -225,19 +225,22 @@ public:
/// output is different. If the DeleteInputs argument is set to true then this
/// function deletes both input modules before it returns.
///
-static Expected<std::unique_ptr<Module>>
-testMergedProgram(const BugDriver &BD, std::unique_ptr<Module> M1,
- std::unique_ptr<Module> M2, bool &Broken) {
- if (Linker::linkModules(*M1, std::move(M2)))
+static Expected<std::unique_ptr<Module>> testMergedProgram(const BugDriver &BD,
+ const Module &M1,
+ const Module &M2,
+ bool &Broken) {
+ // Resulting merge of M1 and M2.
+ auto Merged = CloneModule(&M1);
+ if (Linker::linkModules(*Merged, CloneModule(&M2)))
// TODO: Shouldn't we thread the error up instead of exiting?
exit(1);
// Execute the program.
- Expected<bool> Diff = BD.diffProgram(M1.get(), "", "", false);
+ Expected<bool> Diff = BD.diffProgram(Merged.get(), "", "", false);
if (Error E = Diff.takeError())
return std::move(E);
Broken = *Diff;
- return std::move(M1);
+ return std::move(Merged);
}
/// TestFuncs - split functions in a Module into two groups: those that are
@@ -335,9 +338,8 @@ ExtractLoops(BugDriver &BD,
// extraction.
AbstractInterpreter *AI = BD.switchToSafeInterpreter();
bool Failure;
- Expected<std::unique_ptr<Module>> New =
- testMergedProgram(BD, std::move(ToOptimizeLoopExtracted),
- std::move(ToNotOptimize), Failure);
+ Expected<std::unique_ptr<Module>> New = testMergedProgram(
+ BD, *ToOptimizeLoopExtracted, *ToNotOptimize, Failure);
if (Error E = New.takeError())
return std::move(E);
if (!*New)
@@ -726,8 +728,7 @@ static Expected<bool> TestOptimizer(BugDriver &BD, std::unique_ptr<Module> Test,
outs() << " Checking to see if the merged program executes correctly: ";
bool Broken;
- auto Result =
- testMergedProgram(BD, std::move(Optimized), std::move(Safe), Broken);
+ auto Result = testMergedProgram(BD, *Optimized, *Safe, Broken);
if (Error E = Result.takeError())
return std::move(E);
if (auto New = std::move(*Result)) {
@@ -840,7 +841,7 @@ static void CleanupAndPrepareModules(BugDriver &BD,
// Prototype: void *getPointerToNamedFunction(const char* Name)
Constant *resolverFunc = Safe->getOrInsertFunction(
"getPointerToNamedFunction", Type::getInt8PtrTy(Safe->getContext()),
- Type::getInt8PtrTy(Safe->getContext()), (Type *)nullptr);
+ Type::getInt8PtrTy(Safe->getContext()));
// 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) {
diff --git a/tools/bugpoint/ToolRunner.cpp b/tools/bugpoint/ToolRunner.cpp
index 4633d6437336..10532ef8395b 100644
--- a/tools/bugpoint/ToolRunner.cpp
+++ b/tools/bugpoint/ToolRunner.cpp
@@ -355,37 +355,62 @@ Expected<int> CustomExecutor::ExecuteProgram(
// Tokenize the CommandLine to the command and the args to allow
// defining a full command line as the command instead of just the
// executed program. We cannot just pass the whole string after the command
-// as a single argument because then program sees only a single
+// as a single argument because then the program sees only a single
// command line argument (with spaces in it: "foo bar" instead
// of "foo" and "bar").
//
-// code borrowed from:
-// http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
+// Spaces are used as a delimiter; however repeated, leading, and trailing
+// whitespace are ignored. Simple escaping is allowed via the '\'
+// character, as seen below:
+//
+// Two consecutive '\' evaluate to a single '\'.
+// A space after a '\' evaluates to a space that is not interpreted as a
+// delimiter.
+// Any other instances of the '\' character are removed.
+//
+// Example:
+// '\\' -> '\'
+// '\ ' -> ' '
+// 'exa\mple' -> 'example'
+//
static void lexCommand(std::string &Message, const std::string &CommandLine,
std::string &CmdPath, std::vector<std::string> &Args) {
- std::string Command = "";
- std::string delimiters = " ";
-
- std::string::size_type lastPos = CommandLine.find_first_not_of(delimiters, 0);
- std::string::size_type pos = CommandLine.find_first_of(delimiters, lastPos);
-
- while (std::string::npos != pos || std::string::npos != lastPos) {
- std::string token = CommandLine.substr(lastPos, pos - lastPos);
- if (Command == "")
- Command = token;
- else
- Args.push_back(token);
- // Skip delimiters. Note the "not_of"
- lastPos = CommandLine.find_first_not_of(delimiters, pos);
- // Find next "non-delimiter"
- pos = CommandLine.find_first_of(delimiters, lastPos);
+ std::string Token;
+ std::string Command;
+ bool FoundPath = false;
+
+ // first argument is the PATH.
+ // Skip repeated whitespace, leading whitespace and trailing whitespace.
+ for (std::size_t Pos = 0u; Pos <= CommandLine.size(); ++Pos) {
+ if ('\\' == CommandLine[Pos]) {
+ if (Pos + 1 < CommandLine.size())
+ Token.push_back(CommandLine[++Pos]);
+
+ continue;
+ }
+ if (' ' == CommandLine[Pos] || CommandLine.size() == Pos) {
+ if (Token.empty())
+ continue;
+
+ if (!FoundPath) {
+ Command = Token;
+ FoundPath = true;
+ Token.clear();
+ continue;
+ }
+
+ Args.push_back(Token);
+ Token.clear();
+ continue;
+ }
+ Token.push_back(CommandLine[Pos]);
}
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;
diff --git a/tools/bugpoint/bugpoint.cpp b/tools/bugpoint/bugpoint.cpp
index a5de953b2b75..85c1ddd8277d 100644
--- a/tools/bugpoint/bugpoint.cpp
+++ b/tools/bugpoint/bugpoint.cpp
@@ -181,7 +181,8 @@ int main(int argc, char **argv) {
if (OptLevelO1)
Builder.Inliner = createAlwaysInlinerLegacyPass();
else if (OptLevelOs || OptLevelO2)
- Builder.Inliner = createFunctionInliningPass(2, OptLevelOs ? 1 : 0);
+ Builder.Inliner = createFunctionInliningPass(
+ 2, OptLevelOs ? 1 : 0, false);
else
Builder.Inliner = createFunctionInliningPass(275);
Builder.populateFunctionPassManager(PM);