Добавление атрибута inreg к параметрам функции LLVM IR

Я работаю с LLVM и хочу воссоздать часть IR с помощью API:

declare void @fun(i32* inreg, i32 inreg)

Но я не могу заставить его на самом деле сделать это.

Моя текущая попытка:

Function* fun = cast<Function>(M.getOrInsertFunction("fun",type));

((fun -> getAttributes()).getParamAttributes(0)).addAttribute(c,0,Attribute::InReg);

((fun -> getAttributes()).getParamAttributes(1)).addAttribute(c,0,Attribute::InReg);

Этот код буквально ничего не делает после строки 1, строки 2 и 3 полностью игнорируются, и все, что я получаю в выводе IR, это:

declare void @fun(i32* , i32 )

Как мне заставить его работать правильно?


person hyughgjj    schedule 07.02.2016    source источник


Ответы (2)


Управлять атрибутами функций в LLVM довольно неудобно, так как атрибуты упакованы в неизменяемые и глобальные наборы. Назначение атрибута аргументу функции фактически означает замену набора, представляющего все атрибуты функции и аргумента, новым.

К счастью, есть по крайней мере вспомогательные функции, которые немного облегчают эту работу. Я предлагаю использовать метод llvm::Function::addAttribute().

Function* fun = cast<Function>(M.getOrInsertFunction("fun", type));
fun->addAttribute(1, Attribute::InReg);
fun->addAttribute(2, Attribute::InReg);

Имейте в виду, что индекс 0 представляет атрибуты функции, а атрибуты аргумента начинаются с индекса 1.

person Paweł Bylica    schedule 09.02.2016
comment
Этот комментарий был полезен, но одна ключевая часть неверна: атрибуты функций имеют индекс -1 = ~0 (по крайней мере, в последнем LLVM). Это можно увидеть в llvm::AttributeList::AttrIndex::FunctionIndex. Индекс 0 зарезервирован для атрибутов возвращаемого значения. - person Bensge; 30.10.2019

В вашем фрагменте кода есть три проблемы.

Во-первых, индекс первого параметра равен 1, а не 0. Поэтому вы должны использовать индексы 1 и 2, а не 0 и 1.

Во-вторых, addAttribute() не изменяет своего получателя, вместо этого он возвращает новый набор. Таким образом, правильный способ изменить атрибуты:

fun->setAttributes(fun->getAttributes().addAttribute(1, ...));

И, наконец, есть сокращение для вышеизложенного, которое просто нужно сделать:

fun->addAttribute(1, ...);
person Oak    schedule 08.02.2016