2

プリプロセッサと定数の伝播と簡単なコード分析を経て、 Cコードを取得したいと考えています。これが私の言いたいことです。

gcc の-Eオプションを使用して、プリプロセッサの後にコードを取得します。ただし、取得しているコードは非常に理解しにくく、ローカル定数の伝播を単純にパスするだけで、はるかに読みやすくなります。以下は、プリプロセッサによって生成された1 行の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 に答える