2010-10-04 62 views
6

代码复制is usually bad并且通常很容易发现。我猜想编译器可以在最简单的情况下自动检测它们 - 它们已经解析了文本并获得了以各种方式分析的中间表示 - 检测可疑模式,如未初始化的变量,优化已发布的代码等。我猜他们经常可以检测到功能重复用这种方式编码,并在发送机器码时进行解释。C++编译器能够自动消除重复的代码吗?

是否有C++编译器能够检测重复代码,并且只发送一次相应的机器代码而不是源文本中的每个副本?

+1

Lazy Man's Compiler? – Stephen 2010-10-04 13:27:26

+1

我认为这不是优化器实现者的高优先级,因为这种重复代码应该在团队经理/代码审查级别进行捕获。或者说,“良好实践”水平...... – DevSolar 2010-10-04 13:54:00

+0

@Stephen:是的。我们已经达到了编译器发出的代码足够高而不关心微优化的程度。 – sharptooth 2010-10-04 14:10:15

回答

9

有些做,有些则没有。

从LLVM优化的页面:-mergefuncMergeFunctions pass, how it works

的功能是在LLVM中间表示小块分开,这个优化过程设法合并相似的块。虽然不能保证成功。

在这个页面上你会发现很多其他的优化,尽管它们中的一些可能乍看起来很神秘。

我想补充一个不过请注意,复制代码不是编译/可执行如此糟糕,这是不好的从一个维修点,并没有什么编译器可以做些什么。

+0

即使成功,我也会认为它不能保证提高速度。当然有些人无论如何需要优化空间+1 – 2010-10-04 13:59:00

+0

有趣。我不知道它们是什么意思的“覆盖”,但你通常不能用C函数做这件事,因为相等是通过函数指针定义的。 – Potatoswatter 2010-10-04 17:40:42

+0

@jk:我同意速度可能不会提高,我认为这违背了传统的循环展开优化。但是,您可以使用LLVM框架指定您希望应用优化的顺序,因此您可以拥有两个优化。如果应用了一种启发式算法(取决于代码的大小?),它们并不精确。一方面它会跳转到另一个内存位置,另一方面,代码越少,缓存越有可能......所以我想,再次,你只需要测量自己的一小块代码:) – 2010-10-04 18:32:15

8

我认为这个问题使得编译器总是想要消除代码重复的错误假设。代码复制对源代码的可读性/可维护性不好需要编译代码的性能,实际上可以认为loop unrolling作为编译器添加重复代码以提高速度。编译后的代码不需要遵循与源代码相同的原则,并且通常不会像机器不适合人类阅读。

一般来说编译器正在忙于编译不转换源代码,当然IDEs可能同时允许。

+2

合并代码会减少生成的库/可执行文件的大小,因此它也可以加快执行速度。我同意它与循环展开有些冲突。 – 2010-10-04 13:41:23

+3

与大多数情况下存在折衷一样,但是假设编译器应该总是试图消除重复是假的 – 2010-10-04 13:43:05

+2

我没有看到这个问题在什么地方做出了这样的假设。它是问任何编译器是否这样做,而不是这是一个好主意,还是编译器能做*它总是*会做*。 – 2010-10-04 15:50:36

1

如果指定'最小代码大小'(/ O1),Visual C++会执行此操作。所提供的功能在/Og的文档中进行了描述,该文档不赞成使用更简单的全部选项来支持大小或优先速度(/ O2)。

3

据我所知,代码消除通常不会发生在函数中。所以,如果你在两个不同的函数中编写了一些重复的代码,那么很少有机会(几乎没有)会消除这段代码。

有一些优化,如return value optimizationfunction inlining可能发生跨功能。然而,大多数优化是在函数本身内完成的。这通常不是在更高级的语言级别完成的,这意味着编译器不会查看C++代码并开始优化它。编译器主要有高级语言(C++)和机器语言之间的中介表示。这种中间表示(IR)有点类似于机器语言,但并不完全是编译代码的系统的机器语言。请参阅Wiki页面http://en.wikipedia.org/wiki/Compiler_optimization,它列出了一些优化