如何让RISC-V32的clang/lld避免对同地址范围重复生成lui指令?
RISC-V独立程序编译优化:多内存范围下消除冗余lui指令问题
我正在为RISC-V内核编写独立程序,需要对两个不相邻的内存范围(一个是RAM,另一个是外设,后续可能新增更多)执行大量读写操作,但编译生成的汇编代码存在大量冗余的lui指令。
问题示例
C代码如下:
a=40; b=80; c=0;
编译后得到的汇编代码为:
lui a0, 0x1 li a1, 0x28 sw a1, 0x2c(a0) lui a0, 0x1 li a2, 0x50 sw a2, 0x30(a0) lui a0, 0x1 sw zero, 0x34(a0)
这段代码连续3次用lui将地址0x1000加载到a0寄存器,且期间未修改a0(也无其他跳转进入该段),理想情况是首次加载后保留基地址,无需重复执行lui。
已尝试的单范围解决方案
我曾通过在clang配置中添加--for-linker --relax-gp选项,结合链接文件和启动代码设置全局指针(参考SiFive的《Global Pointer指南》)解决了单内存范围的问题,此时C代码a=40;会被编译为:
li a1, 0x28 sw a1, -0x7d4(gp)
疑问
但我的场景中存在第二个与RAM数据地址范围不相邻的内存范围,请问:
- 是否可让clang/lld支持第二个全局指针?
- 若涉及更多内存范围,无法用全局指针占用所有寄存器,是否有选项可让clang/lld在函数/中断内尽量保留基地址寄存器直至必要时再修改?
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

