首页 > 解决方案 > llvm 无需映射即可复制

问题描述

我正在做一个优化传递,用少一个参数的重复函数替换现有函数。复制函数是通过使用 Function::Create 初始化少一个参数,并使用 CloneBasicBlock 复制现有函数的每个块来制作的。打印出来似乎没问题,但是“引用另一个函数中的参数!” 导致错误。

CloneBasicBlock 上的文档描述了“返回的块是指定基本块的精确副本,没有任何重新映射”,这似乎是原因,但我找不到问题的解决方案。

我试图查看有关模块、函数、函数类型、ValueMapper 和其他一些的 llvm 文档,但无法得到答案。使模块在打印输出上明确可见是我的意图。

以下是从 F.getParent() 打印输出获得更改后的代码,错误如下。我正在将@0 上的调用转换为@use_few_register。

F.getParent() 打印输出

以下是代码的相关部分

Value* arg1 = dyn_cast<Value>(F.getArg(0));
  Value* arg2 = dyn_cast<Value>(F.getArg(1));
  ValueToValueMapTy VMap;
  auto *I64Ty = Type::getInt64Ty(Context);

  vector<Type*> ArgTypes;
  ArgTypes.push_back(I64Ty);

  FunctionType *ftype = FunctionType::get(F.getFunctionType()->getReturnType(), ArgTypes, false);
  Function *func = Function::Create(ftype, F.getLinkage());
  func->copyAttributesFrom(&F);
  func->takeName(&F);
  F.getParent()->getFunctionList().push_back(func);

  for (auto &Arg : func->args()){
    Arg.setName("merged"); //testing on one Arg only
  }

  for (auto &BB : F){
    auto *clone = CloneBasicBlock(&BB, VMap);
    func->getBasicBlockList().push_back(clone);
  }

  Instruction* X = BinaryOperator::Create(Instruction::AShr, func->getArg(0), ConstantInt::get(func->getArg(0)->getType(), 32), "tmp1");
  Instruction* Y = BinaryOperator::Create(Instruction::And, func->getArg(0), ConstantInt::get(func->getArg(0)->getType(), 4294967295), "tmp2");
  Instruction* X_trunc = CastInst::Create(Instruction::Trunc, X, arg1->getType(), arg1->getName());
  Instruction* Y_trunc = CastInst::Create(Instruction::Trunc, Y, arg2->getType(), arg2->getName());

  Y_trunc->insertBefore(&func->getEntryBlock().front());
  X_trunc->insertBefore(Y_trunc);
  Y->insertBefore(X_trunc);
  X->insertBefore(Y);

  return func;

任何有关相关文件/方法的意见或建议将不胜感激

标签: llvm

解决方案


您的问题是 CloneBasicBlock 完全按照其名称所暗示的那样做,并且您想要一些稍微不同的东西:您想要一个在大多数方面相同但在两个方面不同的克隆:当原始引用原始函数中的参数或基本块时,您希望克隆引用副本中的参数或基本块。

您最好的选择可能是查看 CloneBasicBlock() 是如何实现的并编写类似的东西,但是有一个额外的循环调用getOperand()来考虑每条指令的每个操作数,并if(isa<Argument>(…){…} elsif(isa<BasicBlock>(…){…}适当地处理这些操作数。您可能还需要对 phi 节点进行稍微特殊的处理


推荐阅读