Изменить элемент вектора LLVM - PullRequest
0 голосов
/ 21 мая 2018

Я пытаюсь изменить элемент вектора, используя ИК-код LLVM.Следующий код:

extern printd(num);

array a [1 2 3];

printd(a[1]); # 2.0

a[1] = 10;

printd(a[1]); # 2.0

Генерирует этот код IR:

declare double @printd(double)

define <4 x double> @a() {
entry:
  %0 = insertelement <4 x double> undef, double 1.000000e+00, i32 0
  %1 = insertelement <4 x double> %0, double 2.000000e+00, i32 1
  %2 = insertelement <4 x double> %1, double 3.000000e+00, i32 2
  ret <4 x double> %2
}

define double @__anon_expr0() {
entry:
  %calltmp = call <4 x double> @a()
  %0 = extractelement <4 x double> %calltmp, i32 1
  %calltmp1 = call double @printd(double %0)
  ret double %calltmp1
}

define double @__anon_expr1() {
entry:
  %calltmp = call <4 x double> @a()
  %0 = insertelement <4 x double> %calltmp, double 1.000000e+00, i32 1
  ret double 0.000000e+00
}

Эта часть в порядке, проблема здесь (__anon_expr1):

define double @__anon_expr1() {
entry:
  %calltmp = call <4 x double> @a()
  %0 = insertelement <4 x double> %calltmp, double 1.000000e+00, i32 1
  ret double 0.000000e+00
}

То, что я пытаюсь сделать, это заново вставить значение в вектор - это не работает.Я подозреваю, что это одна из двух проблем:

  1. Я не могу переустановить элемент
  2. Я фактически переустанавливаю элемент в переменной %calltmp, а не фактический вектор.

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

1 Ответ

0 голосов
/ 21 мая 2018

Ваша первая проблема в том, что вы определили @a как функцию, особенно ту, которая всегда возвращает значение <1.0, 2.0, 3.0>.Поэтому независимо от того, что вы делаете в другом месте, вы никогда не сможете позвонить @a() и получить что-либо, кроме этого значения.Поэтому первое, что вам нужно сделать, - это превратить @a в глобальную переменную, чтобы вы могли изменить ее значение.

Теперь ваша следующая проблема заключается в том, что insertelement не меняет заданный вектор.Это невозможно, потому что векторы хранятся в регистрах, и вы не можете переназначить регистры (LLVM использует статическую форму одиночного назначения).Поэтому вместо insertelement создается новый вектор с измененным заданным индексом.В своем коде вы сохраняете этот новый вектор в %0, а затем ничего не делаете с ним.Как только вы сделали @a глобальной переменной, вы можете сохранить значение %0 в @a.Это решит вашу непосредственную проблему.

Однако, как мы уже обсуждали в комментариях, векторы не совсем подходят для того, что вы делаете по нескольким причинам:

  1. Поскольку вы не можете иметь указатели на векторы, вы не можете легко написать функции, которые перебирают векторы произвольного размера.
  2. Как я уже указывал, insertelement создает новый вектор с одним измененным элементом,Это означает, что весь вектор копируется.Если вы создаете большие векторы, это может быть довольно дорогостоящим.
  3. Похоже, вы на самом деле не используете ни одно из преимуществ векторов.Векторы позволяют вам выполнять точечную арифметику для векторов чисел одинакового размера, которые будут соответствовать инструкциям SIMD, где это необходимо.Вот как они должны использоваться, а не как замены массивов общего назначения.

Если вы сделаете @a массив, вы можете получить указатель на его второй элемент и сохранить новыйзначение непосредственно в это.Таким образом, вместо того, чтобы создавать новый массив и заменять его @a, вы просто меняете один элемент, который хотите изменить.Это то, что вы действительно хотите.

...