meta: add LTO support and enable it by default

* Set -flto
* Use gcc-ar to build the archive so the LTO plugin is loaded and LTO
  sections aren't stripped off the object files
* Slightly conservative KEEP()s in the linker script (not required but
  I'm paranoid)
* Make the drivers __attribute__((externall_visible)) so they are
  generated by the link-time back-end and not left in the archive
* Remove the unused isappli/optnum parameters of main, which have been
  unused for years, are irrelevant on fx-CG and lead to a link-time
  warning with LTO. I'll add APIs to access them later.
This commit is contained in:
Lephe 2024-05-26 18:16:31 +02:00
parent ea5f21d1dc
commit 335326692f
No known key found for this signature in database
GPG key ID: 1BBA026E13FC0495
6 changed files with 24 additions and 12 deletions

View file

@ -259,7 +259,7 @@ fxconv_declare_assets(${ASSETS_FX} ${ASSETS_CG})
include_directories(
"${PROJECT_SOURCE_DIR}/include"
"${PROJECT_BINARY_DIR}/include")
add_compile_options(-Wall -Wextra -std=c11 -Os -g -fstrict-volatile-bitfields -mtas)
add_compile_options(-Wall -Wextra -std=c11 -Os -g -fstrict-volatile-bitfields -mtas -flto)
if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G)
add_compile_definitions(FX9860G)
@ -297,6 +297,12 @@ endif()
set_target_properties("${NAME}" PROPERTIES OUTPUT_NAME "${NAME}")
# Generate the archive with gcc-ar instead of ar as it will load the LTO plugin
# which is required to generate a usable archive.
set(CMAKE_C_ARCHIVE_CREATE "${CMAKE_C_COMPILER_AR} qcs <TARGET> <OBJECTS>")
# Also the ranlib rule (useless because ar is passed the s flag anyway)
set(CMAKE_C_ARCHIVE_FINISH "${CMAKE_C_COMPILER_RANLIB} <TARGET>")
# Generate linker scripts
macro(generate_linker_script OUTPUT INPUT OPTIONS)
add_custom_command(

View file

@ -61,19 +61,19 @@ SECTIONS
*(.text.entry)
_bctors = . ;
*(.ctors .ctors.*)
KEEP(*(.ctors .ctors.*))
_ectors = . ;
_bdtors = . ;
*(.dtors .dtors.*)
KEEP(*(.dtors .dtors.*))
_edtors = . ;
_gint_exch_start = . ;
*(.gint.exch)
KEEP(*(.gint.exch))
_gint_exch_size = ABSOLUTE(. - _gint_exch_start);
_gint_tlbh_start = . ;
*(.gint.tlbh)
KEEP(*(.gint.tlbh))
_gint_tlbh_size = ABSOLUTE(. - _gint_tlbh_start);
*(.text .text.*)

View file

@ -50,19 +50,19 @@ SECTIONS
*(.text.entry)
_bctors = . ;
*(.ctors .ctors.*)
KEEP(*(.ctors .ctors.*))
_ectors = . ;
_bdtors = . ;
*(.dtors .dtors.*)
KEEP(*(.dtors .dtors.*))
_edtors = . ;
_gint_exch_start = . ;
*(.gint.exch)
KEEP(*(.gint.exch))
_gint_exch_size = ABSOLUTE(. - _gint_exch_start);
_gint_tlbh_start = . ;
*(.gint.tlbh)
KEEP(*(.gint.tlbh))
_gint_tlbh_size = ABSOLUTE(. - _gint_tlbh_start);
*(.text .text.*)

View file

@ -34,6 +34,9 @@
/* Transparent unions */
#define GTRANSPARENT __attribute__((transparent_union))
/* Functions and globals that are visible through whole-program optimization */
#define GVISIBLE __attribute__((externally_visible))
/* Weak symbols */
#define GWEAK __attribute__((weak))

View file

@ -267,7 +267,7 @@ typedef void **gint_world_t;
the section name and the linker then sorts by name. If your driver has a
level lower than 10, you must add a leading 0. */
#define GINT_DECLARE_DRIVER(level, name) \
GSECTION(".gint.drivers." #level) extern gint_driver_t name;
GSECTION(".gint.drivers." #level) GVISIBLE extern gint_driver_t name;
//---
// Internal driver control

View file

@ -34,7 +34,7 @@ extern void (*bctors)(void), (*ectors)(void);
extern void (*bdtors)(void), (*edtors)(void);
/* User-provided main() function */
int main(int isappli, int optnum);
int main(void);
/* Whether to restart main through the OS menu rather than returning */
int8_t gint_restart = 0;
@ -188,7 +188,10 @@ static int start2(int isappli, int optnum)
what it wants in exit() after main() finishes executing */
if(!setjmp(gint_exitbuf)) {
callarray(&bctors, &ectors);
exit(main(isappli, optnum));
// TODO: record isappli and optnum in globals
(void)isappli;
(void)optnum;
exit(main());
}
else {
callarray(&bdtors, &edtors);