はい、以前のTACで修正してください。この中へ
xor c a b
:
copy c a
xor c c b
あなたが説明するように、基本的です:
私が知っている二つの主要な技術がある
は、最初はこのような書き換えはすべてシンプルです私のアイデアはまず0からcに移動し、次にcaを追加してcbを追加します
しかし、TACレベルで、ゼロ/アドの代わりにコピーすると、ゼロ/アドが変です。
ここでレジスタアロケータを実行すると、すべての2オペランド制約が自動的に満たされます。もちろん、どのような自己コピーもゼロ命令として終わります。そして、レジスタアロケータは、コピーの仮想レジスタを合体させようとすることでそれを手配することができます。コピーの大部分は避けられます。
他の方法は、基本的に同じことを行うことですが、レジスタアロケータが最初に実行されたときに合併に失敗した後に、遅延コピーを挿入します。これは、レジスタアロケータがどのように動作するかに応じて、少しトレードオフです。これは、TACサイズがほぼ倍増するのを防ぎます(そして、ほとんどのコピーを無視する命令選択に依存します)が、レジスタアロケータを2回実行します。それが遅いか速いかは、主にレジスタアロケータがどのように動作するかによって決まります。
2オペランド制約を持つ操作のソースとdestを結合し、失敗した場合はそれを受け入れ、次に制約が満たされているかどうかの異なる場合を命令セレクタに持たせることで暗黙的に行うことができます。ない。それは基本的に複雑さを命令セレクタに押しつけるものですが、それはすでに悪いので、私はそれをやりたいとは思いません。 add
は、x86、lea
上の3オペランドのバージョンを持っているので、
は私がxor
に操作を変更した - あなたはもちろん、まだコピー/優先-合体ことを行うことができ、その場合にはフラグを、必要でない限り。
'lea c、[a + b]'を使用しますが、x86では最短のコードが必ずしも最速であるとは限りません。もちろん、あなたはもちろん 'mov c、a;あなたは3つの指示は必要ありません。 PS: 'lea'はフラグを設定しないので、必要があれば使用しないでください。 – Jester