将尾调用void(i32,...)强制转换为llvm :: Function以获取FnAttribute

时间:2018-10-31 15:09:02

标签: c++ casting llvm llvm-ir

我有以下LLVM IR代码:

 //Code snippet #1
; <label>:30:                                     ; preds = %30, %18
  tail call void (i32, ...) bitcast (void (...)* @delay to void (i32, ...)*)(i32 5) #3
  %31 = tail call zeroext i1 (...) @testFunc() #3
  br i1 %31, label %30, label %32

第一个是对函数Delay的函数调用。这是一个空函数,但我向它添加了FnAttributes。我对testFunc做了同样的操作,但是这个返回的是1位整数(布尔值)。

像这样遍历代码时:

//Code snippet #2
for (llvm::Instruction& inst : BB)
{
   llvm::CallInst * callInst = llvm::dyn_cast<llvm::CallInst>(&inst);

    if (callInst == nullptr)
        continue;

    if (llvm::Function *calledFunction = callInst->getCalledFunction()) {
        if (calledFunction->hasFnAttribute("MyAttr")) {
            llvm::outs() << calledFunction.getFnAttribute("MyAttr").getValueAsString().str() << "\n";
        } 
    }

在上面的代码中获取属性(并将其打印到控制台)适用于testFunc,但不适用于void函数。我需要将void函数强制转换为llvm :: Function才能获取FnAttribute。

使用类似

callInst->getCalledValue()

给我该值,但无法将其强制转换为llvm :: Function。

如果我通过使用以下代码来完成所有功能:

//Code snippet #3
for (llvm::Function& F : M)
{
    if (F.hasFnAttribute("MyAttr"))
        {
            llvm::outs() << F.getFnAttribute("MyAttr").getValueAsString().str() << "\n";
        }
}

我很好地获得了延迟函数的FnAttribute。

我的问题是:如何在此代码中将“延迟”函数转换为llvm :: Function,以便可以在代码段2中获取FnAttribute?

非常感谢!

1 个答案:

答案 0 :(得分:1)

因此,经过一些搜索,我找到了解决自己问题的方法。

对于那些在这里寻找答案的人。我也找到了一种获取类型的方法。它包含在下面的代码中。

for (llvm::Instruction& inst : BB)
{
    llvm::CallInst * callInst = llvm::dyn_cast<llvm::CallInst>(&inst);

    if (callInst == nullptr)
           continue;

    //this prints out "normal functions"
    if (llvm::Function *calledFunction = callInst->getCalledFunction()) {
                    llvm::outs() << "Call to => " << calledFunction->getName().str() << "\n";
    }
    //this prints out the void bitcasted functions
    else if (llvm::Function *voidFunc = llvm::dyn_cast<llvm::Function>(callInst->getCalledValue()->stripPointerCasts())) {
                     llvm::outs() << "Call to => " << voidFunc ->getName().str() << "\n";
    }

    llvm::Type* t = callInst->getCalledValue()->getType();
    if (llvm::FunctionType* ft = llvm::cast<llvm::FunctionType>(llvm::cast<llvm::PointerType>(t)->getElementType()))
    { 
    //here is your function type
    }

}

说明:

  1. 首先,我们将指令转换为Callinstruction(Callinst)。
  2. 如果是nullptr,请继续进行下一个迭代。
  3. 尝试将其强制转换为函数指针。
  4. 如果它是位播指针,则尝试投射它。 (这解决了我的问题)。
  5. 要获取类型,可以使用getCalledValue()-> getType()函数 并将其转换为FunctionType