@@ -1239,10 +1239,19 @@ fn start_executing_work<B: ExtraBackendMethods>(
12391239 let mut needs_thin_lto = Vec :: new ( ) ;
12401240 let mut lto_import_only_modules = Vec :: new ( ) ;
12411241 let mut started_lto = false ;
1242- let mut codegen_aborted = false ;
12431242
1244- // This flag tracks whether all items have gone through codegens
1245- let mut codegen_done = false ;
1243+ /// Possible state transitions:
1244+ /// - Ongoing -> Completed
1245+ /// - Ongoing -> Aborted
1246+ /// - Completed -> Aborted
1247+ #[ derive( Debug , PartialEq ) ]
1248+ enum CodegenState {
1249+ Ongoing ,
1250+ Completed ,
1251+ Aborted ,
1252+ }
1253+ use CodegenState :: * ;
1254+ let mut codegen_state = Ongoing ;
12461255
12471256 // This is the queue of LLVM work items that still need processing.
12481257 let mut work_items = Vec :: < ( WorkItem < B > , u64 ) > :: new ( ) ;
@@ -1262,10 +1271,10 @@ fn start_executing_work<B: ExtraBackendMethods>(
12621271 // wait for all existing work to finish, so many of the conditions here
12631272 // only apply if codegen hasn't been aborted as they represent pending
12641273 // work to be done.
1265- while !codegen_done
1274+ while codegen_state == Ongoing
12661275 || running > 0
12671276 || main_thread_worker_state == MainThreadWorkerState :: LLVMing
1268- || ( !codegen_aborted
1277+ || ( codegen_state == Completed
12691278 && !( work_items. is_empty ( )
12701279 && needs_fat_lto. is_empty ( )
12711280 && needs_thin_lto. is_empty ( )
@@ -1275,7 +1284,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
12751284 // While there are still CGUs to be codegened, the coordinator has
12761285 // to decide how to utilize the compiler processes implicit Token:
12771286 // For codegenning more CGU or for running them through LLVM.
1278- if !codegen_done {
1287+ if codegen_state == Ongoing {
12791288 if main_thread_worker_state == MainThreadWorkerState :: Idle {
12801289 // Compute the number of workers that will be running once we've taken as many
12811290 // items from the work queue as we can, plus one for the main thread. It's not
@@ -1312,10 +1321,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
13121321 spawn_work ( cgcx, item) ;
13131322 }
13141323 }
1315- } else if codegen_aborted {
1316- // don't queue up any more work if codegen was aborted, we're
1317- // just waiting for our existing children to finish
1318- } else {
1324+ } else if codegen_state == Completed {
13191325 // If we've finished everything related to normal codegen
13201326 // then it must be the case that we've got some LTO work to do.
13211327 // Perform the serial work here of figuring out what we're
@@ -1382,11 +1388,15 @@ fn start_executing_work<B: ExtraBackendMethods>(
13821388 // Already making good use of that token
13831389 }
13841390 }
1391+ } else {
1392+ // Don't queue up any more work if codegen was aborted, we're
1393+ // just waiting for our existing children to finish.
1394+ assert ! ( codegen_state == Aborted ) ;
13851395 }
13861396
13871397 // Spin up what work we can, only doing this while we've got available
13881398 // parallelism slots and work left to spawn.
1389- while !codegen_aborted && !work_items. is_empty ( ) && running < tokens. len ( ) {
1399+ while codegen_state != Aborted && !work_items. is_empty ( ) && running < tokens. len ( ) {
13901400 let ( item, _) = work_items. pop ( ) . unwrap ( ) ;
13911401
13921402 maybe_start_llvm_timer ( prof, cgcx. config ( item. module_kind ( ) ) , & mut llvm_start_time) ;
@@ -1438,8 +1448,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
14381448 Err ( e) => {
14391449 let msg = & format ! ( "failed to acquire jobserver token: {}" , e) ;
14401450 shared_emitter. fatal ( msg) ;
1441- codegen_done = true ;
1442- codegen_aborted = true ;
1451+ codegen_state = Aborted ;
14431452 }
14441453 }
14451454 }
@@ -1467,7 +1476,9 @@ fn start_executing_work<B: ExtraBackendMethods>(
14671476 }
14681477
14691478 Message :: CodegenComplete => {
1470- codegen_done = true ;
1479+ if codegen_state != Aborted {
1480+ codegen_state = Completed ;
1481+ }
14711482 assert_eq ! ( main_thread_worker_state, MainThreadWorkerState :: Codegenning ) ;
14721483 main_thread_worker_state = MainThreadWorkerState :: Idle ;
14731484 }
@@ -1479,8 +1490,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
14791490 // then conditions above will ensure no more work is spawned but
14801491 // we'll keep executing this loop until `running` hits 0.
14811492 Message :: CodegenAborted => {
1482- codegen_done = true ;
1483- codegen_aborted = true ;
1493+ codegen_state = Aborted ;
14841494 }
14851495
14861496 Message :: WorkItem { result, worker_id } => {
@@ -1512,8 +1522,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
15121522 }
15131523 Err ( Some ( WorkerFatalError ) ) => {
15141524 // Like `CodegenAborted`, wait for remaining work to finish.
1515- codegen_done = true ;
1516- codegen_aborted = true ;
1525+ codegen_state = Aborted ;
15171526 }
15181527 Err ( None ) => {
15191528 // If the thread failed that means it panicked, so
@@ -1525,15 +1534,15 @@ fn start_executing_work<B: ExtraBackendMethods>(
15251534
15261535 Message :: AddImportOnlyModule { module_data, work_product } => {
15271536 assert ! ( !started_lto) ;
1528- assert ! ( !codegen_done ) ;
1537+ assert_eq ! ( codegen_state , Ongoing ) ;
15291538 assert_eq ! ( main_thread_worker_state, MainThreadWorkerState :: Codegenning ) ;
15301539 lto_import_only_modules. push ( ( module_data, work_product) ) ;
15311540 main_thread_worker_state = MainThreadWorkerState :: Idle ;
15321541 }
15331542 }
15341543 }
15351544
1536- if codegen_aborted {
1545+ if codegen_state == Aborted {
15371546 return Err ( ( ) ) ;
15381547 }
15391548
0 commit comments