2017-09-06 10 views
0

Je souhaite supprimer les instructions de branchement dans le code IR via LLVM pass.LLVM PASS: SUPPRIMER toute la branche dans l'IR se produit erreurs

Le code ci-dessous est ma carte de fonction (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; 
} 

Le col de fonction est compilé avec succès, mais quand je l'utilise sur test.c, il se produit l'erreur comme Pastebin

+0

Je ne suis pas tout à fait sûr de ce conteneur est utilisé pour stocker des instructions, mais peut-il avoir à faire avec le fait que vous modifiez essentiellement le conteneur d'instructions dans le bloc de base en effaçant tout en itérer sur le même conteneur? – PaulR

Répondre

0

Modification un conteneur en itérant sur lui avec une plage basée sur la boucle ne fonctionnera pas, car l'expression de fin ne sera pas réévaluée. De plus, en fonction du conteneur, vous pouvez invalider l'itérateur à l'élément que vous supprimez.

cppreference explique gamme à base de boucles jusqu'à C++ 17 comme ceci:

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

     range_declaration = *__begin; 
     loop_statement 

    } 
} 

eraseFromParent supprimera l'instruction du bloc de base, de sorte que vous ne pouvez pas utiliser la gamme à base de boucle dans ce cas. Les développeurs LLVM ont cependant fait revenir un itérateur à l'élément suivant, que vous pouvez utiliser pour continuer votre boucle.

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; 
}