如何在llvm中更改Callinst中的操作数类型?

时间:2016-08-24 00:41:39

标签: llvm

我正在尝试实现CallInst的转换并执行以下操作:

  1. 更改函数调用的参数类型

  2. 更改返回值的类型

  3. 例如,我想更改以下IR:

        %call = call double @add(double %0, double %1)
    
        define double @add(double %x, double %y) #0 {
        entry:
          %x.addr = alloca double, align 8
          %y.addr = alloca double, align 8
          store double %x, double* %x.addr, align 8
          store double %y, double* %y.addr, align 8
          %0 = load double, double* %x.addr, align 8
          %1 = load double, double* %x.addr, align 8
          %add = fadd double %0, %1
          ret double %add
        }
    

    到IR_New:

        %call = call x86_fp80 @new_add(x86_fp80 %0, x86_fp80 %1)
    
        define x86_fp80 @new_add(x86_fp80 %x, x86_fp80 %y) #0 {
        entry:
          %x.addr = alloca x86_fp80, align 16
          %y.addr = alloca x86_fp80, align 16
          store x86_fp80 %x, x86_fp80* %x.addr, align 16
          store x86_fp80 %y, x86_fp80* %y.addr, align 16
          %0 = load x86_fp80, x86_fp80* %x.addr, align 16
          %1 = load x86_fp80, x86_fp80* %x.addr, align 16
          %add = fadd x86_fp80 %0, %1
          ret x86_fp80 %add
        }
    

    我已经完成了更改AllocaInst,StoreInst,LoadInst,BinaryOperator和ReturnInst的类型。

    我现在对如何处理CallInst非常困惑。

    我最初的想法是在迭代所有指令时,如果我找到一个CallInst,

       if (CallInst *call = dyn_cast<CallInst>(it)){
    

    执行以下三个步骤:

    1. 构造新的FunctionType

      x86_fp80(x86_fp80, x86_fp80)
      
      使用

      std::vector<Type*> ParamTys;
      ParamTys.push_back(Type::getX86_FP80Ty(context));
      ParamTys.push_back(Type::getX86_FP80Ty(context));
      FunctionType *new_fun_type = FunctionType::get(Type::getX86_FP80Ty(context), ParamTys, true);
      
    2. 在步骤1中使用新类型构造函数,即在示例中构造new_add

      Function *fun = call->getCalledFunction();
      Function *new_fun = Function::Create(new_fun_type,fun->getLinkage(), "", fun->getParent());
      
    3. 使用从步骤2获得的新函数构造一个新的CallInst。

      CallInst *new_call = CallInst::Create(new_fun, *arrayRefOperands, "newCall", call);
      new_call->takeName(call);
      }
      
    4. 然而,通过这种方式,我获得了以下IR而不是我想要的IR_New:

         %call = call x86_fp80 (x86_fp80, x86_fp80, ...) @0(x86_fp80 %5, x86_fp80 %7)
      
         declare x86_fp80 @new_add(x86_fp80, x86_fp80, ...)
      

      构造了一个新的被调用函数定义(声明x86_fp80 @new_add(x86_fp80,x86_fp80,...)),但这个新函数的主体是空的。我很困惑如何添加身体并获得我想要的IR_New。我的天真想法是:

         for (Instruction i : called function(add in the example)){
             create new_i with type x86_fp80;
             insert new_i in the new function constructed(new_add in the example);
           }   
      

      这是实现目标的好方法吗?

      任何建议都将不胜感激:)

0 个答案:

没有答案