Приведение хвостового вызова void (i32, ...) для передачи в llvm :: Function для получения атрибута FnAttribute - PullRequest
0 голосов
/ 31 октября 2018

У меня есть следующий код IR LLVM:

 //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

Первый - это вызов функции Задержка. Это пустая функция, но я добавил 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, чтобы я мог получить атрибут FnAttribute во фрагменте кода # 2?

Заранее большое спасибо!

1 Ответ

0 голосов
/ 02 ноября 2018

Итак, после некоторых поисков я нашел решение своей проблемы.

Для тех, кто ищет ответ, вот он. Также я нашел способ получить тип. Это включено в код ниже.

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
...