2015-01-19 2 views
3

У меня есть следующий сценарий:Добавление соответствующих PHI Узлов для LLVM-л

 A 
    / \ 
    B C 
     \/
     D 
    /\ 
    E F 
     \/
     ... 

Где A,B,C,D,E,F все основные блоки, | является стрелкой, направленной вниз.

Теперь в B я бы некоторое размораживание, скажем %mul = ..., что позже будет использоваться в соответствующей левой стороне блока E, как ... = %mul .... У меня есть соответствующий поток управления, вставленный - либо будут приняты только левые ветви, или только правильные, проблема в том, что я получаю ошибку Instruction does not dominate all uses на прохождении проверки.

Я попытался это исправить, добавив PHINode инструкции, как показано ниже:

B:          ; preds = %A 
    %shl = shl ... 
    br label %D 

C:          ; preds = %A 
... 
br label %D 

D:          ; preds = %B , %C 
... 
br i1 %ctrl, label %E, label %F 

E:         ; preds = %D 
    %phi_nlcs = phi i32 [ %shl, %extra_l_diff ], [ 0, %for.cond ] 
    %cmp = icmp slt i32 %phi_nlcs, %1 
    br label ... 

эллипсов есть, чтобы скрыть ненужные детали, и я переименовал блоки, но основная логика должна быть там. Как вы можете видеть, я заменил использование %shl на PHINode с помощью соответствующего вызова replaceAllUsesWith().

Однако, теперь я получаю новую ошибку:

PHINode should have one entry for each predecessor of its parent basic block! 
%phi_nlcs = phi i32 [ %shl, %extra_l_diff ], [ 0, %for.cond ] 

Как я могу это исправить?

ответ

3

Фи узел должен быть в начале D.

D: 
    %phi_nlcs = phi [%shl, B] [undef, C] ; if we've come from B use %shl, if from C an undef value. 
    ... 

Это потому, что узел фи говорит, что значение должно быть быть для каждого из доминирующих базовых блоков (В и С) поэтому его необходимо разместить на краю, где объединены основные блоки.

+0

Я только что осознал это сам и собирался опубликовать ответ, но вы избили меня, спасибо – baibo

Смежные вопросы