2016-10-28 14 views
1

実行時にある命令の値をチェックしたい。したがって、私はcompare命令と、 "then"基本ブロックまたは "else"基本ブロックのどちらかに分岐する分岐命令を作成します。しかし、私は、条件付きブランチの後に作成された基本ブロックをどのように挿入できるか、および既存の基本ブロックの分割がどのように機能するかはわかりません。既存の基本ブロックにif/elseを挿入する

Instruction* someInst; 
IRBuilder<> B(someInst); 

Value* condition = B.CreateICmp(CmpInst::ICMP_UGT, someInst, someValue); 

BasicBlock* thenBB = BasicBlock::Create(*ctx, "then"); 
BasicBlock* elseBB = BasicBlock::Create(*ctx, "else"); 

B.CreateCondBr(condition, thenBB, elseBB); 

B.SetInsertPoint(thenBB); 
//insert stuff 

B.SetInsertPoint(elseBB); 
//insert stuff 

if/elseを既存の基本ブロックの中央に挿入するにはどうすればよいですか?

答えて

4

短い回答:おそらくllvm::SplitBlockAndInsertIfThenElseを使用できます。あなたのPHIノードを忘れないでください。ウィキペディア、basic blockによれば

は、出口以外はエントリなし枝を除いでない枝を有する直線コード配列です。

アンされたif-then-elseしたがって、いくつかのブロックが含まれます。

  1. 条件が含まれているブロック、
  2. その後、
  3. 必要に応じて、後のブロックをブロックし、他の
  4. をブロックthenブロックとelseブロック(そうでなければ、他のブロックに戻るか分岐しない場合)。

if-then-elseを挿入するには、元の基本ブロックを(1)と(4)に分割する必要があります。条件チェックと条件分岐は(1)に進み、(2)と(3)は(4)に分岐して終了します。 SplitBlockAndInsertIfThenElse関数(docs)は簡単な場合にこれを行います。複雑な要件がある場合(独自の制御フローが含まれている場合など)、自分で分割する必要があります。

thenまたはelseブロックで変数を変更する場合は、PHIノードが必要です。 Kaleidoscope tutorialは、PHIノードが必要な理由とその使用方法を説明しています。このチュートリアルでは、便利な背景であるSingle Static Assignment Wikipediaの記事を参照しています。

+0

すべての場合で 'SplitBlockAndInsertIfThenElse'で十分です。両方の新しいブロックのターミネータへのポインタを返します。挿入ポイントとしてこれらのブロックを使用して、必要な制御フローを含め、必要な指示を挿入できます。 –

+0

私は誤解していますか? –

+0

SplitBlockAndInsertIfThenElseによって作成されたthenブロックおよびelseブロックには、終了分岐命令があります。有効な基本ブロックには、その分岐先の分岐命令(制御フロー)が含まれていないか、誤解されていますか? –

関連する問題