LLVM - проблем с свързването

Пиша генератор на LLVM код за езика Timber, текущият компилатор излъчва C-код. Проблемът ми е, че трябва да извикам C функции от генерираните LLVM файлове, например компилаторът има събирач на боклук в реално време и трябва да извикам функции, за да уведомя, когато нови обекти са разпределени в купчината. Нямам идея как да свържа тези функции с моите генерирани LLVM файлове.

Генерирането на код се извършва чрез генериране на .ll-файлове и след това ръчно компилиране.

Опитвам се да извикам външна функция от LLVM, но нямам късмет. В примерите, които >открих, се извикват само C стандартни функции като "puts" и "printf", но аз искам да извикам >домашна функция. закъсах.


person capitrane    schedule 13.09.2009    source източник
comment
Имате предвид, че се опитвате да пишете код директно в LLVM IR и не можете да осъществите повикване, или че компилирате код с помощта на LLVM и имате проблеми?   -  person Stephen Canon    schedule 14.09.2009


Отговори (3)


Компилирайте вашите LLVM асемблиращи файлове нормално с llvm-as:

llvm-as *.ll

Компилирайте биткод файловете в .s асемблиращи езикови файлове:

llc *.bc

GCC ги в библиотеката по време на изпълнение:

gcc *.s runtime.c -o executable

Заместете в реални makefiles, споделени библиотеки и т.н., ако е необходимо. Схванахте идеята.

person Jonathan Tang    schedule 01.01.2010

Предполагам, че пишете LLVM трансформация и искате да добавите извиквания към външни функции в трансформиран код. Ако това не е така, редактирайте въпроса си и включете повече информация.

Преди да можете да извикате външна функция от LLVM код, трябва да вмъкнете декларация за нея. Например:

virtual bool runOnModule(Module &m) {
    Constant *log_func = m.getOrInsertFunction("log_func",
                                               Type::VoidTy,
                                               PointerType::getUnqual(Type::Int8Ty),
                                               Type::Int32Ty,
                                               Type::Int32Ty,
                                               NULL);
    ...
}

Кодът по-горе декларира функция log_func, която връща void и приема три аргумента: байтов указател (низ) и две 32-битови цели числа. getOrInsertFunction е метод на 1Module.html" rel="noreferrer">Module.

За да извикате функцията, трябва да вмъкнете 1CallInst.html" rel="noreferrer">CallInst. Има няколко статични Create метода за това.

person Jay Conrod    schedule 23.10.2009
comment
Точно това се опитвах да разбера как да направя с llvm, благодаря! - person Dan; 29.11.2009

Тълкувам въпроса ви като „как да внедря библиотека по време на изпълнение в C или C++ за моя език, която се компилира в LLVM?“

Един подход е, както е описано подробно от Джонатан Танг, да преобразувате изхода на вашия компилатор от LLVM IR в битов код към асемблиране и ванилия gcc да свърже асемблирането с източника за изпълнение (или обектни файлове).

Алтернативен, вероятно по-гъвкав подход е да използвате llvm-gcc, за да компилирате самото време за изпълнение в LLVM биткод, и след това да използвате llvm-ld, за да свържете биткода от вашия компилатор с биткода на вашето време за изпълнение. След това този биткод може да бъде повторно оптимизиран с opt, преобразуван обратно в IR с llvm-dis, интерпретиран директно с lli (това ще, afaik, работи само ако LLVM е изграден срещу libffi) или компилиран до асемблиране с llc (и след това към роден двоичен с ванилия gcc).

person Ben Karel    schedule 27.01.2010