К сожалению под Windows отсутствует механизм динамического связывания, хотя и есть DLL, но LLVM не может зарегистрировать пользовательский пасс, оформленный как DLL, поэтому свои пассы придется собирать как часть проекта LLVM. В данной заметке я приведу небольшую инструкцию, которой очень не хватает на официальном сайте проекта.
1. Нужно скопировать каталог с исходными кодами своих пассов (буду называть его LLVMExperimentPasses) в lib/Transforms (здесь и далее пути даны относительно корня каталога с исходными кодами LLVM, предполагается, что вы уже его зачекаутили, например с GitHub-зеркала).
2. Добавить команду add_subdirectory(LLVMExperimentPasses) в файл lib/Transforms/CMakeLists.txt.
3. Для каждого созданного пасса добавить функцию с сигнатурой initialize${ИМЯ ПАССА}Pass(PassRegistry &); в заголовочный файл include/llvm/InitializePasses.h. Также следует добавить туда функцию с сигнатурой void initializeLLVMExperimentPasses(PassRegistry &);. Для пасса FunctionArgumentCount следует добавить в заголовочный файл такие строки:
4. Добавить библиотеку LLVMExperimentPasses в список LLVM_LINK_COMPONENTS в файле tools/opt/CMakeLists.txt:
5. Зарегистрировать пассы в исходном коде утилиты opt, добавив вызов функции initializeLLVMExperimentPasses в функцию main данной утилиты (в файле tools/opt/opt.cpp):
opt.exe -fnargcnt < sum.bc > sum-out.bc
Понравилось сообщение - подпишитесь на блог
1. Нужно скопировать каталог с исходными кодами своих пассов (буду называть его LLVMExperimentPasses) в lib/Transforms (здесь и далее пути даны относительно корня каталога с исходными кодами LLVM, предполагается, что вы уже его зачекаутили, например с GitHub-зеркала).
2. Добавить команду add_subdirectory(LLVMExperimentPasses) в файл lib/Transforms/CMakeLists.txt.
3. Для каждого созданного пасса добавить функцию с сигнатурой initialize${ИМЯ ПАССА}Pass(PassRegistry &); в заголовочный файл include/llvm/InitializePasses.h. Также следует добавить туда функцию с сигнатурой void initializeLLVMExperimentPasses(PassRegistry &);. Для пасса FunctionArgumentCount следует добавить в заголовочный файл такие строки:
// my experiment passes void initializeLLVMExperimentPasses(PassRegistry &); void initializeFunctionArgumentCountPass(PassRegistry &); } // end namespace llvm(функция обязательно должна быть определена внутри пространства имен llvm).
4. Добавить библиотеку LLVMExperimentPasses в список LLVM_LINK_COMPONENTS в файле tools/opt/CMakeLists.txt:
set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} AggressiveInstCombine ... ExperimentPasses )Важно: Библиотека перечисляется как ExperimentPasses, а не LLVMExperimentPasses.
5. Зарегистрировать пассы в исходном коде утилиты opt, добавив вызов функции initializeLLVMExperimentPasses в функцию main данной утилиты (в файле tools/opt/opt.cpp):
// Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); ... initializeLLVMExperimentPasses(Registry); // For codegen passes, only passes that do IR to IR transformation are // supported.6. Пересобрать LLVM (здесь YOUR_LLVM_BUILDTREE - каталог, в котором вы собираете вашу копию LLVM) и установить новые библиотеки и утилиты:
cd YOUR_LLVM_BUILDTREE cmake -DCMAKE_CXX_COMPILER=YOUR_FAVOURITE_COMPILER -DCMAKE_C_COMPILER=YOUR_FAVOURITE_COMPILER -DCMAKE_LINKER=YOUR_FAVOURITE_LINKER .. -G"Ninja" cmake --build . cmake --build . --target installВсе, пассы готовы к использованию. Например, пасс FunctionArgumentCount из моего примера будет зарегистрирован под именем fnargcnt и может быть вызван с помощью утилиты opt:
opt.exe -fnargcnt < sum.bc > sum-out.bc
Понравилось сообщение - подпишитесь на блог