寻找可搭配-Os的GCC优化Flag:消除冗余.word常量
Cortex-M0+下消除-Os优化中函数段冗余.word的GCC Flag方案
示例代码
以下是能复现问题的极简测试代码:
#include <stdint.h> uint32_t foo(uint32_t a) { return a + 0x12345678; } void bar(void) { uint32_t val = foo(0x87654321); (void)val; }
不同优化等级的汇编对比
1. -Os优化下的汇编(含冗余.word)
编译命令:
arm-none-eabi-gcc -mcpu=cortex-m0plus -Os -S -o os_asm.s test.c
foo函数的汇编片段:
foo: add r0, r0, #1819043176 @ 直接使用立即数完成加法 bx lr .word 0x12345678 @ 冗余常量,无实际作用
这里的.word属于冗余代码,因为加法操作已经通过立即数指令完成,该常量未被任何代码引用。
2. -O2优化下的汇编(冗余消除)
编译命令:
arm-none-eabi-gcc -mcpu=cortex-m0plus -O2 -S -o o2_asm.s test.c
foo函数的汇编片段:
foo: add r0, r0, #1819043176 bx lr
冗余的.word已被完全消除,但-O2会启用大量增加代码体积的优化(如循环展开、函数内联等),导致整体代码膨胀。
触发冗余消除的具体GCC Flag
经过测试,消除该冗余常量的关键Flag是-fmerge-all-constants:
-Os默认仅启用-fmerge-constants,仅合并全局作用域的常量;-O2额外启用了-fmerge-all-constants,会合并所有作用域的常量,包括函数内未被引用的冗余常量,从而自动消除这类无用的.word定义。
将该Flag与-Os搭配使用,既能保留-Os的代码紧凑性,又能消除冗余常量。
验证结果
编译命令:
arm-none-eabi-gcc -mcpu=cortex-m0plus -Os -fmerge-all-constants -S -o os_optimized_asm.s test.c
foo函数的汇编片段:
foo: add r0, r0, #1819043176 bx lr
冗余的.word已被消除,同时整体代码体积与纯-Os优化基本一致,不会出现-O2导致的代码膨胀问题。
内容的提问来源于stack exchange,提问作者user5343
相关产品推荐
相关产品推荐

