【问题标题】:Hint the C compiler (GCC or Clang) of possible variable value/range [duplicate]提示可能的变量值/范围的 C 编译器(GCC 或 Clang)[重复]
【发布时间】:2020-06-13 22:28:00
【问题描述】:

在下面的代码中,只会做一个比较,因为编译器知道条件是互斥的,我们总是会输入第二个条件,因为bar是必要的> 32:

int foo(int bar) {
    if (bar <= 64)
        return 1;
    if (bar > 32) {
        printf("Too many elements");
    }
    return 0;
}

现在,假设我知道bar 总是高于64。因为系统的输入、配置或其他原因。我如何提示编译器根本不进行比较,例如 if (bar &lt;= 64) return 是否已编译,但它实际上并未保存在最终 ASM 中。

类似:

int foo(int bar) {
    @precond(bar > 64);
    if (bar > 32) {
        printf("Too many elements");
    }
    return 0;
}

是我写 LLVM 通行证的唯一解决方案吗?

【问题讨论】:

  • 有什么用? IMO X-Y 问题。
  • 我认为这里不需要详细说明,它是用于高速网络优化的。根据预测的输入专门化代码。我稍微改变了问题,使其更清晰并说明输入。
  • 我觉得你可以使用GCC的__builtin_expect:blog.man7.org/2012/10/how-much-do-builtinexpect-likely-and.html
  • 感谢@ForceBru,但这只是一个提示,会保留分支。它只会确保最可能的代码不在跳转路径上。我想删除跳转部分。我想 __builtin_enforced 也许:p
  • 请注意,写通行证真的非常简单。

标签: c gcc clang llvm


【解决方案1】:

您可以在 GCC 中使用__builtin_unreachable:

if (bar > 32) {
  __builtin_unreachable();
}

__builtin_assume 在 Clang 中:

__builtin_assume(bar <= 32);

和 MSVC 中的 __assume:

__assume(bar <= 32);

【讨论】:

  • 是的,它有效!我用 gcc -S 验证了,没有比较了。
  • 也许我遗漏了一些明显的东西,但是您的两个示例似乎相反:GCC 示例声明 bar &lt;= 32 是 false,而 MSVC 示例声明bar &lt;= 32 是 true。没有?
  • @ruakh 哎呀!固定。
  • 在clang中你应该使用__builtin_assume,即使__builtin_unreachable可用——后者不会导致优化器省略代码,但前者会。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-21
  • 2017-10-17
  • 2014-12-04
  • 1970-01-01
  • 2015-09-12
  • 2021-08-02
相关资源
最近更新 更多