【发布时间】:2013-10-07 20:34:30
【问题描述】:
gcc 似乎对复杂的常量折叠有一些限制。这是一个例子:
static inline unsigned int DJBHash(const char *str)
{
int i;
unsigned int hash = 5381;
for(i = 0; i < strlen(str); i++)
{
hash = ((hash << 5) + hash) + str[i];
}
return hash;
}
int f(void)
{
return DJBHash("01234567890123456");
}
当以 -O3 优化级别 (gcc 4.8) 运行时,它会在 DJBHash 中很好地展开循环,并在编译期间计算该字符串的哈希值。
但是,当使字符串长一个字符return DJBHash("012345678901234567"); 时,它不再折叠它并生成一个带有条件跳转指令的循环。
我想将任意长度的文字字符串折叠为其哈希值作为编译时间常数。
这个可以吗?
澄清
我的问题是关于 gcc 的常量折叠优化(请参阅标题 - 请不要删除 gcc 和 compiler 标签) 这里的许多答案都尝试使用模板或 constexpr 来解决问题。很高兴了解这些选项,并感谢您发布它们以造福所有人。但是,他们没有直接回答我的问题。
实际上,我正在开发一个 gcc 端口,因此如果需要,我可以更改和构建 gcc 源代码。但我仅限于 C,我想在这个范围内解决这个问题。
【问题讨论】:
-
GCC 中可能有一个选项可以让您设置一些阈值,它将决定展开某些内容。不断展开是一个可能无穷无尽的过程。此外,决定展开是否会终止可能是暂停问题。
-
@Mysticial 我查看了optimization command line options,但找不到与常量折叠相关的任何内容。我尝试更改循环展开参数
max-unroll-times,但这似乎没有任何效果。 -
那么您可能无能为力。您只能依靠编译器来做很多事情。这绝对是在突破界限。在某些时候,你需要明确。也许 C++ TMP 或许能够做到。不过我不确定。
-
在 C++ 中,您可以使用
constexpr在编译时计算它 -
顺便说一句,优化器可以将
33 * hash转换为自己的移位和添加。
标签: c gcc compiler-construction compiler-optimization constantfolding