然后,CloneFunction将原始函数替换为LLVM opt pass中的克隆函数

时间:2016-10-19 21:30:07

标签: compiler-construction llvm compiler-optimization llvm-c++-api

我正在写一个LLVM优化模块传递,如果我不喜欢结果,我希望能够恢复原始函数。所以我写了一个ModulePass,其基本结构如下:

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但是我遇到了段错误。尝试用克隆替换它后,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 ....

1 个答案:

答案 0 :(得分:0)

哇,你在这里使用了一堆不安全的API,有些陈述甚至没有意义。例如,您对void replaceCurrentFunction(Function *F, Function *F_clone) F = F_clone;的最后一行有什么期望?如果您希望更新来电者中的“F”,则应使用return F_clone结束此功能并以F = replaceCurrentFunction(F, F_clone);方式调用。

对于实际的LLVM API,正确的顺序是:

  1. 将旧函数的所有用法替换为克隆: F->replaceAllUsesWith(F_clone)
  2. 保存名称:std::string Name = F->getName()
  3. 删除F:F->eraseFromParent()
  4. 重命名克隆:F_clone->setName(Name)