| commit | f9d07890640434a4be0e7f651dd295478598b36d | [log] [tgz] |
|---|---|---|
| author | Qiongsi Wu <274595+qiongsiwu@users.noreply.github.com> | Thu Oct 17 09:32:10 2024 -0400 |
| committer | GitHub <noreply@github.com> | Thu Oct 17 09:32:10 2024 -0400 |
| tree | 2ff0908cf14a8d25ea523a74940ec7efeea31b8c | |
| parent | 3f17da1f45dfcafebff1ef7fba031eae86ce1720 [diff] |
[PGO] Initialize GCOV Writeout and Reset Functions in the Runtime on AIX (#108570) This PR registers the writeout and reset functions for `gcov` for all modules in the PGO runtime, instead of registering them using global constructors in each module. The change is made for AIX only, but the same mechanism works on Linux on Power. When registering such functions using global constructors in each module without `-ffunction-sections`, the AIX linker cannot garbage collect unused undefined symbols, because such symbols are grouped in the same section as the `__sinit` symbol. Keeping such undefined symbols causes link errors (see test case https://github.com/llvm/llvm-project/pull/108570/files#diff-500a7e1ba871e1b6b61b523700d5e30987900002add306e1b5e4972cf6d5a4f1R1 for this scenario). This PR implements the initialization in the runtime, hence avoiding introducing `__sinit` into each module. The implementation adds a new global variable `__llvm_covinit_functions` to each module. This new global variable contains the function pointers to the `Writeout` and `Reset` functions. `__llvm_covinit_functions`'s section is the named section `__llvm_covinit`. The linker will aggregate all the `__llvm_covinit` sections from each module to form one single named section in the final binary. The pair of functions ``` const __llvm_gcov_init_func_struct *__llvm_profile_begin_covinit(); const __llvm_gcov_init_func_struct *__llvm_profile_end_covinit(); ``` are implemented to return the start and end address of this named section in the final binary, and they are used in function ``` __llvm_profile_gcov_initialize() ``` (which is a constructor function in the runtime) so the runtime knows the addresses of all the `Writeout` and `Reset` functions from all the modules. One noticeable implementation detail relevant to AIX is that to preserve the `__llvm_covinit` from the linker's garbage collection, a `.ref` pseudo instruction is inserted into them, referring to the section that contains the `__llvm_gcov_ctr` variables, which are used in the instrumented code. The `__llvm_gcov_ctr` variables did not belong to named sections before, but this PR added them to the `__llvm_gcov_ctr_section` named section, so we can add a `.ref` pseudo instruction that refers to them in the `__llvm_covinit` section.
Welcome to the LLVM project!
This repository contains the source code for LLVM, a toolkit for the construction of highly optimized compilers, optimizers, and run-time environments.
The LLVM project has multiple components. The core of the project is itself called “LLVM”. This contains all of the tools, libraries, and header files needed to process intermediate representations and convert them into object files. Tools include an assembler, disassembler, bitcode analyzer, and bitcode optimizer.
C-like languages use the Clang frontend. This component compiles C, C++, Objective-C, and Objective-C++ code into LLVM bitcode -- and from there into object files, using LLVM.
Other components include: the libc++ C++ standard library, the LLD linker, and more.
Consult the Getting Started with LLVM page for information on building and running LLVM.
For information on how to contribute to the LLVM project, please take a look at the Contributing to LLVM guide.
Join the LLVM Discourse forums, Discord chat, LLVM Office Hours or Regular sync-ups.
The LLVM project has adopted a code of conduct for participants to all modes of communication within the project.