GCC 16이 출시됨
1 week ago
13
GNU 컴파일러 컬렉션의 새 릴리스는 C++ 기본 표준을 gnu++20으로 변경 하고, C++20 구현을 더 이상 experimental로 보지 않는 중요한 전환점이 됨
C++26 reflection·contracts·constexpr 기능, C++23 기능, experimental C++23·C++26 library 지원이 추가되었고, template 오류와 type trait constraint failure 진단은 계층형 메시지 로 더 자세해짐
OpenMP와 OpenACC는 GPU 메모리 할당, target memset, device memcpy API를 확장했고, Ada·Fortran·Modula-2·Algol 68 front end에도 새 언어 기능과 실험적 컴파일러 가 들어감
x86-64는 AMD Zen6, Intel Wildcat Lake, Intel Nova Lake를 지원하고, AMD GPU·LoongArch·IBM z Systems·Solaris·Windows 쪽에서도 타깃별 기능과 ABI 변화 가 추가됨
JSON 진단 형식 제거와 SARIF·HTML 진단 강화, static analyzer 개선, libgdiagnostics의 37개 entrypoint 추가로 도구 연동과 진단 인프라 가 크게 넓어짐
호환성 변경과 공통 개선
Solaris에서 int8_t 등은 C99 표준 준수를 위해 signed char 가 되었고, 이는 호환되지 않는 변경임
Solaris에서 -pthread 옵션은 더 이상 _REENTRANT 를 미리 정의하지 않음
-fdiagnostics-format= 의 json 형식은 제거되었고, 기계 판독 가능한 진단에는 SARIF 를 써야 함
Link-Time Optimization 은 -flto-toplevel-asm-heuristics로 최상위 asm 문 처리를 더 잘 다루게 됨
speculative devirtualization 은 일반 간접 함수 호출을 처리하고, 둘 이상의 대상 추측을 지원함
vectorizer는 reduction의 루프 내부 병렬성 식별이 더 유연해졌고, 반복 횟수를 알 수 없는 루프와 uncounted loop 벡터화를 지원함
masking을 쓰는 vector length agnostic loop의 정렬용 peeling, mutual peeling for alignment, early break 루프의 vector induction 계산 제거도 지원함
GCC Command Options 와 option index 는 이전에 빠졌던 많은 옵션을 담도록 수정됨
GCC-specific attributes 문서는 GCC가 지원하는 모든 C/C++ dialect에서 허용하는 표준 attribute 문법을 더 강조하도록 현대화됨
언어별 주요 변경
OpenMP와 OpenACC
OpenMP 메모리 할당 지원이 강화되어 pinned trait allocator와 ompx_gnu_pinned_mem_alloc은 사용 가능할 때 CUDA API 를 사용하며, Nvidia GPU에서 해당 메모리 접근 성능을 개선함
GNU 확장인 ompx_gnu_managed_mem_alloc allocator와 ompx_gnu_managed_mem_space는 host에서 device-accessible memory를 할당함
unified-shared memory가 지원되지 않아도 device 접근이 가능하며, 모든 host memory가 device-accessible인 시스템에서도 다른 메모리와 page-migration 동작이 다를 수 있음
OpenMP 5.0은 C/C++에서 제한적 declare mapper 지원을 추가했고, uses_allocators clause는 OpenMP 5.2 문법 변경과 OpenMP 6.0 semicolon 지원까지 포함함
OpenMP 5.1은 C/C++에서 map clause와 target update construct의 iterator modifier 초기 지원을 추가함
OpenMP 5.2는 C/C++에서 begin declare variant directive를 지원함
OpenMP 6.0은 omp_target_memset 과 omp_target_memset_async API routine을 추가했고, no_openmp_constructs assumptions clause도 사용할 수 있음
OpenMP 5.0, 5.1, 5.2에서 deprecated 된 directive와 clause는 기본적으로 deprecation warning을 내며, -Wno-deprecated-openmp로 끌 수 있음
deprecated named constant 또는 API routine 사용 시에도 warning이 나오며, -Wno-deprecated-declarations로 끌 수 있음
OpenACC는 C/C++/Fortran용 acc_memcpy_device와 acc_memcpy_device_async API routine을 추가함
OpenACC 3.0의 wait directive는 if clause를 받으며, OpenACC 3.3의 Fortran API routine acc_attach와 acc_detach는 OpenACC 2.6 C/C++ counterpart를 보강함
OpenACC 3.4에서는 Fortran data clause의 named constant PARAMETER 사용이 사양과 GCC에서 허용되지만, GCC에서는 compile-time과 runtime 동작에 영향을 주지 않음
Ada, Fortran, Modula-2, Algol 68
Ada GNAT 확장에는 Constructor 와 Destructor 가 추가되어 표준 Ada와 상당히 다른 construction/finalization 메커니즘을 제공함
Ada의 Implicit with , Structural Generic instantiation , Extended_Access aspect가 추가됨
Extended_Access는 unconstrained array subtype을 가리키는 general access type declaration에 지정 가능하며, pointer representation을 바꾸고 Ada가 할당하지 않은 메모리를 foreign language와 연동하기 쉽게 함
Ada는 -gnatd_V 또는 verbose mode의 -gnatd_W로 compiler debugging용 VAST를 사용할 수 있고, Ada 2022 Reduction Expressions semantic analysis, Ada.Containers.Bounded_Indefinite_Holders, accessibility rule 구현, Android 지원이 개선됨
Fortran은 single node machine에서 native shared memory multithreading을 쓰는 coarray와 Fortran 2018 TEAM feature를 다룸
Fortran 2003 Parameterized Derived Types 지원이 개선되었고, LEN parameter 처리는 동작하지만 PR82649에 따른 향후 representation 변경이 필요함
Fortran 2018은 IMPORT statement 확장, REDUCE intrinsic, 새 GENERIC statement를 지원함
Fortran 2023은 sinpi 같은 trigonometric function 추가분, split intrinsic subroutine, optional lower bound를 인자로 받는 c_f_pointer를 지원함
-fexternal-blas64 옵션은 MATMUL에서 64-bit integer argument로 external BLAS routine을 호출하며, 64-bit system과 -ffrontend-optimize 적용 시에만 유효함
Modula-2는 import list, module name, nested scope symbol 처리 중 spelling hint를 내고, 새 wide set 구현과 M2WIDESET library module을 도입함
wide set 변경은 ABI를 바꿔 이전 GCC 버전의 object file과 link-time error를 만들 수 있음
Modula-2 기본 library에는 BinDict binary dictionary module이 추가되었고, 여러 module에 Write와 WriteLn procedure가 제공되며, -fm2-pathname-root= 옵션으로 external library module 접근이 개선됨
GCC에는 experimental Algol 68 compiler인 ga68이 포함되며, Revised Report와 IFIP WG2.1 Algol 68 Support subcommittee가 승인한 errata 구현을 목표로 함
C++와 libstdc++
C++ compilation의 기본 언어 버전은 -std=gnu++17 에서 -std=gnu++20 으로 바뀜
이전 C++ 표준에 의존하는 코드는 build flag에 -std= 을 추가하거나 코드를 porting해야 하며, porting notes 참고
C++20 modules 지원은 여전히 experimental이며 -fmodules 로 활성화해야 함
C++26 기능은 reflection, annotations for reflection, base class subobject splicing, function parameter reflection, contracts, constexpr exceptions, constexpr virtual inheritance 등 다수가 구현됨
P2996R13 Reflection 은 -std=c++26 -freflection으로 활성화됨
일부 P2686R4 는 부분 지원이며, structured binding은 constexpr 가능하지만 constexpr automatic variable 참조는 아직 허용되지 않음
C++23 기능은 P2036R3 , P2590R2 , P2246R1 이 구현됨
C++ error message는 template 관련 문제 등에서 계층 구조 를 가지며, indentation과 bullet point로 message nesting을 표시함
experimental C++20 modules 지원은 --compile-std-module 옵션을 추가해 <bits/stdc++.h> header unit과 std, std.compat module을 source file compile 전에 빌드함
<bits/stdc++.h> header unit이 빌드되어 있으면 importable standard library header의 #include를 <bits/stdc++.h> import로 투명하게 변환함
보고된 많은 bug가 수정됨
standard library type trait의 constraint failure diagnostics는 is_constructible_v, is_invocable_v 등이 왜 false인지 더 자세히 알려줌
libstdc++에서 128-bit integer를 지원하는 target은 std::is_integral<__int128>와 유사 trait가 항상 true가 됨
이전에는 GNU dialect에서는 true였지만 strict dialect에서는 그렇지 않았음
P0952R2: A new specification for std::generate_canonical 이 C++11 이후 영향을 받는 모든 mode에 구현되어 관찰되는 output에 영향을 줌
이전 동작은 _GLIBCXX_USE_OLD_GENERATE_CANONICAL 정의로 복원 가능함
std::variant ABI는 C++20 이상 mode와 일관되도록 갱신되었고, 특정 C++17 mode class layout에 영향을 줌
이전 동작은 _GLIBCXX_USE_VARIANT_CXX17_OLD_ABI 정의로 복원 가능하며, 영향은 C++17 mode에만 해당함
std::regex execution은 system stack 대신 heap-based stack을 쓰도록 다시 작성되어, 더 큰 string matching 중 stack overflow를 피함
C++20 구현은 더 이상 experimental이 아니며, Windows에서 std::chrono::current_zone()이 동작함
GCC 16 이전 C++20 지원은 experimental이었기 때문에, C++20 component 사용 program은 older release와 호환되지 않는다고 봐야 함
ABI 변경 대상에는 <atomic> waiting/notifying function, <semaphore> semaphore type, <syncstream> synchronization, std::format args와 std::formatter representation, <compare>의 std::partial_ordering, 일부 <ranges> adaptor representation 등이 포함됨
experimental C++23 library 지원은 std::mdspan, ranges::starts_with, ranges::ends_with, ranges::shift_left, ranges::shift_right, std::allocator_traits::allocate_at_least를 포함함
experimental C++26 library 지원은 std::simd, std::inplace_vector, std::optional<T&>, std::copyable_function, std::function_ref, std::indirect, std::polymorphic, shared pointer용 std::owner_equal, <debugging> header 등을 포함함
타깃과 운영체제 지원
IA-32/x86-64
AMD Zen6 기반 CPU는 -march=znver6로 지원되며, Zen5에 활성화된 ISA extension 위에 AVX512_BMM, AVX_NE_CONVERT, AVX_IFMA, AVX_VNNI_INT8, AVX512_FP16을 활성화함
AVX512 지원이 켜져 있고 znver4, znver5, znver6 tuning이면 auto-vectorization이 masked vector epilog 사용을 시도해 code size를 줄이고 성능을 개선함
Intel Wildcat Lake는 -march=wildcatlake, Intel Nova Lake는 -march=novalake로 지원됨
-march=novalake는 Panther Lake 기반 ISA extension에 APX_F, AVX10.1, AVX10.2, PREFETCHI를 추가로 활성화함
GCC 16부터 여러 -march= switch에서 AMX-TRANSPOSE, USER_MSR, CLDEMOTE, KL, WIDEKL, PREFETCHI 활성화가 제거됨
-mavx10.1-256, -mavx10.1-512, -mevex512는 제거되었고, -mavx10.1 behavior change warning도 함께 사라짐
AMX-TRANSPOSE 지원은 GCC 16에서 제거되었고, GCC는 더 이상 -mamx-transpose를 받지 않음
새 --enable-x86-64-mfentry configure option은 x86-64 profiling에 mcount 대신 __fentry__를 쓰는 -mfentry를 활성화하며, glibc target에서는 기본 활성화됨
--enable-tls=DIALECT는 기본 TLS dialect 제어를 지원하고, 기본값은 gnu이며 허용값은 gnu와 TLS descriptor용 gnu2임
AMD GPU, LoongArch, IBM z Systems
AMD GPU offloading에서 OpenMP target region과 OpenACC compute region launch overhead가 크게 줄어듦
AMD Instinct MI300 gfx942 device experimental 지원이 추가되었고, generic gfx9-4-generic과 대부분 호환되는 gfx950도 포함됨
AMD GPU 기본 multilib build set은 gfx908, gfx90a, gfx9-generic, gfx9-4-generic, gfx10-3-generic, gfx11-generic으로 바뀜
LoongArch는 _BitInt (N)와 unsigned _BitInt (N) 같은 bit-precise integer type을 지원함
LoongArch는 target_clones attribute로 CPU feature별 function version을 만들고 runtime에 최적 version을 자동 선택하는 FunctionMulti-Versioning을 지원함
LoongArch32 architecture 지원이 추가되어 ilp32d 기본 ABI와 ilp32f, ilp32s ABI를 포함함
표준 32-bit version LA32와 reduced 32-bit version LA32R을 모두 다루며, embedded application을 위한 32-bit target code 생성을 가능하게 함
해당 기능은 Binutils와 glibc 지원에 의존함
S/390, System z, IBM z Systems는 bit-precise integer type과 _Float16 floating-point type을 지원함
_Float16 operation은 software 또는 float instruction으로 수행됨
S/390 계열에는 Linux kernel의 canary address loading runtime patching을 지원하기 위한 global stack protector가 -mstack-protector-guard=global로 추가되었고, -mstack-protector-guard-record도 추가됨
S/390 계열의 -m31 지원은 deprecated 되었고 향후 release에서 제거될 예정임
운영체제
Solaris는 -gsctf 옵션으로 Solaris CTF, 즉 Compact C Type Format 생성을 쉽게 지원함
Windows는 native TLS, 즉 Thread-Local Storage를 지원함
활성화하려면 configure 시 --enable-tls 지정과 GNU binutils 2.44 이상이 필요함
진단, 플러그인, 정적 분석
GCC는 -fdiagnostics-add-output=experimental-html 로 HTML 형식 진단 출력 을 지원함
SARIF 출력은 dump directory 를 따르며, build-dir/foo.o 출력 예시에서는 GCC 16이 build-dir/foo.c.sarif에 SARIF를 기록함
GCC 15는 같은 예시에서 foo.c.sarif에 기록했음
SARIF 출력은 logical location nesting을 캡처하고, 많은 경우 fix object에 description property를 포함함
SARIF threadFlowLocation의 kinds property 는 비표준 control flow 표현을 위해 throw, catch, unwind, setjmp, longjmp 값을 새로 얻음
GCC diagnostics는 directed graph를 연결할 수 있고, global directed graph도 report 가능함
graph는 text sink에서는 무시되지만 SARIF sink에 캡처되며, experimental-html은 dot을 사용해 SVG 기반으로 렌더링함
SARIF 또는 HTML diagnostic sink에서 cfgs=yes를 설정하면 모든 optimization pass의 모든 function에 대한 GCC intermediate representation 캡처가 활성화됨
GCC diagnostics는 XML과 JSON file 내부의 logical location을 참조할 수 있음
sarif-replay tool은 이를 사용해 SARIF input issue report 시 JSON pointer를 제공함
GCC_DIAGNOSTICS_LOG 가 environment에 설정되면 diagnostic subsystem이 stderr 또는 named file에 text log를 내보냄
diagnostic이 정확히 언제, 왜 reject 되는지 같은 내부 결정 추적에 사용됨
EXPERIMENTAL_SARIF_SOCKET 이 environment에 설정되면 GCC는 startup 시 해당 socket에 연결을 시도하고, 발생한 모든 diagnostic에 대해 JSON-RPC notification을 보냄
Plugin author를 위해 publish/subscribe framework가 추가되어 loosely-coupled sender와 receiver 사이에서 strongly-typed message를 전달함
이번 release에서 plugin이 subscribe 가능한 topic은 특정 function의 optimization pass start/stop event와 static analyzer 관련 event뿐임
GCC diagnostic sink는 finalizer hook을 가진 extension object를 가질 수 있고, plugin은 이를 사용해 SARIF output file에 추가 정보를 캡처할 수 있음
GCC 16에서 diagnostic machinery가 크게 정리되었고, diagnostic-core.h만 쓰는 plugin에는 영향이 없어야 함
Static analyzer는 C++ Named Return Value Optimization과 exception 초기 지원을 처리해 simple C++ example에서 사용 가능함
scaling issue 때문에 이번 release에서는 production C++ code에 쓰기 어려울 가능성이 큼
-fanalyzer는 -fexceptions가 활성화된 경우 nothrow attribute가 없는 external function call이 exception을 던질 수 있다고 가정함
새 -fanalyzer-assume-nothrow 옵션은 이 가정을 비활성화함
C++ interoperability를 위해 C code에서 -fexceptions를 쓰지만 사용 중인 C API가 exception을 던질 가능성이 낮은 project의 warning 증가를 우회하는 용도임
-fanalyzer의 user code representation 자료구조는 이해와 debugging이 더 쉽도록 다시 작성되었고, diagnostic location이 약간 개선됨
대신 analyzer memory usage가 증가함
-fanalyzer의 memory contents simulation 자료구조는 다시 구현되어 더 빠르고 유지보수하기 쉬워짐
analyzer는 GCC의 value_range machinery를 사용하기 시작해 일부 false positive를 제거함
libgdiagnostics와 수정된 문제
libgdiagnostics 는 총 37개 entrypoint 를 새로 얻음
logical location 작업용 entrypoint 5개가 추가됨
command-line option과 SARIF playback 지원용 entrypoint 2개가 추가됨
directed graph 작업용 entrypoint 12개가 추가되어 graph 생성, global graph 전달, diagnostic graph 연결, node와 edge 추가·조회, node label과 location 설정을 지원함
diagnostic text를 buffer로 구성하기 위한 entrypoint 17개가 추가됨
message buffer 생성·해제, string/text/byte/printf append, event id append, URL/quote/color 범위 처리, dump, buffer 기반 diagnostic finish와 location label/event 추가를 포함함
diagnostic_manager_set_debug_physical_locations() 도 추가됨
GCC bug tracking system에서 16.1 release에 fixed로 알려진 problem report 목록은 PR list 에서 확인 가능함
해당 목록은 완전하지 않을 수 있으며, 수정된 일부 PR이 포함되지 않았을 수 있음
Homepage
Tech blog
GCC 16이 출시됨
🔉 볼륨 줄이기
🔊 볼륨 키우기
🔇 음소거
⏭️ 다음 곡