2

我想在经过预处理器常量传播和简单的代码分析后得到C代码。这就是我的意思。

我使用 gcc 的-E选项在预处理器之后获取代码。然而,我得到的代码真的很难理解,一个简单的局部常量传播将使它更容易阅读。这是预处理器生成的仅一行C代码的示例。

(b1[0] = (kp + 1 * 4)[0] ^ 
( t_fn[0][(((( 0 == 0 ? ( 0 == 0 ? b0[0] : 0 == 1 ? b0[1] : 0 == 2 ? b0[2] : b0[3]) : 0 == 1 ? ( 0 == 0 ? b0[1] : 0 == 1 ? b0[2] : 0 == 2 ? b0[3] : b0[0]) : 0 == 2 ? ( 0 == 0 ? b0[2] : 0 == 1 ? b0[3] : 0 == 2 ? b0[0] : b0[1]) : ( 0 == 0 ? b0[3] : 0 == 1 ? b0[0] : 0 == 2 ? b0[1] : b0[2]))) >> (8 * ((0)))) & 0xff)] 
^ t_fn[1][(((( 1 == 0 ? ( 0 == 0 ? b0[0] : 0 == 1 ? b0[1] : 0 == 2 ? b0[2] : b0[3]) : 1 == 1 ? ( 0 == 0 ? b0[1] : 0 == 1 ? b0[2] : 0 == 2 ? b0[3] : b0[0]) : 1 == 2 ? ( 0 == 0 ? b0[2] : 0 == 1 ? b0[3] : 0 == 2 ? b0[0] : b0[1]) : ( 0 == 0 ? b0[3] : 0 == 1 ? b0[0] : 0 == 2 ? b0[1] : b0[2]))) >> (8 * ((1)))) & 0xff)] 
^ t_fn[2][(((( 2 == 0 ? ( 0 == 0 ? b0[0] : 0 == 1 ? b0[1] : 0 == 2 ? b0[2] : b0[3]) : 2 == 1 ? ( 0 == 0 ? b0[1] : 0 == 1 ? b0[2] : 0 == 2 ? b0[3] : b0[0]) : 2 == 2 ? ( 0 == 0 ? b0[2] : 0 == 1 ? b0[3] : 0 == 2 ? b0[0] : b0[1]) : ( 0 == 0 ? b0[3] : 0 == 1 ? b0[0] : 0 == 2 ? b0[1] : b0[2]))) >> (8 * ((2)))) & 0xff)] 
^ t_fn[3][(((( 3 == 0 ? ( 0 == 0 ? b0[0] : 0 == 1 ? b0[1] : 0 == 2 ? b0[2] : b0[3]) : 3 == 1 ? ( 0 == 0 ? b0[1] : 0 == 1 ? b0[2] : 0 == 2 ? b0[3] : b0[0]) : 3 == 2 ? ( 0 == 0 ? b0[2] : 0 == 1 ? b0[3] : 0 == 2 ? b0[0] : b0[1]) : ( 0 == 0 ? b0[3] : 0 == 1 ? b0[0] : 0 == 2 ? b0[1] : b0[2]))) >> (8 * ((3)))) & 0xff)]));

0 == 0 ? X : Y并且 8*2可以很容易地转换为更简单的形式。现在我的代码中有很多这样的行,这真是令人头疼。因此,如果我可以通过简单的局部常量传播和代码分析来获得更简单的C代码,那该多好?

4

2 回答 2

3

我所知道的任何 C 编译器都无法做到这一点。常量传播通常发生在将内部表示转换回 C 已经太迟之后。

于 2012-10-10T00:07:51.960 回答
3

为此,您需要一个基本上可以在源代码级别执行代码优化的工具。编译器在这里不会帮助您,因为编译器通常不会在源代码级别优化代码。任何代码转换通常发生在很久以后,当源代码不再相关并且真的没有办法回到它时。

换句话说,您需要专门设计的工具来解决您的问题。我不知道有任何这样的工具,我怀疑它是否存在。

于 2012-10-10T00:08:20.003 回答