编译器优化理论中的 CSE vs GVN

CSE vs GVN in compiler optimization theory

当我读第 11 讲时,我有一个问题,Common Subexpression Elimination, of Advanced Compilers umass amherst 课程。

问题是,在第11讲第12页,它说明了值编号不能消除所有子表达式。

    read(i);
    l = 2*i;
    if(i > 0) goto L1;
    j = 2*i;
    goto L2;
L1: k = 2*i;
L2:  

解释是:l的值并不总是等于j或k的值

令我疑惑的是,所有(l / j / k)的值都依赖于 2*i ,i的值编号在所有基本块中应该是相同的,因为没有对 i 进行任何赋值或重新定义示例代码片段。正确吗?

如果正确,2*i也将得到相同的值编号,j和k的冗余2*i计算可以成功消除。

我画错了吗?如果你找到了,请帮我解决一下。

你的两个假设都是正确的。 i 的值编号和随后的 2*i 的值编号在 read(i) 之后的整个函数中将相同。因此,在分配jk时,2*i的计算是多余的,在这两种情况下都可以用l代替。