Есть ли способ различать типы указателей guish в llvm ir? - PullRequest
1 голос
/ 27 мая 2020

Я пытаюсь оптимизировать коды в llvm ir, понимая, что Types - isPointerTy не различает guish между * i8, * i16, * i32, * i64. Вывод значений их типов, очевидно, дает разные значения. Ниже приведен код, который я использовал для обнаружения проблемы.

in C:

...
if (CallInst *CI = dyn_cast<CallInst>(UsrI)) {
   if (CI->getCalledFunction()->getReturnType() ->isPointerTy()){
      outs() << "Calling func with ptr return = " << CI->getCalledFunction()->getName() << "\n";
      outs() << CI->getCalledFunction()->getReturnType() << "\n";
   }
}
...

in llvm:

...
if.end:
    %test3 = call i64* @malloc64(i64 %mul)
    %call = call i32* @malloc32(i64 %mul) #4
    %test = call i16* @malloc16(i64 %mul)
    %test2 = call i8* @malloc8(i64 %mul)
...
declare i8* @malloc8(i64)
declare i16* @malloc16(i64)
declare i16* @malloc16(i64)
declare i16* @malloc16(i64)

Отображение вывода как

Вызов развлечения c с ptr return = malloc8
0x1c56e90
Вызов удовольствия c с ptr return = malloc16
0x1c56e20
Calling fun c с ptr return = malloc32
0x1c56db0
Calling fun c with ptr return = malloc64
0x1c56d40

Я пробовал просматривать многие документы llvm, но кое-что упустил. Любые советы о том, как я могу проверить точный тип указателя, были бы оценены.

1 Ответ

2 голосов
/ 27 мая 2020

Метод isPointerTy не различает guish между разными типами, он просто сообщает true или false, является ли тип указателем.

Один из способов решить вашу проблема заключается в том, чтобы изучить его базовый тип, указатель тип (тип, на который указывает указатель).

Вот как вы можете это сделать:

Type *returnType = CI->getCalledFunction()->getReturnType();
if (PointerType *pointerType = dyn_cast<PointerType>(returnType)) {
  llvm::Type *pointeeType = pointerType->getElementType();
  /// the pointee type now holds one of i8, i16, i32, or i64
  if (IntegerType *intType = dyn_cast<IntegerType>(pointeeType)) {
    outs() << intType->getBitWidth() << "\n";
  }
}

Второй строка пытается преобразовать общий Type * в более специальный PointerType *. dyn_cast возвращает либо действительный указатель, либо nullptr, если returnType не является PointerType.

Затем вы получаете доступ к типу указателя (через getElementType) и можете делать дальнейшие проверки. В вашем примере все базовые типы - IntegerType s, способ отличить guish их - проверить их битовую ширину.

Думаю, это должно помочь :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...