2012-03-14 16 views
5

私は最初、私は、(i>である条件よりも大きいを比較しています%2にvairable "I" %1で、変数 "J" をロードしていますfollowintのLLVMのIRファイルにそれでLLVM IRからの基本ブロックの最初の命令の消去?

%1 = load i32* %i, align 4 
    %2 = load i32* %j, align 4 
    %3 = icmp sgt i32 %1, %2 
    br i1 %3, label %4, label %6 

; <label>:4          ; preds = %0 
    %5 = load i32* %i, align 4 
    store i32 %5, i32* %k, align 4 
    br label %6 

; <label>:6          ; preds = %5, %0 
    ret i32 0 

を持っていますj)。それに基づいて、ラベル4またはラベル6のいずれかにブランチがあります。私の問題は、変数 "i"のロード命令が第1の基本ブロックに1つと第2の基本ブロックに2つあります。ここでは、2番目のロード命令を削除したいと思います。 これは、変数 "i"の2番目のロード命令に到達したときと同じように実行されます。2番目の命令のすべての使用を最初の命令で置き換えています。次に、現在の命令すなわち2番目の命令を消去しています。ここでは、イテレータポインタを設定することができません。私は次の命令(ストアi32%5、i32 *%k、アライメント4)に設定したくありません。別の方法がありますか? ご存知の方は教えてください。

+0

ご不明な点がございましたらご質問ください。しかし、後続のパスで簡単にその負荷を取り除くことができると確信しているので、私は本当に気にしません。負荷を削除する魅力的な理由がある場合は、あなたの問題が本当に何であるかを理解することができないので、あなたの質問を再提示してください。 – CAFxX

+0

私の問題は、2番目のロード命令を削除した後、forループで命令イテレータをインクリメントするので、次の反復で(i32%5、i32 *%k、アライン4を格納する) 。 – damrudhard

+0

'inst-> eraseFromParent()'の直後に 'BB-> begin()'をもう一度呼び出すだけで、新しいイテレータを取得するのはなぜですか? – CAFxX

答えて

10

私が正しく理解しているのであれば、命令を消去してコードを繰り返し処理するだけです。そうです場合は、(lib/Transforms/Scalar/DCE.cppに住んでいる)DeadInstElimintationパスからこの例を見てみましょう:

virtual bool runOnBasicBlock(BasicBlock &BB) { 
    bool Changed = false; 
    for (BasicBlock::iterator DI = BB.begin(); DI != BB.end();) { 
    Instruction *Inst = DI++; 
    if (isInstructionTriviallyDead(Inst)) { 
     Inst->eraseFromParent(); 
     Changed = true; 
     ++DIEEliminated; 
    } 
    } 
    return Changed; 
} 

注意する興味深いのは、イテレータをインクリメントする方法です。 DI++は、forの最後の句の内部ではなく、別々に、現在のDIInstに割り当てられています。これにより、Instを削除しても、DIが既に次の命令を指しているので、ループは次の命令で実行され続けます。

+0

私はCAFxXから解決策を得ました。あなたも助けてくれてありがとう。 – damrudhard

+0

@damrudhard:新しいイテレータを 'BB-> begin()'に設定するのは、新しい命令が基本ブロックの最初の命令である場合にのみ機能します。それ以外の場合は、いくつかの手順に戻ります。これがあなたと問題なければ問題ありません。私の答えに示されている解決策はもっと一般的だと思います。 –

+0

それ以外の場合は、命令イテレータを前の命令に設定して、次の反復で削除された命令の直後の命令 を指すようにします。 – damrudhard

関連する問題