Я пишу модуль модуля оптимизации LLVM, и я хочу, чтобы иметь возможность восстановить исходную функцию, если мне не нравятся результаты. Так что я написал ModulePass следующую базовую структуру:CloneFunction затем заменит оригинальную функцию клонированным в LLVM opt pass
while(cloneAndTryAgain){
ValueToValueMapTy vmap;
Function *F_clone = CloneFunction(F, vmap, true);
.... trying out things on F
if(cloneAndTryAgain){ //not happy with changes to F
//replace F with clone
replaceCurrentFunction(F, F_clone);
F_clone = NULL;
}
}
Однако после запуска replaceCurrentFunction (..), я пытаюсь напечатать F, но я получаю Segfault. Что-то не так с F после попытки заменить его клоном.
replaceCurrentFunction(..)
выглядит следующим образом:
void replaceCurrentFunction(Function *F, Function *F_clone) {
Module *M = F->getParent();
// New function will take the name of the current function.
F_clone->takeName(F);
// Insert new function right next to current function.
M->getFunctionList().insert(F, F_clone);
// Erase current function.
F->eraseFromParent();
// The new function is now the current function.
F = F_clone;
}
Вот выдаёт ошибку сегментации и трассировки стека:
Program received signal SIGSEGV, Segmentation fault.
(anonymous namespace)::SlotTracker::SlotTracker (this=0x7fffffff94b0, F=0x1b) at AsmWriter.cpp:438
438 mNext(0), fNext(0), mdnNext(0) {
#0 (anonymous namespace)::SlotTracker::SlotTracker (this=0x7fffffff94b0, F=0x1b) at AsmWriter.cpp:438
#1 0x00007ffff63c66dc in llvm::Value::print (this=0x6d4a30, ROS=..., AAW=0x0) at AsmWriter.cpp:2092
#2 0x00007ffff6fb536c in operator<< (V=..., OS=...) at /llvm/include/llvm/Value.h:318
#4 ....
I nee d указатель F остаться в живых, потому что я использую его для создания другого клона, поэтому у меня есть F = F_clone – mohsaied
относительно 'F = F_clone', я делал это неправильно. Мне нужно передать ссылку указателя на функцию, чтобы правильно установить ее. Итак, мой новый прототип функции теперь: 'replaceCurrentFunction (Function * & F, Function * & F_clone)'. Это означает, что F указывает на правильную вещь в моем внешнем цикле, где я буду клонировать ее и повторить попытку. – mohsaied
С F, являющимся ссылкой указателя, тогда да, это имеет смысл. Однако это не очень хорошая практика. Вы должны вернуть указатель вместо того, чтобы выполнять задание на сайте вызова. Остальная часть описанного мной действия все еще действительна (вы должны отметить ответ, принятый, если он правильно задает ваш вопрос, в противном случае дайте мне знать, как улучшить). – Joky