From 11d99f315d405ca5d6930576eb44f278d97e789c Mon Sep 17 00:00:00 2001 From: Vladimir Smitka Date: Sun, 20 Sep 2026 17:14:16 +0000 Subject: [PATCH 1/2] raspberrypi: build with -O2 plus the two -O3 flags that measure The port default was -O3. Measured flag by flag on a raspberry_pi_pico (RP2040) and a Fruit Jam (RP2350), two of what -O3 adds over -O2 move a benchmark; the rest costs flash and wins nothing. -funswitch-loops +16 KB. Hoists a loop-invariant test out of the loop and keeps one body per value. Gives the -O3 numbers on a flipped sprite blit (23 %) and a textured floor (9 %), and 1-2 % on bitmaptools.alphablend and ulab reductions. -fvect-cost-model=dynamic +4 KB. -O2 uses very-cheap, which rejects nearly every loop; dynamic lets the vectorizer unroll memset, memcpy and a 16-bit row fill. Gives the -O3 numbers on rectangle fills and bytearray copies (37 %) and on aesio (16 %). A run shorter than its alignment prologue loses: a four-pixel span fill is 7 % slower. The other four -O3 loop passes tried (-fpredictive-commoning, -fgcse-after-reload, -ftree-partial-pre, -fsplit-paths) emit the same code as -O2 for the loops that matter and cost -168 to +2376 bytes. The rest of -O3 is 130 KB, 92 KB of it the inline parameters, and no column moves under it. The bytecode interpreter does not move under any flag: py/py.mk builds gc.o and vm.o at -O3 whatever this is set to. RP2040, raspberry_pi_pico, microseconds per call: -O2 pair -O3 blit_flip 113 87 87 mode7 5915 5413 5406 fill_rect 1163 732 739 fill_circle 322 245 243 4 KB copy 3857 2441 2435 AES 4 KB 17248 14508 13543 vspans 3703 3945 3807 text +0 +20664 +151020 RP2350, Fruit Jam with PSRAM off so the buffers sit in SRAM, three rounds: pair -O3 fill_circle 136 135 vspans 1666 1652 triangles 1221 1212 fill_rect 490 490 blit565 44 44 blit_flip 43 45 mode7 2623 2639 text 849004 971752 With PSRAM on, a 4 KB copy and fill, an integer loop, fib(20), bignum, aesio, alphablend, rotozoom, fill_region, three ulab calls and an mbedtls sha256 are all within 0.25 % of -O3. So the pair is 130 KB smaller on RP2040 and 123 KB smaller on RP2350 at the same speed, and one setting covers the port. pajenicko_picopad and pimoroni_picosystem drop their board copies of the earlier five-pass set, which would otherwise pin it with =. Boards that set -O2 or -Os keep their setting. --- ports/raspberrypi/Makefile | 5 ++++- ports/raspberrypi/boards/pajenicko_picopad/mpconfigboard.mk | 5 ----- .../raspberrypi/boards/pimoroni_picosystem/mpconfigboard.mk | 4 ---- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/ports/raspberrypi/Makefile b/ports/raspberrypi/Makefile index 6348dc941f7..13499baf0f7 100755 --- a/ports/raspberrypi/Makefile +++ b/ports/raspberrypi/Makefile @@ -217,7 +217,10 @@ CFLAGS += \ -DPICO_NO_BI_BOOTSEL_VIA_DOUBLE_RESET=0 \ -DDVI_1BPP_BIT_REVERSE=0 -OPTIMIZATION_FLAGS ?= -O3 +# -O2 plus the two -O3 flags that measure: -funswitch-loops (16 KB) carries the sprite +# blits, -fvect-cost-model=dynamic (4 KB) the fills and memcpy. Same speed as -O3 on both +# cores for about 125 KB less flash. Boards may override this in mpconfigboard.mk. +OPTIMIZATION_FLAGS ?= -O2 -funswitch-loops -fvect-cost-model=dynamic # TinyUSB defines CFLAGS += \ -DCFG_TUSB_OS=OPT_OS_PICO \ diff --git a/ports/raspberrypi/boards/pajenicko_picopad/mpconfigboard.mk b/ports/raspberrypi/boards/pajenicko_picopad/mpconfigboard.mk index b5df0e6ecb5..03a203dc2de 100644 --- a/ports/raspberrypi/boards/pajenicko_picopad/mpconfigboard.mk +++ b/ports/raspberrypi/boards/pajenicko_picopad/mpconfigboard.mk @@ -50,8 +50,3 @@ CFLAGS += \ # Must be accompanied by a linker script change CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(1536 * 1024)' - -# The rp2 port default is -O3; on this Cortex-M0+ (no SIMD/FPU, 16 KB XIP cache) -O2 plus -# these five loop passes measures within +-1% of -O3 across the picogame render kernels -# while using ~150 KB less flash (gc.o/vm.o stay -O3 via SUPEROPT regardless). -OPTIMIZATION_FLAGS = -O2 -funswitch-loops -fpredictive-commoning -fgcse-after-reload -ftree-partial-pre -fsplit-paths diff --git a/ports/raspberrypi/boards/pimoroni_picosystem/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_picosystem/mpconfigboard.mk index 28a3c6a641a..38ee11df70b 100644 --- a/ports/raspberrypi/boards/pimoroni_picosystem/mpconfigboard.mk +++ b/ports/raspberrypi/boards/pimoroni_picosystem/mpconfigboard.mk @@ -18,7 +18,3 @@ CIRCUITPY_PICOGAME_FAST_DISPLAY = 1 CIRCUITPY_AUDIOIO = 1 FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/picosystem - -# The default is -O3. picogame does not fit at -O3; these loop passes keep the render -# kernels within 1% of it. -OPTIMIZATION_FLAGS = -O2 -funswitch-loops -fpredictive-commoning -fgcse-after-reload -ftree-partial-pre -fsplit-paths From 77221943bef0dda55d69af5b3ff4964be2110a22 Mon Sep 17 00:00:00 2001 From: Vladimir Smitka Date: Sun, 20 Sep 2026 17:14:29 +0000 Subject: [PATCH 2/2] raspberry_pi_pico, raspberry_pi_pico_w: enable picogame Neither fits at -O3: pico had 48 KB free of its 1020 KB partition and pico_w 2 KB of its 1536 KB, while the engine needs 50 KB. With the port flags pico has 153 KB free and pico_w 148 KB (en_US build). --- ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.mk | 4 ++++ ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.mk | 3 +++ 2 files changed, 7 insertions(+) diff --git a/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.mk b/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.mk index 20607d50e41..c53ddbbd7e4 100644 --- a/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.mk +++ b/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.mk @@ -9,4 +9,8 @@ CHIP_FAMILY = rp2 EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" CIRCUITPY__EVE = 1 + +CIRCUITPY_PICOGAME = 1 +CIRCUITPY_PICOGAME_FAST_DISPLAY = 1 + CIRCUITPY_PICODVI = 1 diff --git a/ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.mk b/ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.mk index e658db65f4d..bb7a9208899 100644 --- a/ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.mk +++ b/ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.mk @@ -12,6 +12,9 @@ CIRCUITPY_USB_HOST = 0 CIRCUITPY__EVE = 1 +CIRCUITPY_PICOGAME = 1 +CIRCUITPY_PICOGAME_FAST_DISPLAY = 1 + CIRCUITPY_CYW43 = 1 CIRCUITPY_SSL = 1 CIRCUITPY_HASHLIB = 1