【问题标题】:Casting tail call void (i32, ...) bitcast to an llvm::Function to get the FnAttribute将尾调用 void (i32, ...) bitcast 转换为 llvm::Function 以获取 FnAttribute
【发布时间】:2018-10-31 15:09:01
【问题描述】:

我有以下 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的函数调用。这是一个 void 函数,但我在其中添加了 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,以便在代码 sn-p #2 中获取 FnAttribute?

非常感谢!

【问题讨论】:

    标签: c++ casting llvm llvm-ir


    【解决方案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. 首先我们将指令转换为调用指令 (Callinst)。
    2. 如果是 nullptr,则继续下一次迭代。
    3. 尝试将其强制转换为函数指针。
    4. 如果它是位转换指针,请尝试转换它。 (这解决了我的问题)。
    5. 要获取类型,您可以使用 getCalledValue()->getType() 函数 并将其转换为 FunctionType

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-11
      • 2017-07-08
      • 2018-04-26
      • 2020-08-23
      • 1970-01-01
      • 1970-01-01
      • 2018-02-26
      相关资源
      最近更新 更多