2016-06-12 7 views
5

Прямо в точку - я пытаюсь связать два (или более) модуля llvm вместе, и я столкнулся с некоторой нечетной ошибкой LLVM.Типы LLVM IR сбрасываются неправильно при связывании (C++ API)

Я не хочу размещать слишком много кода, поэтому я буду использовать кучу псевдо здесь.

У меня есть 3 модуля, допустим, A, B и C. A является основным модулем; Я инициализирую llvm::Linker с ним. B и C - вторичные модули; Я звоню linker.linkInModule(B and C).

Все 3 модулей, помимо всего прочего, эти два типа определены:

%String = type { i8*, i64 } 
%Character = type { i8*, i64 } 

Обратите внимание, что они имеют те же тип элементов. Кроме того, функция foo определяется как таковой (в модуле B):

define i1 @_ZN9Character7hasDataEv(%Character*) { } 

Эта функция объявлена ​​в модулях A и C. Теперь, все кажется хорошо - эта функция вызывается из обоих модулей А и C и ИК выглядит нормально, так как:

%21 = call i1 @_ZN9Character7hasDataEv(%Character* %4) 

Здесь возникает проблема: когда все 3 модуля связаны между собой, что-то происходит с этими типами:

  1. Они теряют свое название, став %2 (%String) и %3 (%Character).
  2. Они, кажется, объединены вместе.

Странно, хотя это преобразование происходит в обоих модулях A и C, ошибка возникает только в C - обратите внимание, что A является так называемым «основным» модулем.

Функция определения связанного файла теперь

define i1 @_ZN9Character7hasDataEv(%2*) 

Обратите внимание, как %Character или %3, был превращен в %2. Кроме того, в callsite, в том, что, по-видимому попытка ип-объединить типы, я получаю это:

%10 = call i1 bitcast (i1 (%2*)* @_ZN9Character7hasDataEv to i1 (%3*)*)(%2* %2) 

Любопытно, что хотя функция отлили из i1 (%2*) в %3 (%2*), аргумент, передаваемый (. Arg 1) по-прежнему типа %2. Что происходит?

Обратите внимание, что в модуле A все, что происходит, выполняется правильно, и нет ошибки. Это происходит из-за целый ряд функций, но только в модуле С.

Я пытался воспроизвести его копию наклеивать их на .ll файлов и вызов llvm-link с последующим llvm-dis, но 1. типов не объединены, и 2 . Нет такой ошибки.

Спасибо ...?

+0

Вы пытались отключить все оптимизации? Имеет ли значение разница, если вы используете разные оптимизации? Первое, что я подозреваю, столкнувшись с странными ошибками, - это попытки оптимизации, связанные с моим кодом. – user2600312

+0

Я отключил все проходы оптимизации. Я нашел решение, я отредактирую его в вопросе. – zhiayang

ответ

1

Хорошо, получается, что после того, как некоторые прокручивались в IRC-канале llvm, llvm :: Linker предназначался для использования с пустым модулем llvm :: Module в качестве стартового модуля.

Кроме того, в моем случае использования я повторно использую один и тот же llvm :: Type (фактическая вещь в памяти) для разных модулей, которые я связываю вместе. Они сказали, что это не было незаконным, но что он никогда не тестировался, поэтому ... ¯ \ _ (ツ) _/¯

Так или иначе проблема была устранена путём пустого модуля перейти к компоновщику ,