Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable Link Time Optimisation #3824

Draft
wants to merge 3 commits into
base: 0_15
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 24 additions & 0 deletions pio-scripts/lto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Import('env')
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a short comment here why this script exists and what it does on a high level (I assume it replaces some parts of the linker with another that supports LTO?)


env.Replace(AR=env['AR'].replace('elf-ar', 'elf-gcc-ar'))
env.Replace(RANLIB=env['RANLIB'].replace('elf-ranlib', 'elf-gcc-ranlib'))

# Something later clobbers AR & RANLIB, so until https://github.com/platformio/platform-espressif32/pull/1329
# is available, wrap the replace function to protect them

# Save a reference to the original env.Replace()
original_replace = env.Replace

def create_replace_wrapper(env):
def replace_wrapper(**kw):
if 'AR' in kw:
kw.pop("AR")
if 'RANLIB' in kw:
kw.pop("RANLIB")

original_replace(**kw)

return replace_wrapper

# Replace the env.Replace with the wrapper
env.Replace = create_replace_wrapper(env)
12 changes: 10 additions & 2 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ platform_packages = platformio/framework-arduinoespressif8266
# esp8266 : see https://docs.platformio.org/en/latest/platforms/espressif8266.html#debug-level
# esp32 : see https://docs.platformio.org/en/latest/platforms/espressif32.html#debug-level
# ------------------------------------------------------------------------------
# Enabling debug? You might want to disable LTO to avoid call stacks being squashed through inlining
debug_flags = -D DEBUG=1 -D WLED_DEBUG
-DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_TLS_MEM ;; for esp8266
# if needed (for memleaks etc) also add; -DDEBUG_ESP_OOM -include "umm_malloc/umm_malloc_cfg.h"
Expand Down Expand Up @@ -103,11 +104,16 @@ build_flags =
-D DECODE_LG=true
-DWLED_USE_MY_CONFIG

lto_flags =
-flto

build_unflags =
-fno-lto

# No LTO for ESP8266 as we overflow IRAM
build_flags_esp8266 = ${common.build_flags} ${esp8266.build_flags}
build_flags_esp32 = ${common.build_flags} ${esp32.build_flags}
build_flags_esp32_V4= ${common.build_flags} ${esp32_idf_V4.build_flags}
build_flags_esp32 = ${common.build_flags} ${esp32.build_flags} ${common.lto_flags}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are no longer present in current platformio.ini so LTO flags should be moved into appropriate [esp32xx] sections.
I would also create environment (or better just flags) for debug builds. Enabling all debug flags (as specified in [common] section) will no longer link successfully when using anything but plain binary.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

platformio.ini.gz

This is the path I've been going down. I'll rebase against whatever the current development branch is when I get back to it.

Basically, every platform will have a normal (undecorated) and debug environment, with (LTO|None) or DEBUG flags applied as appropriate for the platform.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider this when making base environments:

[env:wemos_d1_mini32]
board = esp32dev
platform = ${esp32.platform}
;board_build.f_flash = 80000000L  # does not work on every ESP
board_build.flash_mode = qio
board_build.partitions = ${esp32.default_partitions}
board_build.filesystem = littlefs
monitor_filters = esp32_exception_decoder
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=WEMOS32
;  -D WLED_DISABLE_HUESYNC
;  -D WLED_DISABLE_LOXONE
;  -D WLED_DISABLE_ALEXA
  -D WLED_DISABLE_BROWNOUT_DET
  -D WLED_NTP_ENABLED=true
  -D WLED_TIMEZONE=2
  -D WLED_LAT=45.8
  -D WLED_LON=15.17
  -D LEDPIN=16
  -D RLYPIN=19
  -D BTNPIN=17
  -D IRPIN=18
  -D USERMOD_DALLASTEMPERATURE
  -D TEMPERATURE_PIN=23
  -D USERMOD_FOUR_LINE_DISPLAY
  -D USERMOD_PIRSWITCH
  -D PIR_SENSOR_PIN=26
  -D PIR_SENSOR_OFF_SEC=60
  -D PIR_SENSOR_MAX_SENSORS=2
  -D USERMOD_MULTI_RELAY
  -D MULTI_RELAY_MAX_RELAYS=3
  -D USERMOD_AUDIOREACTIVE
  -D DMTYPE=1     # 0-analog/disabled, 1-I2S generic, 2-ES7243, 3-SPH0645, 4-I2S+mclk, 5-I2S PDM
  -UWLED_USE_MY_CONFIG
lib_deps = ${esp32.lib_deps}
  olikraus/U8g2 # @~2.33.15
  paulstoffregen/OneWire@~2.3.8
  Wire
  ${esp32.AR_lib_deps}

[env:wemos_d1_mini32_debug]
extends = env:wemos_d1_mini32
extra_scripts = ${env.extra_scripts}
  replace_fs.py
