using namespace llvm;
-extern cl::OptionCategory LLVMReduceOptions;
-static cl::opt<unsigned> PollInterval("process-poll-interval",
- cl::desc("child process wait polling"),
- cl::init(5), cl::Hidden,
- cl::cat(LLVMReduceOptions));
-
TestRunner::TestRunner(StringRef TestName,
const std::vector<std::string> &TestArgs,
std::unique_ptr<ReducerWorkItem> Program,
/// Runs the interestingness test, passes file to be tested as first argument
/// and other specified test arguments after that.
-int TestRunner::run(StringRef Filename, const std::atomic<bool> &Killed) const {
+int TestRunner::run(StringRef Filename) const {
std::vector<StringRef> ProgramArgs;
ProgramArgs.push_back(TestName);
ProgramArgs.push_back(Filename);
std::string ErrMsg;
- bool ExecutionFailed;
- sys::ProcessInfo PI =
- sys::ExecuteNoWait(TestName, ProgramArgs, /*Env=*/std::nullopt,
- Verbose ? DefaultRedirects : NullRedirects,
- /*MemoryLimit=*/0, &ErrMsg, &ExecutionFailed);
- if (ExecutionFailed) {
+ int Result =
+ sys::ExecuteAndWait(TestName, ProgramArgs, /*Env=*/std::nullopt,
+ Verbose ? DefaultRedirects : NullRedirects,
+ /*SecondsToWait=*/0, /*MemoryLimit=*/0, &ErrMsg);
+
+ if (Result < 0) {
Error E = make_error<StringError>("Error running interesting-ness test: " +
ErrMsg,
inconvertibleErrorCode());
exit(1);
}
- // Poll every few seconds, taking a break to check if we should try to kill
- // the process. We're trying to early exit on long running parallel reductions
- // once we know they don't matter.
- std::optional<unsigned> SecondsToWait(PollInterval);
- bool Polling = true;
- sys::ProcessInfo WaitPI;
-
- while (WaitPI.Pid == 0) { // Process has not changed state.
- WaitPI = sys::Wait(PI, SecondsToWait, &ErrMsg, nullptr, Polling);
- // TODO: This should probably be std::atomic_flag
- if (Killed) {
- // The current Program API does not have a way to directly kill, but we
- // can timeout after 0 seconds.
- SecondsToWait = 0;
- Polling = false;
- }
- }
-
- return !WaitPI.ReturnCode;
+ return !Result;
}
void TestRunner::setProgram(std::unique_ptr<ReducerWorkItem> P) {
void readBitcode(ReducerWorkItem &M, MemoryBufferRef Data, LLVMContext &Ctx,
StringRef ToolName);
-bool isReduced(ReducerWorkItem &M, const TestRunner &Test,
- const std::atomic<bool> &Killed) {
+bool isReduced(ReducerWorkItem &M, const TestRunner &Test) {
const bool UseBitcode = Test.inputIsBitcode() || TmpFilesAsBitcode;
SmallString<128> CurrentFilepath;
}
// Current Chunks aren't interesting
- return Test.run(CurrentFilepath, Killed);
+ return Test.run(CurrentFilepath);
}
/// Splits Chunks in half and prints them.
std::unique_ptr<ReducerWorkItem> Clone, const TestRunner &Test,
ReductionFunc ExtractChunksFromModule,
const DenseSet<Chunk> &UninterestingChunks,
- const std::vector<Chunk> &ChunksStillConsideredInteresting,
- const std::atomic<bool> &Killed) {
+ const std::vector<Chunk> &ChunksStillConsideredInteresting) {
// Take all of ChunksStillConsideredInteresting chunks, except those we've
// already deemed uninteresting (UninterestingChunks) but didn't remove
// from ChunksStillConsideredInteresting yet, and additionally ignore
errs() << "\n";
}
- if (!isReduced(*Clone, Test, Killed)) {
+ if (!isReduced(*Clone, Test)) {
// Program became non-reduced, so this chunk appears to be interesting.
if (Verbose)
errs() << "\n";
Chunk &ChunkToCheckForUninterestingness, TestRunner &Test,
ReductionFunc ExtractChunksFromModule, DenseSet<Chunk> &UninterestingChunks,
std::vector<Chunk> &ChunksStillConsideredInteresting,
- SmallString<0> &OriginalBC, std::atomic<bool> &AnyReduced,
- const std::atomic<bool> &Killed) {
+ SmallString<0> &OriginalBC, std::atomic<bool> &AnyReduced) {
LLVMContext Ctx;
auto CloneMMM = std::make_unique<ReducerWorkItem>();
MemoryBufferRef Data(StringRef(OriginalBC), "<bc file>");
if (std::unique_ptr<ReducerWorkItem> ChunkResult =
CheckChunk(ChunkToCheckForUninterestingness, std::move(CloneMMM),
Test, ExtractChunksFromModule, UninterestingChunks,
- ChunksStillConsideredInteresting, Killed)) {
+ ChunksStillConsideredInteresting)) {
raw_svector_ostream BCOS(Result);
writeBitcode(*ChunkResult, BCOS);
// Communicate that the task reduced a chunk.
assert(!verifyReducerWorkItem(Test.getProgram(), &errs()) &&
"input module is broken after counting chunks");
- assert(isReduced(Test.getProgram(), Test, std::atomic<bool>()) &&
+ assert(isReduced(Test.getProgram(), Test) &&
"input module no longer interesting after counting chunks");
#ifndef NDEBUG
writeBitcode(Test.getProgram(), BCOS);
}
- // If doing parallel reduction, signal to running workitem threads that we
- // no longer care about their results. They should try to kill the reducer
- // workitem process and exit.
- std::atomic<bool> Killed = false;
-
SharedTaskQueue TaskQueue;
for (auto I = ChunksStillConsideredInteresting.rbegin(),
E = ChunksStillConsideredInteresting.rend();
for (unsigned J = 0; J < NumInitialTasks; ++J) {
TaskQueue.emplace_back(ChunkThreadPool.async(
[J, I, &Test, &ExtractChunksFromModule, &UninterestingChunks,
- &ChunksStillConsideredInteresting, &OriginalBC, &AnyReduced,
- &Killed]() {
+ &ChunksStillConsideredInteresting, &OriginalBC, &AnyReduced]() {
return ProcessChunkFromSerializedBitcode(
*(I + J), Test, ExtractChunksFromModule,
UninterestingChunks, ChunksStillConsideredInteresting,
- OriginalBC, AnyReduced, Killed);
+ OriginalBC, AnyReduced);
}));
}
TaskQueue.emplace_back(ChunkThreadPool.async(
[&Test, &ExtractChunksFromModule, &UninterestingChunks,
&ChunksStillConsideredInteresting, &OriginalBC,
- &ChunkToCheck, &AnyReduced, &Killed]() {
+ &ChunkToCheck, &AnyReduced]() {
return ProcessChunkFromSerializedBitcode(
ChunkToCheck, Test, ExtractChunksFromModule,
UninterestingChunks, ChunksStillConsideredInteresting,
- OriginalBC, AnyReduced, Killed);
+ OriginalBC, AnyReduced);
}));
}
continue;
break;
}
- Killed = true;
-
// If we broke out of the loop, we still need to wait for everything to
// avoid race access to the chunk set.
//
*I,
cloneReducerWorkItem(Test.getProgram(), Test.getTargetMachine()),
Test, ExtractChunksFromModule, UninterestingChunks,
- ChunksStillConsideredInteresting, Killed);
+ ChunksStillConsideredInteresting);
}
if (!Result)