@@ -280,14 +280,17 @@ mergeBatchInputs(ArrayRef<const Job *> jobs,
280
280
return false ;
281
281
}
282
282
283
- // / Debugging only: return whether the set of \p jobs is an ordered subsequence
284
- // / of the sequence of top-level input files in the \c Compilation \p C.
285
- static bool
286
- jobsAreSubsequenceOfCompilationInputs (ArrayRef<const Job *> jobs,
287
- Compilation &C) {
288
- llvm::SmallVector<const Job *, 16 > sortedJobs;
283
+ // / Unfortunately the success or failure of a Swift compilation is currently
284
+ // / sensitive to the order in which files are processed, at least in terms of
285
+ // / the order of processing extensions (and likely other ways we haven't
286
+ // / discovered yet). So long as this is true, we need to make sure any batch job
287
+ // / we build names its inputs in an order that's a subsequence of the sequence
288
+ // / of inputs the driver was initially invoked with.
289
+ static void sortJobsToMatchCompilationInputs (ArrayRef<const Job *> unsortedJobs,
290
+ SmallVectorImpl<const Job *> &sortedJobs,
291
+ Compilation &C) {
289
292
llvm::StringMap<const Job *> jobsByInput;
290
- for (const Job *J : jobs ) {
293
+ for (const Job *J : unsortedJobs ) {
291
294
const CompileJobAction *CJA = cast<CompileJobAction>(&J->getSource ());
292
295
const InputAction* IA = findSingleSwiftInput (CJA);
293
296
auto R = jobsByInput.insert (std::make_pair (IA->getInputArg ().getValue (),
@@ -300,40 +303,34 @@ jobsAreSubsequenceOfCompilationInputs(ArrayRef<const Job *> jobs,
300
303
sortedJobs.push_back (I->second );
301
304
}
302
305
}
303
- if (sortedJobs.size () != jobs.size ())
304
- return false ;
305
- for (size_t i = 0 ; i < sortedJobs.size (); ++i) {
306
- if (sortedJobs[i] != jobs[i])
307
- return false ;
308
- }
309
- return true ;
310
306
}
311
307
312
308
// / Construct a \c BatchJob by merging the constituent \p jobs' CommandOutput,
313
309
// / input \c Job and \c Action members. Call through to \c constructInvocation
314
310
// / on \p BatchJob, to build the \c InvocationInfo.
315
311
std::unique_ptr<Job>
316
- ToolChain::constructBatchJob (ArrayRef<const Job *> jobs ,
312
+ ToolChain::constructBatchJob (ArrayRef<const Job *> unsortedJobs ,
317
313
Compilation &C) const
318
314
{
319
- if (jobs .empty ())
315
+ if (unsortedJobs .empty ())
320
316
return nullptr ;
321
317
322
- assert (jobsAreSubsequenceOfCompilationInputs (jobs, C));
318
+ llvm::SmallVector<const Job *, 16 > sortedJobs;
319
+ sortJobsToMatchCompilationInputs (unsortedJobs, sortedJobs, C);
323
320
324
321
// Synthetic OutputInfo is a slightly-modified version of the initial
325
322
// compilation's OI.
326
323
auto OI = C.getOutputInfo ();
327
324
OI.CompilerMode = OutputInfo::Mode::BatchModeCompile;
328
325
329
- auto const *executablePath = jobs [0 ]->getExecutable ();
330
- auto outputType = jobs [0 ]->getOutput ().getPrimaryOutputType ();
331
- auto output = makeBatchCommandOutput (jobs , C, outputType);
326
+ auto const *executablePath = sortedJobs [0 ]->getExecutable ();
327
+ auto outputType = sortedJobs [0 ]->getOutput ().getPrimaryOutputType ();
328
+ auto output = makeBatchCommandOutput (sortedJobs , C, outputType);
332
329
333
330
llvm::SmallSetVector<const Job *, 16 > inputJobs;
334
331
llvm::SmallSetVector<const Action *, 16 > inputActions;
335
332
auto *batchCJA = C.createAction <CompileJobAction>(outputType);
336
- if (mergeBatchInputs (jobs , inputJobs, inputActions, batchCJA))
333
+ if (mergeBatchInputs (sortedJobs , inputJobs, inputActions, batchCJA))
337
334
return nullptr ;
338
335
339
336
JobContext context{C, inputJobs.getArrayRef (), inputActions.getArrayRef (),
@@ -346,7 +343,7 @@ ToolChain::constructBatchJob(ArrayRef<const Job *> jobs,
346
343
std::move (invocationInfo.Arguments ),
347
344
std::move (invocationInfo.ExtraEnvironment ),
348
345
std::move (invocationInfo.FilelistInfos ),
349
- jobs );
346
+ sortedJobs );
350
347
}
351
348
352
349
bool
0 commit comments