2017-09-06 5 views
0

LLVMパスを使用してIRコードの分岐命令を削除します。LLVM Pass:IR内のすべてのブランチを削除するとエラーが発生する

以下のコードは、私の関数パス(Github)です:

virtual bool runOnFunction(Function &F) { 
    for (auto &B : F) { 
     for (auto &I : B) { 
      auto op_name = I.getOpcodeName(); 
      if(strcmp(op_name, "br")==0) { 
       I.eraseFromParent(); 
      } 
     } 
    } 
    return true; 
} 

機能パスが正常にコンパイルされていますが、私はtest.cの上でそれを使用する場合、それはPastebin

+0

私は命令を格納するために使用されているが、これはあなたが、本質的に同じコンテナを反復処理しながら、消去することにより、基本ブロック内の命令コンテナを変更しているという事実としなければならないかもしれないものの容器はかなりわかりませんか? – PaulR

答えて

0

の変更のようなエラーが発生します終了式が再評価されないため、コンテナはループベースの範囲で反復処理しても機能しません。さらに、コンテナによっては、イテレータを削除する要素に無効にすることができます。この場合、forループベースの範囲を使用することはできませんので

{ 
    auto && __range = range_expression ; 
    for (auto __begin = begin_expr, __end = end_expr; 
     // __end not reevaluated! 
     __begin != __end; ++__begin) { 

     range_declaration = *__begin; 
     loop_statement 

    } 
} 

eraseFromParentは、基本ブロックからの命令を削除します:

cppreferenceは、このようなC++ 17になるまでループに基づいて、範囲を説明しています。しかし、LLVM開発者は次の要素にイテレータを返し、ループを続けることができます。

virtual bool runOnFunction(Function &F) { 
    for (auto &B : F) { 
     auto It = B.begin() 
     // we modify B, so we must reevaluate end() 
     while(It != B.end()) { 
      auto &I = *It; 
      auto op_name = I.getOpcodeName(); 
      if(strcmp(op_name, "br")==0) { 
       // we continue with the next element 
       It = I.eraseFromParent(); 
      } else { 
       ++It; 
      } 
     } 
    } 
    return true; 
} 
関連する問題