LLVM IR временное использование - PullRequest
0 голосов
/ 25 июня 2018

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

while (*s == 'a')
{
    c = *s++;
}
*s = c;

и, как я и подозревал, окончательная запись вне цикла (* s = c) выполнена с другим временным (%tmp5), чем тот, который читается внутри цикла (%tmp4)

while.body:      ; preds = %while.cond
  %tmp3 = load i8*, i8** %s.addr, align 8
  %incdec.ptr = getelementptr inbounds i8, i8* %tmp3, i32 1
  store i8* %incdec.ptr, i8** %s.addr, align 8
  %tmp4 = load i8, i8* %tmp3, align 1
  store i8 %tmp4, i8* %c, align 1
  br label %while.cond

while.end:       ; preds = %while.cond
  %tmp5 = load i8, i8* %c, align 1
  %tmp6 = load i8*, i8** %s.addr, align 8
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ; store i8 %tmp4, i8* %tmp6, align 1 ;
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  store i8 %tmp5, i8* %tmp6, align 1

Когда я редактирую файл * .ll и вручную заменяю %tmp5 на %tmp4, тогда llvm-as несчастен:

$ llvm-as modified.ll
Instruction does not dominate all uses!
%tmp4 = load i8, i8* %tmp3, align 1
store i8 %tmp4, i8* %tmp6, align 1

Есть ли пример, где временное значение будет определено внутри цикла и используется вне его ? Спасибо!

Ответы [ 2 ]

0 голосов
/ 25 июня 2018

Базовый блок while.end имеет только блок while.cond в качестве предшественника. Таким образом, вы не можете получить доступ к переменным, определенным в while.body. Это как будто вы хотите получить доступ к переменной, определенной в одной ветви из другой:

if(...)
   int x = ...;
else
   print(x);

Вместо этого объявите все переменные, которые вам нужны, в блоке ввода цикла, а затем используйте его как из while.body, так и while.end.

0 голосов
/ 25 июня 2018

LLVM на самом деле не имеет временных показателей, он использует SSA. Это сокращение от статического одиночного присваивания, а ключевое слово здесь - одиночное. Все является значением, и значение всегда должно присваиваться один раз .

Все может использовать любое значение, которое обязательно было назначено ко времени, когда оно используется. «Доминирует» означает «доказуемо предшествует» в сообщении об ошибке, которое вы получили, т.е. LLVM видит, что входная строка - «b», код будет прыгать прямо с while.cond до while.end, мимо while.body.

Когда вы используете значения из цикла после его окончания, все может немного запутаться. Возможно, вам придется подумать и закрыть вкладки Slack и Facebook. Но LLVM не возражает.

...