Nios® II Software Developer Handbook

ID 683525
Date 8/28/2023
Public
Document Table of Contents

7.13.1. Enable Compiler Optimizations

A number of nios2-elf-gcc compiler switches may be of use when optimizing code for small RAM footprints. These switches may be set directly on the compiler command line (typically in a Makefile, in the CFLAGS definition) or by the BSP GUI editor settings.
  • -fno-delete-null-pointer-checks: (IMPORTANT!) You should always set this switch if your design includes valid data at address zero. If you do not, nios2-elf-gcc may silently produce incorrect code, since the C standard specifies that a NULL pointer must never be dereferenced. GCC v. 4.9 is particularly prone to this.
  • -Os: This is the most important compiler switch when optimizing for space. This instructs nios2-elf-gcc to pervasively optimize for space rather than speed. (But you may wish to use -Og when debugging. This generates code easier to understand in the debugger.)
  • -fno-exceptions: If you are coding a small RAM footprint program in C++ (risky, because C++ tends to add unwanted overhead) and attempting to avoid linking in C++ exception handling code to save space, this switch can dissuade nios2-elf-g++ from linking in the exception handling code "just to be safe" in cases where it is not sure whether exception handling is needed.
  • -mgpopt=global: This switch improves code in both space and speed relative to the -mgpopt=local default. You should always use -mgpopt=global unless you using different -Gn compile switch settings for different compilation units, which should seldom if ever be the case.
  • -mgpopt=data: This improves code in both space and speed relative to -mgpopt=global if all of your data fits in 64 KB of address space, which is often the case for small embedded projects. You may need to edit your linker script to ensure that _gp is defined to be 32 KB beyond the start of your 64 KB of data. (You may use the "-Wl,-verbose" compiler switch to display your current linker script and the "-T" compiler switch to specify a different linker script.)
  • -gpopt=all: This improved code in both space and speed relative to "-mgpopt=data" if all of your data AND code fit in 64 KB of address space. As above, you may need to modify your linker script to set _gp to be 32 KB beyond the start of your 64 KB of combined code and data.
  • -ffunction-sections: This places each function in a separate code section in the .o file, making it possible for ld to produce smaller executables by not linking in unused functions. This results in larger .o files (due to the increased number of code section headers) and in slower links (since ld must process the increased number of code section headers) but that is rarely an issue on contemporary machines.
  • -ffunction-sections: As above, but placing each global data item in its own .o file section.