2017-09-06 157 views
0

我想通过LLVM通过删除IR代码中的分支指令。LLVM通过:删除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

修改错误一个容器在迭代时使用基于循环的范围将不起作用,因为结束表达式不会被重新评估。此外,根据容器,您可能会使迭代器无效到要删除的元素。

cppreference解释为基于循环,直到C++ 17这样的范围:

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

     range_declaration = *__begin; 
     loop_statement 

    } 
} 

eraseFromParent将基本块删除指令,所以你不能使用基于在这种情况下,循环的范围内。然而,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; 
}