build_flags = ${common.build_flags} ${esp32.build_flags}
;  -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue ;; this adds approximately 99k to the binary size
; DEBUG reserves GPIO1
  -D WLED_DEBUG
;  -D WLED_DEBUG_HOST='"192.168.x.x"'
;  -D WLED_DEBUG_MATH
;  -D WLED_USE_UNREAL_MATH
;  -D WLED_USE_ETHERNET
;  -D WLED_ETH_DEFAULT=5
;  -D WLED_DISABLE_MQTT
;  -D WLED_DISABLE_INFRARED
  -D WLED_DISABLE_ALEXA
  -D WLED_DISABLE_HUESYNC
  -D WLED_DISABLE_LOXONE
;  -D WLED_DISABLE_MODE_BLEND
;  -D WLED_ENABLE_DMX
;  -D WLED_ENABLE_PIXART
;  -D WLED_DISABLE_PXMAGIC
;  -D WLED_DISABLE_WEBSOCKETS
;  -D WLED_DISABLE_2D
  -D WLED_AP_SSID_UNIQUE
  -D WLED_NTP_ENABLED=true
  -D WLED_TIMEZONE=2
  -D WLED_LAT=45.8
  -D WLED_LON=15.17
;  -D LEDPIN=16
  -D DATA_PINS=16,3
  -D PIXEL_COUNTS=30,30
  -D RLYPIN=19
  -D BTNPIN=17
  -D IRPIN=18
;  -D WLED_MAX_BUTTONS=12
;  -D USERMOD_SHT
  -D USERMOD_DALLASTEMPERATURE
  -D TEMPERATURE_PIN=23
  -D USERMOD_FOUR_LINE_DISPLAY
  -D USERMOD_ROTARY_ENCODER_UI # 33,34,35
  -D ENCODER_DT_PIN=33
  -D ENCODER_CLK_PIN=34
  -D ENCODER_SW_PIN=35
;  -D USERMOD_AUTO_SAVE
;  -D AUTOSAVE_AFTER_SEC=90
;  -D USERMOD_ANIMATED_STAIRCASE
  -D USERMOD_PIRSWITCH
  -D PIR_SENSOR_PIN=36
  -D PIR_SENSOR_OFF_SEC=60
  -D PIR_SENSOR_MAX_SENSORS=2
  -D USERMOD_MULTI_RELAY  # 14, 15, 32
  -D MULTI_RELAY_MAX_RELAYS=2
;  -D MULTI_RELAY_PINS=14,15
;  -D USERMOD_PWM_FAN
;  -D USERMOD_BOBLIGHT
;  -D USERMOD_POWER_AP
  -D USERMOD_AUDIOREACTIVE
  -D AUDIOPIN=-1  # analog pin
  -D DMTYPE=1     # 0-analog/disabled, 1-I2S generic, 2-ES7243, 3-SPH0645, 4-I2S+mclk, 5-I2S PDM
  -D I2S_SDPIN=4
  -D I2S_WSPIN=32
  -D I2S_CKPIN=12
;  -D STATUSLED=2
  -D WLED_WATCHDOG_TIMEOUT=10
  -D WLED_DISABLE_BROWNOUT_DET
;  -D ABL_MILLIAMPS_DEFAULT=0
  -UWLED_USE_MY_CONFIG

These are my daily build environments for ESP32 that I often change wile testing WLED. I have similar environments for 8266, S2, S3 and C3, Ethernet, WROVER models and many exotic boards that I received for testing.

build_flags_esp32_V4= ${common.build_flags} ${esp32_idf_V4.build_flags} ${common.lto_flags}

ldscript_1m128k = eagle.flash.1m128.ld
ldscript_2m512k = eagle.flash.2m512.ld
Expand All @@ -121,6 +127,7 @@ extra_scripts =
post:pio-scripts/strip-floats.py
pre:pio-scripts/user_config_copy.py
pre:pio-scripts/build_ui.py
pre:pio-scripts/lto.py

# ------------------------------------------------------------------------------
# COMMON SETTINGS:
Expand Down Expand Up @@ -198,6 +205,7 @@ build_flags =
; decrease code cache size and increase IRAM to fit all pixel functions
-D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48 ;; in case of linker errors like "section `.text1' will not fit in region `iram1_0_seg'"
; -D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED ;; (experimental) adds some extra heap, but may cause slowdown


lib_deps =
#https://github.com/lorol/LITTLEFS.git
Expand Down
2 changes: 2 additions & 0 deletions wled00/wled00.ino
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
*/
#include "wled.h"

void setup() __attribute__((used));
void setup() {
WLED::instance().setup();
}

void loop() __attribute__((used));
void loop() {
WLED::instance().loop();
}