Как создать код для локальных именованных значений в регистре LLVM IR? - PullRequest
0 голосов
/ 03 июля 2011

Я генерирую LLVM IR (.ll файлы) из исходного языка.Этот язык не имеет изменяемых локальных переменных, и я пока не использую alloca s, пока все находится в регистрах LLVM.Тем не менее, он имеет неизменные локальные значения.В настоящее время они работают нормально, если часть инициализатора не является константой или другим идентификатором.Например:

def fun(a: Int, b: Int) = {
  val n = a + b
  n + 2
}

Это компилируется нормально, потому что a + b компилируется в инструкцию add i32 %a, %b, и инструкции могут быть дополнительно назначены локальным значениям, поэтому строка становится: %n = add i32 %a, %b.

С другой стороны, у меня проблемы с генерацией кода для следующего:

def fun() = {
  val n = 1
  n
}

Я мог бы сгенерировать %n = bitcast i32 1 to i32, но bitcast не работает со всеми типами и не предназначен для этого.Ну, я думаю, в LLVM действительно нет ничего специально предназначенного для этого, иначе у меня не возникло бы вопроса.

Но есть ли хорошее решение без генерации множества различных неоперационных инструкций в зависимости от типаЗначение?bitcast не будет работать с кортежами, например:

error: invalid cast opcode for cast from '{ i32, i32 }' to '{ i32, i32 }'
%n = bitcast {i32, i32} {i32 1, i32 2} to {i32, i32}

Опять же, может быть, из-за того, что в IR нет инструкций «копирования», я не должен пытаться это делать и должен заменить% n назначение везде, где оно используется?

1 Ответ

0 голосов
/ 04 июля 2011

У вас есть две возможности:

  1. Сгенерировать код, используя alloca, load и store (проверьте, например, вывод clang или llvm-gcc при -O0), а затем используйте проход оптимизации -mem2reg, чтобы поднять все этовещи в регистры LLVM
  2. Используйте 1 вместо% n везде.
...