diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2015-04-27 14:47:19 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-05-19 02:46:27 +0000 |
commit | 2650ff3d70c9933e4c3dcd1401ca66b4426def4a (patch) | |
tree | 7a4658b060d3439a525a7562c226358d55424035 | |
parent | cb29daa58c0fa5866a7847c454967ef0376c7688 (diff) | |
download | chrome-ec-2650ff3d70c9933e4c3dcd1401ca66b4426def4a.tar.gz |
Add option to enable GCC LTO
Add CONFIG_LTO to use GCC Link-Time Optimizations to try to reduce the
flash footprint of the firmware.
Add additional protection to some functions/data to avoid removal by the
linker when their usage is not obvious.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BRANCH=none
BUG=none
TEST=make buildall (with and without LTO enable on all boards)
Change-Id: I586b8c1eda4592b416c85383b65153c1d5ab0059
Reviewed-on: https://chromium-review.googlesource.com/271291
Trybot-Ready: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Commit-Queue: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | Makefile.toolchain | 2 | ||||
-rw-r--r-- | board/zinger/runtime.c | 2 | ||||
-rw-r--r-- | chip/mec1322/watchdog.c | 2 | ||||
-rw-r--r-- | chip/npcx/watchdog.c | 2 | ||||
-rw-r--r-- | chip/stm32/gpio.c | 2 | ||||
-rw-r--r-- | chip/stm32/hwtimer.c | 2 | ||||
-rw-r--r-- | chip/stm32/hwtimer32.c | 2 | ||||
-rw-r--r-- | common/clz.c | 4 | ||||
-rw-r--r-- | common/main.c | 2 | ||||
-rw-r--r-- | common/version.c | 4 | ||||
-rw-r--r-- | core/cortex-m/build.mk | 5 | ||||
-rw-r--r-- | core/cortex-m/irq_handler.h | 1 | ||||
-rw-r--r-- | core/cortex-m/panic.c | 4 | ||||
-rw-r--r-- | core/cortex-m/task.c | 6 | ||||
-rw-r--r-- | core/cortex-m/watchdog.c | 2 | ||||
-rw-r--r-- | core/cortex-m0/atomic.h | 2 | ||||
-rw-r--r-- | core/cortex-m0/build.mk | 5 | ||||
-rw-r--r-- | core/cortex-m0/panic.c | 4 | ||||
-rw-r--r-- | core/cortex-m0/task.c | 2 | ||||
-rw-r--r-- | include/common.h | 10 | ||||
-rw-r--r-- | include/config.h | 3 | ||||
-rw-r--r-- | include/console.h | 4 | ||||
-rw-r--r-- | include/hooks.h | 2 | ||||
-rw-r--r-- | include/host_command.h | 2 |
24 files changed, 51 insertions, 25 deletions
diff --git a/Makefile.toolchain b/Makefile.toolchain index 8beb7b2c0f..f875751115 100644 --- a/Makefile.toolchain +++ b/Makefile.toolchain @@ -55,7 +55,7 @@ LIBFTDI_LDLIBS=$(shell $(PKG_CONFIG) --libs lib${LIBFTDI_NAME}) BUILD_CFLAGS= $(LIBFTDI_CFLAGS) $(CPPFLAGS) -O3 $(CFLAGS_DEBUG) $(CFLAGS_WARN) HOST_CFLAGS=$(CPPFLAGS) -O3 $(CFLAGS_DEBUG) $(CFLAGS_WARN) -DHOST_TOOLS_BUILD -LDFLAGS=-nostdlib -Wl,-X -Wl,--gc-sections -Wl,--build-id=none +LDFLAGS=-nostdlib -Wl,-X -Wl,--gc-sections -Wl,--build-id=none $(LDFLAGS_EXTRA) BUILD_LDFLAGS=$(LIBFTDI_LDLIBS) HOST_TEST_LDFLAGS=-T core/host/host_exe.lds -lrt -pthread -rdynamic -lm\ $(if $(TEST_COVERAGE),-fprofile-arcs,) diff --git a/board/zinger/runtime.c b/board/zinger/runtime.c index 0dfb51aed4..f2b40cbfd9 100644 --- a/board/zinger/runtime.c +++ b/board/zinger/runtime.c @@ -216,7 +216,7 @@ uint32_t task_wait_event(int timeout_us) return evt; } -void cpu_reset(void) +void __keep cpu_reset(void) { /* Disable interrupts */ asm volatile("cpsid i"); diff --git a/chip/mec1322/watchdog.c b/chip/mec1322/watchdog.c index 3d6c4fc89c..c547b79911 100644 --- a/chip/mec1322/watchdog.c +++ b/chip/mec1322/watchdog.c @@ -73,7 +73,7 @@ int watchdog_init(void) } #ifdef CONFIG_WATCHDOG_HELP -void watchdog_check(uint32_t excep_lr, uint32_t excep_sp) +void __keep watchdog_check(uint32_t excep_lr, uint32_t excep_sp) { /* Clear status */ MEC1322_TMR16_STS(0) |= 1; diff --git a/chip/npcx/watchdog.c b/chip/npcx/watchdog.c index f72be3cb7b..036a768bb6 100644 --- a/chip/npcx/watchdog.c +++ b/chip/npcx/watchdog.c @@ -45,7 +45,7 @@ void watchdog_init_warning_timer(void) task_enable_irq(ITIM16_INT(ITIM_WDG_NO)); } -void watchdog_check(uint32_t excep_lr, uint32_t excep_sp) +void __keep watchdog_check(uint32_t excep_lr, uint32_t excep_sp) { int wd_cnt; /* Clear timeout status for event */ diff --git a/chip/stm32/gpio.c b/chip/stm32/gpio.c index d58ce29328..683303688f 100644 --- a/chip/stm32/gpio.c +++ b/chip/stm32/gpio.c @@ -115,7 +115,7 @@ int gpio_enable_interrupt(enum gpio_signal signal) /*****************************************************************************/ /* Interrupt handler */ -void gpio_interrupt(void) +void __keep gpio_interrupt(void) { int bit; /* process only GPIO EXTINTs (EXTINT0..15) not other EXTINTs */ diff --git a/chip/stm32/hwtimer.c b/chip/stm32/hwtimer.c index a1053e28c8..2658cf5734 100644 --- a/chip/stm32/hwtimer.c +++ b/chip/stm32/hwtimer.c @@ -372,7 +372,7 @@ int __hw_clock_source_init(uint32_t start_t) #ifdef CONFIG_WATCHDOG_HELP -void watchdog_check(uint32_t excep_lr, uint32_t excep_sp) +void __keep watchdog_check(uint32_t excep_lr, uint32_t excep_sp) { struct timer_ctlr *timer = (struct timer_ctlr *)TIM_WD_BASE; diff --git a/chip/stm32/hwtimer32.c b/chip/stm32/hwtimer32.c index e04f540d04..ef6e9321c4 100644 --- a/chip/stm32/hwtimer32.c +++ b/chip/stm32/hwtimer32.c @@ -189,7 +189,7 @@ int __hw_clock_source_init(uint32_t start_t) #define IRQ_WD IRQ_TIM(TIM_WATCHDOG) -void watchdog_check(uint32_t excep_lr, uint32_t excep_sp) +void __keep watchdog_check(uint32_t excep_lr, uint32_t excep_sp) { /* clear status */ STM32_TIM_SR(TIM_WATCHDOG) = 0; diff --git a/common/clz.c b/common/clz.c index 30c987e367..456683b0cd 100644 --- a/common/clz.c +++ b/common/clz.c @@ -5,6 +5,8 @@ * Software emulation for CLZ instruction */ +#include "common.h" + /** * Count leading zeros * @@ -12,7 +14,7 @@ * @return the number of leading 0-bits in x, * starting at the most significant bit position. */ -int __clzsi2(int x) +int __keep __clzsi2(int x) { int r = 0; diff --git a/common/main.c b/common/main.c index f30f2970cd..a2f86abdee 100644 --- a/common/main.c +++ b/common/main.c @@ -33,7 +33,7 @@ #define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) #define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) -test_mockable int main(void) +test_mockable __keep int main(void) { /* * Pre-initialization (pre-verified boot) stage. Initialization at diff --git a/common/version.c b/common/version.c index b6cc8e1d8b..331f155571 100644 --- a/common/version.c +++ b/common/version.c @@ -11,14 +11,14 @@ #include "ec_version.h" #include "version.h" -const struct version_struct version_data +const struct version_struct __keep version_data __attribute__((section(".rodata.ver"))) = { CROS_EC_VERSION_COOKIE1, CROS_EC_VERSION32, CROS_EC_VERSION_COOKIE2 }; -const char build_info[] __attribute__((section(".rodata.buildinfo"))) = +const char build_info[] __keep __attribute__((section(".rodata.buildinfo"))) = CROS_EC_VERSION " " DATE " " BUILDER; uint32_t ver_get_numcommits(void) diff --git a/core/cortex-m/build.mk b/core/cortex-m/build.mk index 522f6dedeb..5724a9ba39 100644 --- a/core/cortex-m/build.mk +++ b/core/cortex-m/build.mk @@ -17,6 +17,11 @@ CFLAGS_CPU+=-mthumb -Os -mno-sched-prolog CFLAGS_CPU+=-mno-unaligned-access CFLAGS_CPU+=$(CFLAGS_FPU-y) +ifneq ($(CONFIG_LTO),) +CFLAGS_CPU+=-flto +LDFLAGS_EXTRA+=-flto +endif + core-y=cpu.o init.o ldivmod.o uldivmod.o core-$(CONFIG_COMMON_PANIC_OUTPUT)+=panic.o core-$(CONFIG_COMMON_RUNTIME)+=switch.o task.o diff --git a/core/cortex-m/irq_handler.h b/core/cortex-m/irq_handler.h index 2b49de15e1..602c3245e4 100644 --- a/core/cortex-m/irq_handler.h +++ b/core/cortex-m/irq_handler.h @@ -24,6 +24,7 @@ #define DECLARE_IRQ(irq, routine, priority) DECLARE_IRQ_(irq, routine, priority) #define DECLARE_IRQ_(irq, routine, priority) \ void IRQ_HANDLER(irq)(void) __attribute__((naked)); \ + void __keep routine(void); \ void IRQ_HANDLER(irq)(void) \ { \ asm volatile("mov r0, lr\n" \ diff --git a/core/cortex-m/panic.c b/core/cortex-m/panic.c index 6b81e8c484..0d484bf1d0 100644 --- a/core/cortex-m/panic.c +++ b/core/cortex-m/panic.c @@ -302,7 +302,7 @@ void panic_data_print(const struct panic_data *pdata) #endif } -void report_panic(void) +void __keep report_panic(void) { struct panic_data *pdata = pdata_ptr; uint32_t sp; @@ -352,7 +352,7 @@ void report_panic(void) * * Declare this as a naked call so we can extract raw LR and IPSR values. */ -void exception_panic(void) __attribute__((naked)); +void __keep exception_panic(void) __attribute__((naked)); void exception_panic(void) { /* Save registers and branch directly to panic handler */ diff --git a/core/cortex-m/task.c b/core/cortex-m/task.c index 69b92d5de8..342fcdcf39 100644 --- a/core/cortex-m/task.c +++ b/core/cortex-m/task.c @@ -284,7 +284,7 @@ void __schedule(int desched, int resched) } #ifdef CONFIG_TASK_PROFILING -void task_start_irq_handler(void *excep_return) +void __keep task_start_irq_handler(void *excep_return) { /* * Get time before checking depth, in case this handler is @@ -312,7 +312,7 @@ void task_start_irq_handler(void *excep_return) } #endif -void task_resched_if_needed(void *excep_return) +void __keep task_resched_if_needed(void *excep_return) { /* * Continue iff a rescheduling event happened or profiling is active, @@ -414,7 +414,7 @@ void task_enable_irq(int irq) CPU_NVIC_EN(irq / 32) = 1 << (irq % 32); } -void task_disable_irq(int irq) +void __keep task_disable_irq(int irq) { CPU_NVIC_DIS(irq / 32) = 1 << (irq % 32); } diff --git a/core/cortex-m/watchdog.c b/core/cortex-m/watchdog.c index 8366f48d0a..229009330e 100644 --- a/core/cortex-m/watchdog.c +++ b/core/cortex-m/watchdog.c @@ -12,7 +12,7 @@ #include "uart.h" #include "watchdog.h" -void watchdog_trace(uint32_t excep_lr, uint32_t excep_sp) +void __keep watchdog_trace(uint32_t excep_lr, uint32_t excep_sp) { uint32_t psp; uint32_t *stack; diff --git a/core/cortex-m0/atomic.h b/core/cortex-m0/atomic.h index 8ba1b66739..62bc2ff370 100644 --- a/core/cortex-m0/atomic.h +++ b/core/cortex-m0/atomic.h @@ -23,7 +23,7 @@ #asm_op" %0, %0, %2\n" \ " str %0, [%1]\n" \ " cpsie i\n" \ - : "=&r" (reg0) \ + : "=&b" (reg0) \ : "b" (a), "r" (v) : "cc"); \ } while (0) diff --git a/core/cortex-m0/build.mk b/core/cortex-m0/build.mk index c87df856e0..5f2bc32eb5 100644 --- a/core/cortex-m0/build.mk +++ b/core/cortex-m0/build.mk @@ -13,6 +13,11 @@ CROSS_COMPILE?=arm-none-eabi- CFLAGS_CPU+=-mthumb -Os -mno-sched-prolog CFLAGS_CPU+=-mno-unaligned-access +ifneq ($(CONFIG_LTO),) +CFLAGS_CPU+=-flto +LDFLAGS_EXTRA+=-flto +endif + core-y=cpu.o init.o thumb_case.o div.o lmul.o ldivmod.o uldivmod.o core-$(CONFIG_COMMON_PANIC_OUTPUT)+=panic.o core-$(CONFIG_COMMON_RUNTIME)+=switch.o task.o diff --git a/core/cortex-m0/panic.c b/core/cortex-m0/panic.c index 2ba22c6998..cb347054ea 100644 --- a/core/cortex-m0/panic.c +++ b/core/cortex-m0/panic.c @@ -104,7 +104,7 @@ void panic_data_print(const struct panic_data *pdata) print_reg(15, sregs, 6); } -void report_panic(void) +void __keep report_panic(void) { struct panic_data *pdata = pdata_ptr; uint32_t sp; @@ -139,7 +139,7 @@ void report_panic(void) * * Declare this as a naked call so we can extract raw LR and IPSR values. */ -void exception_panic(void) __attribute__((naked)); +__keep void exception_panic(void) __attribute__((naked)); void exception_panic(void) { /* Save registers and branch directly to panic handler */ diff --git a/core/cortex-m0/task.c b/core/cortex-m0/task.c index ffdbe49595..d26a82b6d2 100644 --- a/core/cortex-m0/task.c +++ b/core/cortex-m0/task.c @@ -181,7 +181,7 @@ int task_start_called(void) /** * Scheduling system call */ -task_ *__svc_handler(int desched, task_id_t resched) +task_ __attribute__((noinline)) *__svc_handler(int desched, task_id_t resched) { task_ *current, *next; #ifdef CONFIG_TASK_PROFILING diff --git a/include/common.h b/include/common.h index 59e66b7f29..af451a3ec9 100644 --- a/include/common.h +++ b/include/common.h @@ -58,6 +58,16 @@ #define __packed __attribute__((packed)) #endif +/* + * Force the toolchain to keep a symbol even with Link Time Optimization + * activated. + * + * Useful for C functions called only from assembly or through special sections. + */ +#ifndef __keep +#define __keep __attribute__((used)) __attribute__((externally_visible)) +#endif + /* There isn't really a better place for this */ #define C_TO_K(temp_c) ((temp_c) + 273) #define K_TO_C(temp_c) ((temp_c) - 273) diff --git a/include/config.h b/include/config.h index 36c1b3f53a..53232410ac 100644 --- a/include/config.h +++ b/include/config.h @@ -970,6 +970,9 @@ /* Support LPC interface */ #undef CONFIG_LPC +/* Use Link-Time Optimizations to try to reduce the firmware code size */ +#undef CONFIG_LTO + /* Presence of a Bosh Sensortec BMM150 magnetometer behind a BMI160. */ #undef CONFIG_MAG_BMI160_BMM150 diff --git a/include/console.h b/include/console.h index ee6897821d..00036d3632 100644 --- a/include/console.h +++ b/include/console.h @@ -134,13 +134,13 @@ void console_has_input(void); #ifdef CONFIG_CONSOLE_CMDHELP #define DECLARE_CONSOLE_COMMAND(name, routine, argdesc, shorthelp, longhelp) \ static const char __con_cmd_label_##name[] = #name; \ - const struct console_command __con_cmd_##name \ + const struct console_command __keep __con_cmd_##name \ __attribute__((section(".rodata.cmds." #name))) \ = {__con_cmd_label_##name, routine, argdesc, shorthelp} #else #define DECLARE_CONSOLE_COMMAND(name, routine, argdesc, shorthelp, longhelp) \ static const char __con_cmd_label_##name[] = #name; \ - const struct console_command __con_cmd_##name \ + const struct console_command __keep __con_cmd_##name \ __attribute__((section(".rodata.cmds." #name))) \ = {__con_cmd_label_##name, routine} #endif diff --git a/include/hooks.h b/include/hooks.h index 15ab778c5b..f5a728d8e1 100644 --- a/include/hooks.h +++ b/include/hooks.h @@ -231,7 +231,7 @@ int hook_call_deferred(void (*routine)(void), int us); * order in which hooks are called. */ #define DECLARE_HOOK(hooktype, routine, priority) \ - const struct hook_data CONCAT4(__hook_, hooktype, _, routine) \ + const struct hook_data __keep CONCAT4(__hook_, hooktype, _, routine) \ __attribute__((section(".rodata." STRINGIFY(hooktype)))) \ = {routine, priority} diff --git a/include/host_command.h b/include/host_command.h index f95fe06966..2667cb9a27 100644 --- a/include/host_command.h +++ b/include/host_command.h @@ -209,7 +209,7 @@ void host_packet_receive(struct host_packet *pkt); /* Register a host command handler */ #define DECLARE_HOST_COMMAND(command, routine, version_mask) \ - const struct host_command __host_cmd_##command \ + const struct host_command __keep __host_cmd_##command \ __attribute__((section(".rodata.hcmds"))) \ = {routine, command, version_mask} |