【发布时间】:2012-05-01 03:43:05
【问题描述】:
我正在编写一种编译语言来取乐,而我最近开始努力使我的优化编译器变得非常健壮。我已经想出了几种优化某些东西的方法,例如,2 + 2 总是 4,所以我们可以在编译时进行数学运算, if(false){ ... } 可以完全删除等等,但是现在我已经开始循环了。经过一些研究,我认为我正在尝试做的并不是完全循环展开,但它仍然是一种优化技术。让我解释一下。
获取以下代码。
String s = "";
for(int i = 0; i < 5; i++){
s += "x";
}
output(s);
作为一个人类,我可以坐在这里告诉你,这 100% 的时间都相当于
output("xxxxx");
所以,换句话说,这个循环可以完全“编译”出来。这不是循环展开,而是我所说的“完全静态”,也就是说,没有输入会改变段的行为。我的想法是,任何完全静态的东西都可以解析为单个值,任何依赖输入或产生条件输出的东西当然不能进一步优化。那么,从机器的角度来看,我需要考虑什么?是什么让循环“完全静态”?
我想出了三种类型的循环,我需要弄清楚如何分类。每次运行后总是以相同的机器状态结束的循环,无论输入如何,循环永远不会完成,以及我无法找出一种或另一种方式的循环。在我无法弄清楚的情况下(它有条件地根据动态输入改变它将运行的次数),我不担心优化。除非程序员明确禁止,否则无限循环将是编译错误/警告,并且每次都相同的循环应该直接跳过以使机器处于正确状态,而不是循环。
当然要优化的主要情况是静态循环迭代,此时内部的所有函数调用也是静态的。确定循环是否具有动态组件很容易,如果它不是动态的,我想它必须是静态的。我无法弄清楚的是如何检测它是否会是无限的。有人对此有任何想法吗?我知道这是停机问题的一个子集,但我觉得它是可以解决的;停止问题是一个问题,因为对于某些程序子集,您不能说它可能会永远运行,也可能不会,但我不想考虑这些情况,我只想考虑这些情况它会在哪里停止,或者它不会停止,但首先我必须区分这三种状态。
【问题讨论】:
-
要了解目前这一行实际支持的内容,您可能需要阅读新 C++ 标准中对
constexpr的限制。 -
如果你可以静态判断循环条件始终为真,并且没有其他方法可以退出循环,那么你就知道循环不会终止。
-
在您的示例中,您不一定知道 String s 也不会被另一个通过 extern 引用它并在并行线程中修改它的文件修改。
-
来自维基百科的@JerryCoffin:“函数体不能声明变量”。这排除了大多数循环。我想知道这是由于理论限制还是实际限制。我觉得还有一部分问题仍然可以通过编程方式检测和解决,因此应该如此。
-
for(int i = 0; i < 5; i--){}在我看来并不是无限的,除非你有奇怪的不换行的整数。无论如何,检测“简单案例”很容易,那么您想走多远呢?
标签: optimization language-agnostic compiler-construction theory