Для любого вида сложного преобразования программы, подобного тому, которое вы пытаетесь достичь здесь, лучше всего удалить как можно больше промежуточных шагов, добавляющих сложность.Сначала докажите, что он работает в простейшем случае, а затем добавьте сложность обратно шаг за шагом.Для вашей конкретной проблемы это означает: попытаться добиться желаемой оптимизации на чистом коде C со всем кодом в одном файле, затем на чистом коде C в разных файлах и т. Д. Если вы не можете этого добиться во всехиз более простых случаев весьма маловероятно, что вы сможете заставить ее работать для исходной цели со всей дополнительной сложностью (и, делая это шаг за шагом, вы также получите гораздо лучшее представление о возможных причинах любых проблем, с которыми вы сталкиваетесь).
Если вы последуете приведенному выше совету, я вполне уверен (хотя я и не пробовал), что оптимизатор LLVM сделает желаемую оптимизацию , а не , даже впростейший случай иметь все в одном файле C и работать с полной оптимизацией.Причина в том, что вы ожидаете, что оптимизатор изменит семантику вашего кода, потому что два последовательных цикла for
не гарантируют одинаковые побочные эффекты (наблюдаемые изменения) как один цикл for
с двумя выполненными теламив последовательности (код, который вы предоставили, является хорошим примером этого).Чтобы оптимизация была безопасной, компилятор должен иметь возможность гарантировать (доказывать) различные свойства о побочных эффектах всего кода, выполняемого из тел цикла.Хотя это и не невозможно, в общем случае это чрезвычайно сложно сделать на языке с неконтролируемыми побочными эффектами, такими как C, и в большинстве случаев это невозможно, если вы пересекаете какие-либо границы библиотеки (как вы, вероятно, сделаете здесь), посколькуна самом деле у вас нет единого шага оптимизации, который (по крайней мере, теоретически) мог бы принять во внимание весь необходимый код.Если вы действительно хотите углубиться в LLVM и его среду оптимизатора, я рекомендую вам начать с прочтения этой превосходной статьи, в которой описаны мотивы и дизайн LLVM , а затем выяснить, какой код оптимизатор сможет использоватьчтобы сделать это возможным, рассмотрим один шаг.
Я бы порекомендовал подумать о том, что вы мотивируете, пытаясь заставить Lua скомпилировать в битовый код LLVM и оптимизировать вместе с битовым кодом LLVM из C. I 'Я уверен, что на то есть веские причины, но если вы не уверены в том, что это единственный способ достичь ваших целей, я бы лично попробовал другой подход.
Допустим, ваша основная мотивация - производительность.Как уже упоминалось Эндрю Y , я бы рекомендовал хорошенько взглянуть на luajit .Это позволяет чистому (прилично написанному) Lua работать близко к C и во много раз лучше, чем стандартный Lua , и также включает Интерфейс внешних функций (FFI) что может быть полезно для вашей проблемы.Со страницы FFI:
Библиотека FFI позволяет вызывать внешние функции C и , используя структуры данных C из чистого кода Lua.
Библиотека FFI в значительной степени избавляет от необходимости писать утомительные ручные привязки Lua / C на C. Не нужно изучать отдельный язык привязок - она анализирует простые объявления C !Их можно вырезать из файлов заголовков C или справочных руководств.Это задача связывания больших библиотек без необходимости иметь дело с хрупкими генераторами связывания.
Библиотека FFI тесно интегрирована в LuaJIT (она не доступна как отдельный модуль).Код, сгенерированный JIT-компилятором для доступа к структурам данных C из кода Lua, находится на одном уровне с кодом, который сгенерирует компилятор C.Вызовы функций C могут быть встроены в JIT-скомпилированный код, в отличие от вызовов функций, связанных через классический API Lua / C.