我想使用gcc编译一个针对ARM处理器的程序,并启用链接时优化。当我不使用LTO进行编译时,系统能够被编译。但是当我启用LTO(使用-flto)时,我会遇到以下汇编错误:
通过在网上查找,我发现这与我的系统中的常量有关,这些常量位于名为.rodata的特殊部分中,该部分称为常量池,并位于我的系统中的.text部分之后。似乎在使用LTO进行编译时,由于内联和其他优化,.rodata部分距离指令太远,以至于无法再寻址常量。是否可以将常量放置在使用它们的函数之后?或者是否可以使用另一种寻址模式来寻址.rodata部分?谢谢。Error: invalid literal constant: pool needs to be closer
.rodata
中。通常,它们直接放在函数后面。如果您知道这是发生在哪里的(我们需要更多上下文),我或许能够提供更好的帮助。例如,如果您没有内联汇编,则在特定有问题的函数上使用__attribute__((noinline))
。如果它在内联汇编中,则可以使用其他技术来处理它。-flto
相对较新。编译器可以定位分支(例如b 1f
)并放置文字。但是,在当前形式中,它可能只会将它们放在函数的末尾。 - artless noise-flto
选项后,您的函数将变得大于4k,并且函数的结尾不在ldr rX,[pc,#immed_12]
范围内。对于资源受限的系统,这也可能是不好的,因为内联会增加堆栈使用。如果可能,请提供有关ARM目标的更多信息(Thumb2?)。 - artless noise-finline-limit=2048
、--param max-inline-insns-auto=200
、--param max-inline-insns-single=200
等等。基本上,告诉-flto
限制函数的大小。 - artless noise