@@ -442,153 +442,13 @@ class TargetLibraryInfo {
442442 return false ;
443443 }
444444
445+ static bool doesArgEscape (LibFunc F, unsigned ArgNo);
446+ static bool isReturnValueEscaping (LibFunc F);
445447
446448 static bool isLockAcquireFunction (const Function &F);
447449 static bool isLockReleaseFunction (const Function &F);
448450
449- bool isSyncFree (LibFunc F) const {
450- if (getState (F) == TargetLibraryInfoImpl::Unavailable)
451- return false ; // If the function is unavailable, it cannot be sync-free
452-
453- switch (F) {
454- // Functions that are NOT sync-free (they use synchronization)
455-
456- // Direct atomic operations and guard mechanisms:
457- case LibFunc_atomic_load: case LibFunc_atomic_store:
458- case LibFunc_cxa_guard_abort: case LibFunc_cxa_guard_acquire:
459- case LibFunc_cxa_guard_release:
460-
461- // Explicit file locks:
462- case LibFunc_flockfile: case LibFunc_ftrylockfile: case LibFunc_funlockfile:
463-
464- // Standard I/O (versions without _unlocked suffix imply internal locks):
465- // Operations with FILE* or global stdin/stdout/stderr
466- case LibFunc_fclose: case LibFunc_fdopen: case LibFunc_fflush:
467- case LibFunc_fgetc: case LibFunc_fgetpos: case LibFunc_fgets:
468- case LibFunc_fopen: case LibFunc_fopen64: case LibFunc_fprintf:
469- case LibFunc_fiprintf: // Assumed to be an analog of fprintf for integers to FILE*
470- case LibFunc_small_fprintf: case LibFunc_fputc: case LibFunc_fputs:
471- case LibFunc_fread: case LibFunc_fscanf: case LibFunc_fseek:
472- case LibFunc_fseeko: case LibFunc_fseeko64: case LibFunc_fsetpos:
473- case LibFunc_ftell: case LibFunc_ftello: case LibFunc_ftello64:
474- case LibFunc_fwrite: case LibFunc_getc: case LibFunc_getchar:
475- case LibFunc_gets: // Uses stdio, usually with locking
476- case LibFunc_perror: // Writes to stderr, which is usually locked
477- case LibFunc_printf:
478- case LibFunc_iprintf: // Printing integers, usually to stdout
479- case LibFunc_small_printf: case LibFunc_putc: case LibFunc_putchar:
480- case LibFunc_puts: case LibFunc_rewind: case LibFunc_scanf:
481- case LibFunc_dunder_isoc99_scanf: // This is scanf
482- case LibFunc_setbuf: // Modifies FILE stream buffering, implies synchronization
483- case LibFunc_setvbuf: // Modifies FILE stream buffering, implies synchronization
484- case LibFunc_tmpfile: case LibFunc_tmpfile64: case LibFunc_ungetc:
485- case LibFunc_vfprintf: case LibFunc_vfscanf: case LibFunc_vprintf:
486- case LibFunc_vscanf:
487- case LibFunc_under_IO_getc: // Assumed to be similar to fgetc
488- case LibFunc_under_IO_putc: // Assumed to be similar to fputc
489- case LibFunc_clearerr: // Modifies FILE state, likely requires synchronization
490- case LibFunc_feof: // Reads FILE state, likely requires synchronization
491- case LibFunc_ferror: // Reads FILE state, likely requires synchronization
492- case LibFunc_fileno: // Reads FILE state, conservatively assumed to potentially require synchronization
493-
494- // Memory allocation/deallocation (usually internally synchronized):
495- // MSVC new/delete operators
496- case LibFunc_msvc_new_int:
497- case LibFunc_msvc_new_int_nothrow:
498- case LibFunc_msvc_new_longlong:
499- case LibFunc_msvc_new_longlong_nothrow:
500- case LibFunc_msvc_delete_ptr32:
501- case LibFunc_msvc_delete_ptr32_nothrow:
502- case LibFunc_msvc_delete_ptr32_int:
503- case LibFunc_msvc_delete_ptr64:
504- case LibFunc_msvc_delete_ptr64_nothrow:
505- case LibFunc_msvc_delete_ptr64_longlong:
506- case LibFunc_msvc_new_array_int:
507- case LibFunc_msvc_new_array_int_nothrow:
508- case LibFunc_msvc_new_array_longlong:
509- case LibFunc_msvc_new_array_longlong_nothrow:
510- case LibFunc_msvc_delete_array_ptr32:
511- case LibFunc_msvc_delete_array_ptr32_nothrow:
512- case LibFunc_msvc_delete_array_ptr32_int:
513- case LibFunc_msvc_delete_array_ptr64:
514- case LibFunc_msvc_delete_array_ptr64_nothrow:
515- case LibFunc_msvc_delete_array_ptr64_longlong:
516- // Itanium C++ ABI new/delete operators
517- case LibFunc_ZdaPv: case LibFunc_ZdaPvRKSt9nothrow_t:
518- case LibFunc_ZdaPvSt11align_val_t:
519- case LibFunc_ZdaPvSt11align_val_tRKSt9nothrow_t:
520- case LibFunc_ZdaPvj: case LibFunc_ZdaPvjSt11align_val_t:
521- case LibFunc_ZdaPvm: case LibFunc_ZdaPvmSt11align_val_t:
522- case LibFunc_ZdlPv: case LibFunc_ZdlPvRKSt9nothrow_t:
523- case LibFunc_ZdlPvSt11align_val_t:
524- case LibFunc_ZdlPvSt11align_val_tRKSt9nothrow_t:
525- case LibFunc_ZdlPvj: case LibFunc_ZdlPvjSt11align_val_t:
526- case LibFunc_ZdlPvm: case LibFunc_ZdlPvmSt11align_val_t:
527- case LibFunc_Znaj: case LibFunc_ZnajRKSt9nothrow_t:
528- case LibFunc_ZnajSt11align_val_t:
529- case LibFunc_ZnajSt11align_val_tRKSt9nothrow_t:
530- case LibFunc_Znam: case LibFunc_Znam12__hot_cold_t:
531- case LibFunc_ZnamRKSt9nothrow_t:
532- case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
533- case LibFunc_ZnamSt11align_val_t:
534- case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
535- case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
536- case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
537- case LibFunc_Znwj: case LibFunc_ZnwjRKSt9nothrow_t:
538- case LibFunc_ZnwjSt11align_val_t:
539- case LibFunc_ZnwjSt11align_val_tRKSt9nothrow_t:
540- case LibFunc_Znwm: case LibFunc_Znwm12__hot_cold_t:
541- case LibFunc_ZnwmRKSt9nothrow_t:
542- case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
543- case LibFunc_ZnwmSt11align_val_t:
544- case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
545- case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
546- case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
547- // Standard C allocators
548- case LibFunc_aligned_alloc: case LibFunc_calloc: case LibFunc_free:
549- case LibFunc_malloc:
550- case LibFunc_memalign: // Obsolete, but if present, it's an allocator
551- case LibFunc_posix_memalign: case LibFunc_realloc:
552- case LibFunc_reallocf: // Calls realloc, then free on failure
553- case LibFunc_valloc: // Obsolete, but if present, it's an allocator
554- case LibFunc_strdup: // Calls malloc
555- case LibFunc_dunder_strdup: // Calls malloc
556- case LibFunc_strndup: // Calls malloc
557- case LibFunc_dunder_strndup: // Calls malloc
558- // OpenMP runtime allocators
559- case LibFunc___kmpc_alloc_shared: case LibFunc___kmpc_free_shared:
560- // Vector allocators (assuming they might be synchronized like standard ones)
561- case LibFunc_vec_calloc: case LibFunc_vec_free: case LibFunc_vec_malloc:
562- case LibFunc_vec_realloc:
563-
564- // Process/system level utilities that are inherently synchronizing
565- // or involve significant system state changes:
566- case LibFunc_fork:
567- case LibFunc_pclose: // Waits for process completion
568- case LibFunc_popen: // Creates a pipe and process
569- case LibFunc_system: // Creates a shell, involves fork/exec
570- case LibFunc_execl: case LibFunc_execle: case LibFunc_execlp:
571- case LibFunc_execv: case LibFunc_execvP: case LibFunc_execve:
572- case LibFunc_execvp: case LibFunc_execvpe:
573-
574- // Other potentially synchronized standard library functions:
575- case LibFunc_atexit: // Modification of a global list
576- case LibFunc_cxa_atexit: // Modification of a global list
577- case LibFunc_getenv: // Access to shared environment, may be locked
578- case LibFunc_mktime: // Access to global/static timezone data
579- case LibFunc_ctermid: // Often uses a static buffer, potentially requires synchronization
580- case LibFunc_getlogin_r: // System call to get information
581- case LibFunc_getpwnam: // Access to system database (e.g., /etc/passwd)
582-
583- return false ; // These functions are NOT sync-free.
584-
585- default :
586- // All other functions (mathematical, string operations without memory allocation,
587- // I/O with _unlocked suffix, buffer operations like sprintf/sscanf, etc.)
588- // are considered sync-free.
589- return true ;
590- }
591- }
451+ bool isSyncFree (LibFunc F) const ;
592452
593453 StringRef getName (LibFunc F) const {
594454 auto State = getState (F);
0 commit comments