@@ -65,7 +65,8 @@ void writeBitcode(ReducerWorkItem &M, raw_ostream &OutStream);
65
65
void readBitcode (ReducerWorkItem &M, MemoryBufferRef Data, LLVMContext &Ctx,
66
66
StringRef ToolName);
67
67
68
- bool isReduced (ReducerWorkItem &M, const TestRunner &Test) {
68
+ bool isReduced (ReducerWorkItem &M, const TestRunner &Test,
69
+ const std::atomic<bool > &Killed) {
69
70
const bool UseBitcode = Test.inputIsBitcode () || TmpFilesAsBitcode;
70
71
71
72
SmallString<128 > CurrentFilepath;
@@ -96,7 +97,7 @@ bool isReduced(ReducerWorkItem &M, const TestRunner &Test) {
96
97
}
97
98
98
99
// Current Chunks aren't interesting
99
- return Test.run (CurrentFilepath);
100
+ return Test.run (CurrentFilepath, Killed );
100
101
}
101
102
102
103
// / Splits Chunks in half and prints them.
@@ -138,7 +139,8 @@ CheckChunk(const Chunk &ChunkToCheckForUninterestingness,
138
139
std::unique_ptr<ReducerWorkItem> Clone, const TestRunner &Test,
139
140
ReductionFunc ExtractChunksFromModule,
140
141
const DenseSet<Chunk> &UninterestingChunks,
141
- const std::vector<Chunk> &ChunksStillConsideredInteresting) {
142
+ const std::vector<Chunk> &ChunksStillConsideredInteresting,
143
+ const std::atomic<bool > &Killed) {
142
144
// Take all of ChunksStillConsideredInteresting chunks, except those we've
143
145
// already deemed uninteresting (UninterestingChunks) but didn't remove
144
146
// from ChunksStillConsideredInteresting yet, and additionally ignore
@@ -178,7 +180,7 @@ CheckChunk(const Chunk &ChunkToCheckForUninterestingness,
178
180
errs () << " \n " ;
179
181
}
180
182
181
- if (!isReduced (*Clone, Test)) {
183
+ if (!isReduced (*Clone, Test, Killed )) {
182
184
// Program became non-reduced, so this chunk appears to be interesting.
183
185
if (Verbose)
184
186
errs () << " \n " ;
@@ -191,7 +193,8 @@ static SmallString<0> ProcessChunkFromSerializedBitcode(
191
193
Chunk &ChunkToCheckForUninterestingness, TestRunner &Test,
192
194
ReductionFunc ExtractChunksFromModule, DenseSet<Chunk> &UninterestingChunks,
193
195
std::vector<Chunk> &ChunksStillConsideredInteresting,
194
- SmallString<0 > &OriginalBC, std::atomic<bool > &AnyReduced) {
196
+ SmallString<0 > &OriginalBC, std::atomic<bool > &AnyReduced,
197
+ const std::atomic<bool > &Killed) {
195
198
LLVMContext Ctx;
196
199
auto CloneMMM = std::make_unique<ReducerWorkItem>();
197
200
MemoryBufferRef Data (StringRef (OriginalBC), " <bc file>" );
@@ -201,7 +204,7 @@ static SmallString<0> ProcessChunkFromSerializedBitcode(
201
204
if (std::unique_ptr<ReducerWorkItem> ChunkResult =
202
205
CheckChunk (ChunkToCheckForUninterestingness, std::move (CloneMMM),
203
206
Test, ExtractChunksFromModule, UninterestingChunks,
204
- ChunksStillConsideredInteresting)) {
207
+ ChunksStillConsideredInteresting, Killed )) {
205
208
raw_svector_ostream BCOS (Result);
206
209
writeBitcode (*ChunkResult, BCOS);
207
210
// Communicate that the task reduced a chunk.
@@ -242,7 +245,7 @@ void llvm::runDeltaPass(TestRunner &Test, ReductionFunc ExtractChunksFromModule,
242
245
243
246
assert (!verifyReducerWorkItem (Test.getProgram (), &errs ()) &&
244
247
" input module is broken after counting chunks" );
245
- assert (isReduced (Test.getProgram (), Test) &&
248
+ assert (isReduced (Test.getProgram (), Test, std::atomic< bool >() ) &&
246
249
" input module no longer interesting after counting chunks" );
247
250
248
251
#ifndef NDEBUG
@@ -290,6 +293,11 @@ void llvm::runDeltaPass(TestRunner &Test, ReductionFunc ExtractChunksFromModule,
290
293
writeBitcode (Test.getProgram (), BCOS);
291
294
}
292
295
296
+ // If doing parallel reduction, signal to running workitem threads that we
297
+ // no longer care about their results. They should try to kill the reducer
298
+ // workitem process and exit.
299
+ std::atomic<bool > Killed = false ;
300
+
293
301
SharedTaskQueue TaskQueue;
294
302
for (auto I = ChunksStillConsideredInteresting.rbegin (),
295
303
E = ChunksStillConsideredInteresting.rend ();
@@ -316,11 +324,12 @@ void llvm::runDeltaPass(TestRunner &Test, ReductionFunc ExtractChunksFromModule,
316
324
for (unsigned J = 0 ; J < NumInitialTasks; ++J) {
317
325
TaskQueue.emplace_back (ChunkThreadPool.async (
318
326
[J, I, &Test, &ExtractChunksFromModule, &UninterestingChunks,
319
- &ChunksStillConsideredInteresting, &OriginalBC, &AnyReduced]() {
327
+ &ChunksStillConsideredInteresting, &OriginalBC, &AnyReduced,
328
+ &Killed]() {
320
329
return ProcessChunkFromSerializedBitcode (
321
330
*(I + J), Test, ExtractChunksFromModule,
322
331
UninterestingChunks, ChunksStillConsideredInteresting,
323
- OriginalBC, AnyReduced);
332
+ OriginalBC, AnyReduced, Killed );
324
333
}));
325
334
}
326
335
@@ -344,11 +353,11 @@ void llvm::runDeltaPass(TestRunner &Test, ReductionFunc ExtractChunksFromModule,
344
353
TaskQueue.emplace_back (ChunkThreadPool.async (
345
354
[&Test, &ExtractChunksFromModule, &UninterestingChunks,
346
355
&ChunksStillConsideredInteresting, &OriginalBC,
347
- &ChunkToCheck, &AnyReduced]() {
356
+ &ChunkToCheck, &AnyReduced, &Killed ]() {
348
357
return ProcessChunkFromSerializedBitcode (
349
358
ChunkToCheck, Test, ExtractChunksFromModule,
350
359
UninterestingChunks, ChunksStillConsideredInteresting,
351
- OriginalBC, AnyReduced);
360
+ OriginalBC, AnyReduced, Killed );
352
361
}));
353
362
}
354
363
continue ;
@@ -361,6 +370,8 @@ void llvm::runDeltaPass(TestRunner &Test, ReductionFunc ExtractChunksFromModule,
361
370
break ;
362
371
}
363
372
373
+ Killed = true ;
374
+
364
375
// If we broke out of the loop, we still need to wait for everything to
365
376
// avoid race access to the chunk set.
366
377
//
@@ -375,7 +386,7 @@ void llvm::runDeltaPass(TestRunner &Test, ReductionFunc ExtractChunksFromModule,
375
386
*I,
376
387
cloneReducerWorkItem (Test.getProgram (), Test.getTargetMachine ()),
377
388
Test, ExtractChunksFromModule, UninterestingChunks,
378
- ChunksStillConsideredInteresting);
389
+ ChunksStillConsideredInteresting, Killed );
379
390
}
380
391
381
392
if (!Result)
0 commit comments