我希望在完成预处理器 AND 常量传播和简单代码分析后获得 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 代码,那会很棒吗?
答案 0 :(得分:3)
对于我所知道的任何C编译器,都无法做到这一点。恒定传播通常发生在将内部表示转换回C之后已经太晚了。
答案 1 :(得分:2)
为此你需要一个基本上可以在源代码级别执行代码优化的工具。编译器在这里没有帮助,因为编译器通常不会在源代码级别优化代码。任何代码转换通常都会在很晚的时候发生,当源代码不再相关时,实际上无法回复它。
换句话说,您需要一个专门用于解决问题的工具。我不知道任何这样的工具,我怀疑它是否存在。