Как избежать нежелательного свертывания констант, выполняемого генератором кода LLVM?

То, чего я пытаюсь добиться, - это избежать постоянного свертывания некоторых констант (которые представляют адреса в моем коде), таких как 100000000 константа ниже. Мне это нужно, потому что позже JIT-скомпилированный код может быть исправлен, что изменяет константы из-за перемещения объекта.

Код ниже - моя лучшая попытка избежать постоянного сворачивания (любой ценой). Не работает Я в конечном итоге с постоянным 100011111 в потоке инструкций.

llc -O0 code.ll -print-after-all показывает, что сворачивание происходит в Expand ISel Pseudo-instructions проходить.

; ModuleID = '0'
target triple = "x86_64-unknown-linux-gnu"

define  i64 @"0"() {
BlockEntry0:
  %cell = alloca i64, align 8
  store volatile i64 0, i64* %cell, align 8
  %volatile_zero3 = load volatile i64, i64* %cell, align 8
  %base = add i64 %volatile_zero3, 100000000
  %volatile_zero4 = load volatile i64, i64* %cell, align 8
  %opaque_offset = add i64 %volatile_zero4, 11111
  %casted_base = inttoptr i64 %base to i8*
  %gep = getelementptr i8, i8* %casted_base, i64 %opaque_offset
  %as_ptr = bitcast i8* %gep to i64*
  %loaded = load i64, i64* %as_ptr, align 4
  %as_function = inttoptr i64 %loaded to i64 (i64)*
  %ret_val = tail call i64 %as_function(i64 0)
  ret i64 %ret_val
}

attributes #0 = { nounwind }

Я понимаю, что моя проблема может быть решена путем добавления некоторого внутреннего, которое на уровне кода будет разворачиваться в простой movabs reg, imm64, Но я хотел бы иметь временное решение в настоящее время.

Вопрос: возможно ли создать непрозрачную константу в llvm, которая не будет постоянно свёрнута?

Моя версия llvm 3.7.0svn.

1 ответ

Решение

Нет, это невозможно. Лучше всего использовать внешнюю глобальную переменную, как было упомянуто в комментариях. Фактически, для ваших целей это может быть именно то, что вы хотите сделать, так как в этот момент ваш jittable код получит перемещение для того, что вы на самом деле хотите, и будет соответствующим образом исправлен во время выполнения rtdyld.

Если вам нужна фактическая константа для объединенного кода (например, для вызова определенного адреса, о котором вы знаете), то то, что вы делаете, просто отлично.

Другие вопросы по тегам