高级/语义优化

时间:2009-08-27 19:02:11

标签: language-agnostic optimization static-analysis

我正在编写一个编译器,我正在寻找有关优化的资源。我正在编译机器代码,因此运行时的任何事情都是不可能的。

我最近一直在寻找的是更少的代码优化和更多的语义/高级优化。例如:

free(malloc(400)); // should be completely optimized away

即使这些函数完全内联,它们最终也可以调用永远不会内联的OS内存函数。我希望能够完全消除该语句而不在编译器中构建特殊情况规则(毕竟,malloc只是另一个函数)。

另一个例子:

string Parenthesize(string str) {
    StringBuilder b; // similar to C#'s class of the same name
    foreach(str : ["(", str, ")"])
        b.Append(str);
    return b.Render();
}

在这种情况下,我希望能够将b的容量初始化为str.Length + 2(足以完全保留结果,而不会浪费内存)。

说实话,我不知道从哪里开始解决这个问题,所以我希望能在某个地方开始。是否在类似领域做过任何工作?是否有任何编译器在一般意义上实现了类似的东西?

2 个答案:

答案 0 :(得分:2)

要在2个或更多操作中进行优化,您必须了解 这两种操作的代数关系。如果您查看操作 在他们的问题领域,他们经常有这样的关系。

你的免费(malloc(400))是可能的,因为free和malloc是反转的 在存储分配域中。 许多操作都反转并教导编译器它们是反转的, 并证明一个数据流的结果无条件地进入另一个, 是需要的。你必须确保你的反转真的是逆 并且某处并不出人意料; a / x * x看起来就像值a, 但如果x为零,你会得到一个陷阱。如果你不关心陷阱,那就是反过来; 如果您关心陷阱,那么优化会更复杂:       (如果(x == 0)则陷阱()否则a) 如果你认为差别很大,这仍然是一个很好的优化。

其他“代数”关系也是可能的。例如,有 可以是幂等操作:将变量归零(将任何内容设置为相同 重复的值)等。有一个操作数作用的操作 像一个身份元素; X + 0 ==> X为任何0.如果X和0是矩阵, 这仍然是真的,节省了很多时间。

当您可以抽象地说明代码的内容时,可能会发生其他优化 是在做。 “抽象解释”是一套推理技巧 通过将结果分类为各种有趣的箱(例如,该整数)来获得值 是未知的,零,负面或正面的)。要做到这一点,你需要决定什么 bin很有用,然后计算每个点的抽象值。这很有用 当对类别进行测试时(例如,“if(x <0){...”并且您知道 抽象地说x小于零;你可以优化条件。

另一种方法是定义计算正在做什么,并模拟计算以查看结果。这就是你计算所需缓冲区有效大小的方法;你在循环开始之前象征性地计算了缓冲区大小, 并模拟了对所有迭代执行循环的效果。 为此,您需要能够构造符号公式 代表程序属性,组成这样的公式,并经常简化 当这些公式变得非常复杂时(这些公式逐渐淡化为抽象 解释方案)。你也想要这样的符号计算 考虑我上面描述的代数性质。这样做的工具擅长构建公式,程序转换系统通常是这方面的良好基础。一个源到源程序转换系统,可用于执行此操作 是DMS Software Reengineering Toolkit

决定哪些优化值得做是很困难的,因为你可以结束 跟踪大量的东西,这可能无法获得回报。电脑周期 越来越便宜,因此在编译器中跟踪代码的更多属性是有意义的。

答案 1 :(得分:1)

Broadway框架可能与您正在寻找的内容紧密相关。关于“源到源转换”的论文可能也很有启发性。