Как LLVM обрабатывает оператор if, за которым следует некоторый код - PullRequest
0 голосов
/ 12 марта 2019

Я думаю о компиляторах и у меня вопрос о том, как они поддерживают древовидный аспект инструкций. В основном инструкции , кажется, образуют дерево.

outer.for.body:
  ...
  %val1 = load i32, i32* %arrayidx3, !llvm.access.group !4
  ...
  br label %inner.for.body

inner.for.body:
  ...
  %val0 = load i32, i32* %arrayidx1, !llvm.access.group !3
  ...
  store i32 %val0, i32* %arrayidx2, !llvm.access.group !3
  ...
  br i1 %exitcond, label %inner.for.end, label %inner.for.body, !llvm.loop !1

inner.for.end:
  ...
  store i32 %val1, i32* %arrayidx4, !llvm.access.group !4
  ...
  br i1 %exitcond, label %outer.for.end, label %outer.for.body, !llvm.loop !2

outer.for.end:                                          ; preds = %for.body

Мне интересно, как это дерево поддерживается, когда у вас есть что-то вроде этого:

function hello() {
  foo()
  if (x == 0) {
    a()
  } else {
    b()
  }
  bar()
}

Я бы подумал, что это примерно так (псевдокод):

call %foo
br %xcondition label %a, label %b
call %bar

Но это будет означать, что на самом деле больше нет бинарного дерева, потому что есть 3 ветви:

a()
b()
bar()

Но, тем не менее, вышеприведенное не имеет никакого смысла, потому что bar() никогда не будет вызван, поскольку он либо a(), либо b(), и он прыгает без (я предполагаю) возврата , Вот где мой вопрос. Как выглядит сборка или LLVM IR (или псевдокод) для того, как он может справиться с этим делом.

...