Как судить, что инструкция в LLVM IR - это инструкция вызова или нет? - PullRequest
1 голос
/ 31 марта 2019

Я новичок в llvm, и я пытаюсь найти все инструкции по вызову функции в IR. Мой код показан ниже:

  for (BasicBlock &BB : F) {
    for (Instruction &inst : BB) {

      errs() << "\n => " << inst << "\n";

      // if (dyn_cast<CallInst>(&inst) || dyn_cast<InvokeInst>(&inst)) {
      if(inst.getOpcode() == Instruction::Call || inst.getOpcode() == Instruction::Invoke) { 
        errs() << "\n callinst => " << inst << "\n";
      }
    }
  }

Но это не работает, чтобы найти инструкции вызова функции. Например:

for this instruction: call void @func2(i32* %num)
the code can not find it.
And I did some experiment for this instucion:
inst.getOpcodeName() == "call"
inst.getOpcode() == 56
but:
Instruction::Call == 54
Instruction::UserOp1 == 56

У меня есть несколько вопросов:

  1. Как найти вызов функции в llvm IR?
  2. Для чего используется Инструкция :: UserOp1?
  3. Почему приведенный выше пример так запутан?

1 Ответ

1 голос
/ 31 марта 2019

На самом деле, ваш код правильный. Начиная с последних коммитов в зеркале llvm, код операции инструкции вызова больше не 54, а 56. 13 ноября 2018 года он был изменен на 55, а 8 февраля 2019 года он был изменен на 56.

https://github.com/llvm-mirror/llvm/commit/ca8cb6852b59f4cbfc311415aab0d5a7ce0616b4#diff-3ac5806b20ed80b3be17bac3cdb4f799

https://github.com/llvm-mirror/llvm/commit/e3696113b639c8bf0b72d6c27dd76d6fdd8ebf61#diff-3ac5806b20ed80b3be17bac3cdb4f799

Код операции для UserOp1 теперь 58.

На ваши вопросы:

1) Правильный способ идентифицировать инструкции вызова, как и любые другие типы инструкций, - это использовать функцию isa<>(). Аргумент шаблона - это тип, который вы хотите идентифицировать, а аргумент функции - указатель на инструкцию. В вашем примере вы можете изменить условие if на:

if(isa<CallInst>(&inst) || isa<InvokeInst>(&inst)) {

Причина, по которой вы предпочли бы делать это, а не сравнивать коды операций, довольно очевидна. Как видите, можно добавить новые инструкции и изменить коды операций. Таким образом, сравнение кодов операций становится довольно быстро несовместимым. Использование функции isa всегда будет возвращать true, если типы совпадают, независимо от кодов операций. Проверьте документы для этой функции здесь: http://llvm.org/docs/ProgrammersManual.html#the-isa-cast-and-dyn-cast-templates

2) UserOp1 - это тип инструкции, используемой только внутри проходов. Насколько я знаю, он также используется фреймворком llvm в нескольких функциях для решения некоторых важных случаев. Вы никогда не сможете прочитать или написать инструкцию «UserOp1» (или UserOp2) для IR. Вам не нужно заботиться об этом типе. См. Также здесь: Как использовать инструкцию UserOp1 / UserOp2?

3) Возможно, вы используете последнюю версию фреймворка, и поэтому вы получаете 56 для инструкций вызова. Вы могли быть смущены, потому что вы сравнили этот вывод с немного устаревшим файлом Instructions.def, который отображает инструкцию вызова на код операции 54.

...