有没有办法告诉GCC参数的范围?

时间:2017-06-23 14:32:06

标签: gcc optimization

我有一些使用频繁的代码,我希望GCC能够积极优化。但我还想编写干净,可重用的代码,其中包含从几个地方调用的(无限)函数。在内联函数中,有些情况下我知道可以删除代码,因为条件永远不会发生。

让我们看一个具体的例子:

#include <assert.h>

static inline int foo(int c)
{
  if (c < 4)
    return c;
  else
    return 4;
}

int bar(int c)
{
  assert(c < 2);

  return foo(c);
}

使用-DNDEBUG -O3,GCC仍会生成(c <4)比较,即使我知道不需要它,因为bar函数的前提是c是0或1.如果没有-DNDEBUG,GCC 会删除比较,因为它是断言所隐含的 - 但当然你有断言的开销(这是更多)。

有没有办法将变量范围传达给GCC,以便可以用于优化?

如果CLang能做得更好,我也可以考虑转换编译器。

1 个答案:

答案 0 :(得分:2)

您可以在测试中使用__builtin_unreachable(阅读other builtins)来告诉编译器,例如

if (x<2 || x>100) __builtin_unreachable();
// here the compiler knows that x is between 3 and 99 inclusive

在您的情况下,在bar开头添加(可能包含在一些漂亮的宏中):

if (c >= 2) __builtin_unreachable();

如果强烈优化(例如至少-O2),编译器知道 x介于3和99之间(并且最近的GCC包含进行此类分析的代码 - 至少处理简单的常数区间约束,如上所述 - 并在以后的优化过程中利用它们。)

但是,我不太确定你应该使用它! (至少不要经常使用它并将其包装在某些assert - 就像宏),因为它可能不值得麻烦,因为编译器实际上只能处理和传播简单的约束(其详细信息是特定于编译器版本的)。

AFAIK最近的Clang和GCC都接受了内置。

同时查看__builtin_trap(也会发出运行时代码)。