Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有办法告诉GCC参数的范围?_Gcc_Optimization - Fatal编程技术网

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

有没有办法告诉GCC参数的范围?,gcc,optimization,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

我有一些大量使用的代码,我希望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);
}
#包括
静态内联intfoo(intc)
{
if(c<4)
返回c;
其他的
返回4;
}
整型条(整型c)
{
断言(c<2);
返回foo(c);
}
使用
-DNDEBUG-O3
,GCC仍然会生成(c<4)比较,即使我知道它是不需要的,因为
bar
函数的先决条件是
c
为0或1。如果没有
-DNDEBUG
,GCC确实会删除比较,因为它是由断言暗示的-但是当然,您会有断言的开销(这要多得多)

是否有办法将变量范围传达给GCC,以便用于优化


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

< P>你可以在测试中使用<代码>
if (x<2 || x>100) __builtin_unreachable();
// here the compiler knows that x is between 3 and 99 inclusive
如果您进行了强优化(例如,
-O2
至少),编译器会知道x介于3和99之间(最近的GCC包含进行此类分析的代码-至少处理上述简单的常量间隔约束-并在以后的优化过程中利用它们)

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

AFAIK最近的Clang和GCC都接受这种内置模式


还可以查看
\uuuu内置陷阱(它也会发出运行时代码)。

Clang 4.0/Zapcc比GCC 7.1-4指令略好一些,而不是x64上的5指令,但它们都不够聪明,无法选择退出foo的
c<4
。你可以用不同的编译器来检查这个问题,我检查过的编译器中没有一个能够优化这个问题(这是有意义的)。理想情况下,在bar中指定c的范围会有一些神奇的pragma,但我认为还没有人想出这样的pragma。。。或者可能是一些智能断言内置,它可以从生成的代码中删除自身,但会被优化器识别。@Mike:这些断言只是一个示例,我只删除第一个,因为它在这里不相关(不用于优化)。@valiano:的确,智能断言是我要找的。GIMPLE(GCC的内部表示)跟踪可变范围,这就是它如何在存在资产的情况下优化(c<4)。我想用一种方法来显式地表达这样的范围,而不仅仅是让编译器来做分析。您可以将其包装在宏中:
#define-ASSUME(COND)do{if(!(COND))uu-builtin\u-unreachable();},而(0)
工作起来很有魅力!但是,你为什么说不要使用它?
if (c >= 2) __builtin_unreachable();