私は趣味でコンパイル済み言語を書いていますが、最近、最適化コンパイラを非常に堅牢にすることに熱中しています。たとえば、2 + 2 は常に 4 であるため、コンパイル時にその計算を行うことができ、if(false){ ... } を完全に削除することができます。ループになってしまいました。いくつかの調査の後、私がやろうとしていることは正確にはループ展開ではないと思いますが、それでも最適化手法です。説明させてください。
次のコードを取ります。
String s = "";
for(int i = 0; i < 5; i++){
s += "x";
}
output(s);
人間として、私はここに座って、これが 100% の確率で
output("xxxxx");
つまり、このループは完全に「コンパイル」することができます。これはループ展開ではありませんが、私が「完全に静的」と呼んでいるもの、つまり、セグメントの動作を変更する入力はありません。私の考えでは、完全に静的なものはすべて単一の値に解決でき、入力に依存するものや条件付き出力を作成するものはもちろん、それ以上最適化することはできません。では、マシンの観点からは、何を考慮する必要があるでしょうか? ループを「完全に静的」にするのは何ですか?
分類方法を理解する必要がある 3 種類のループを考え出しました。入力に関係なく、毎回の実行後に常に同じマシン状態で終了するループ、決して完了しないループ、およびどちらか一方を理解できないループ。私がそれを理解できない場合(動的入力に基づいて実行回数が条件付きで変更されます)、最適化について心配することはありません。無限のループは、プログラマーが特に抑制しない限り、コンパイル エラー/警告になります。毎回同じループは、ループせずに、マシンを適切な状態にするために直接スキップする必要があります。
もちろん、最適化する主なケースは、内部のすべての関数呼び出しも静的である静的ループの反復です。ループに動的コンポーネントがあるかどうかを判断するのは簡単です。動的でない場合は、静的でなければならないと思います。私が理解できないのは、それが無限になるかどうかを検出する方法です。誰もこれについて何か考えがありますか?これが停止問題のサブセットであることはわかっていますが、解決可能だと感じています。停止の問題は、プログラムの一部のサブセットについては、それが永久に実行される可能性があるかどうかを判断できないという事実による問題です。どこで停止するか、どこで停止しないかですが、最初に 3 つの状態を区別する必要があります。