LLVM несовместимая схема нумерации - PullRequest
1 голос
/ 14 февраля 2020

Я играл с компиляторами и работал над собственным игрушечным C компилятором. В настоящее время я пытаюсь настроить таргетинг на IR LLVM, но у меня возникают проблемы с обдумыванием синтаксиса.

Моя текущая проблема: почему этот правильный синтаксис IR:

define i32 @main() {
    %1 = alloca i32, align 4
    %2 = add i32 0, 0
    store i32 %2, i32* %1, align 4
    %3 = alloca i32, align 4
    %4 = add i32 0, 1
    store i32 %4, i32* %3, align 4
    %5 = load i32, i32* %1, align 4
    %6 = icmp ne i32 %5, 0
    br i1 %6, label %true0, label %else0
true0:                          ; preds %0
    %7 = add i32 0, 1
    store i32 %7, i32* %3, align 4
    br label %end0
else0:                          ; preds %0
    %8 = load i32, i32* %3, align 4
    %9 = icmp ne i32 %8, 0
    br i1 %9, label %true1, label %end1
true1:                      ; preds %else0
    %10 = add i32 0, 2
    store i32 %10, i32* %3, align 4
    br label %end1
end1:                       ; preds %true1, %else0
    br label %end0
end0:                           ; preds %true0, %else1
    %11 = load i32, i32* %3, align 4
    ret i32 %11
}

но это не так:

define i32 @main() {
    %1 = alloca i32, align 4
    %2 = add i32 0, 0
    store i32 %2, i32* %1, align 4 ; variable a
    %3 = load i32, i32* %1, align 4
    %4 = icmp ne i32 %3, 0
    br i1 %4, label %true0, label %else0
true0: ; preds %0
    %5 = add i32 0, 1
    ret i32 %5
    br label %end0
else0: ; preds %0
    %6 = add i32 0, 2
    ret i32 %6
    br label %end0
end0: ; % preds %true0, %else0
    ret i32 0
}

Я получаю ошибку:

llc-6.0: test2.ll:13:1: error: instruction expected to be numbered '%7'
%6 = add i32 0, 2
^

Я не понимаю, почему этот блок должен быть% 7, учитывая, что ранее использовалось число% 6 , Сравните метку% else0 первого примера, она очень похожа по синтаксису и отлично работает.

И да, мой компилятор нуждается в большой оптимизации, но я еще не закончил:)

1 Ответ

3 голосов
/ 14 февраля 2020

Ваш код недействителен, потому что на самом деле есть еще один базовый c блок, который вы не пометили:

true0: ; preds %0
    %5 = add i32 0, 1
    ret i32 %5
hidden_bb: ; this will named as %6 by default
    br label %end0
else0: ; preds %0

Если у него есть метка, ошибка исчезнет. Обратите внимание, что все инструкции терминатора, такие как br и ret, создадут свой собственный блок basi c.

...