Other Parts Discussed in Thread: C2000-CGT, C2000WARE
主题: C2000WARE 中讨论的其他器件
工具/软件:
我想知道当前版本的 C2000-CGT 是否能够进行尾调用优化。 编译器手册没有提到这一点、但似乎在 C 编译器中找到了足够普遍的优化。
我找到的这篇文章表明至少有非常旧的 C2000-CGT 版本能够优化尾部递归调用: 在 cmath 中使用 modf (float、float*) 会产生无限循环 — Code Composer Studio 论坛 — Code Composer Studio︎ — TI E2E 支持论坛
然而,我的问题不是针对尾部递归函数(我们的代码库中没有任何相关的函数),而是针对一般的尾调用优化——即发射 LB 而不是 LCR; LRETR。
我们以以下 C 函数为例简单说明:
__attribute__((ramfunc)) static void tx0(void) {
set_low();
DEVICE_DELAY_US(10);
set_high();
DEVICE_DELAY_US(5);
}
device_delay_US 扩展到从 C2000Ware (F2838x) 对 SysCtl_delay 的调用。 生成的汇编代码 (C2000-CGT 22.6.2.LTS、--silicon_version=28 --abi=eabi --unified_memory --cla_support=cla2 --float_support=fpu64 --idiv_support=idiv0 --tmu_support=tmu0 --vcu_support=vcrc - opt_level=4 --float_sperelax_debug - optime_proc_relaxed - op_debug - opt_prec11-op_debug - op_debug - optime-comprelax_debug -
如下所示:
LCR set_low
MOV ACC, #398
LCR SysCtl_delay
LCR set_high
MOVB ACC, #198
LCR SysCtl_delay
LRETR
我天真地希望将最后两行替换为LB SysCtl_delay将产生功能等效的代码、但返回后会节省 4 个 CPU 周期。 考虑到有意长时间的延迟、这在特定示例中当然无关紧要、但希望能得到正确答案。 可以分享其他示例、但可能需要 进行一定程度的手动编辑、以避免发布任何专有 IP 的风险。
由于被调用函数被内联、但非内联调用站点会保留、因此在使用-O4 链接期间、为我们代码生成的汇编代码中的一些情况会被消除。 这还包括间接调用(即 LCR *XARn;LRETR)、我假设该调用可与 LB *XAR7 类似地替换。
这让我想知道:启用尾调用优化是否需要任何特定的编译标志? 相反、已知是否有禁止它的标志? 或者、C2000 编译器通常不能进行尾调用优化?