Прохождение LLVM с циклическим инвариантным кодом (-licm) - PullRequest
0 голосов
/ 05 ноября 2018

У меня есть простой код цикла C, и я хочу упростить это максимально . Вот оригинальный файл C:

#include <stdio.h>

char *foo(char *s)
{
    while (*s == 'a' || *s == 'b')
    {
        s++;
    }
    return s;
}

int main(int argc, char **argv)
{
    char *s1 = argv[1];
    char *s2 = foo(s1);
    return 0;
}

Я пытался использовать opt с флагом -licm, который должен:

удалить как можно больше кода из тела цикла. Это делается путем поднятия кода в блок предварительного заголовка

Но когда я смотрю на тело цикла, я вижу, что строки 21 и 22 действительно избыточны , так как %s.addr не не изменился, и поэтому строки 21 и 22 могут можно безопасно удалить, и вместо %tmp3 мы можем использовать %tmp1 из строки 23 вперед.

 13 while.cond:                                       ; preds = %while.body, %entry
 14   %tmp = load i8*, i8** %s.addr, align 8
 15   %tmp1 = load i8, i8* %tmp, align 1
 16   %conv = sext i8 %tmp1 to i32
 17   %cmp = icmp eq i32 %conv, 97
 18   br i1 %cmp, label %lor.end, label %lor.rhs
 19 
 20 lor.rhs:                                          ; preds = %while.cond
 21   %tmp2 = load i8*, i8** %s.addr, align 8
 22   %tmp3 = load i8, i8* %tmp2, align 1
 23   %conv2 = sext i8 %tmp3 to i32
 24   %cmp3 = icmp eq i32 %conv2, 98
 25   br label %lor.end

Что мне не хватает? есть ли другой проход для достижения этой цели?

1 Ответ

0 голосов
/ 05 ноября 2018

Вам не хватает того, что %s.addr не является инвариантом в цикле while. Оптимизация движения кода инвариантного цикла идентифицирует выражения, которые не меняются между итерациями, и пытается вывести их из цикла. То, что вы ищете, - это что-то вроде устранения общего подвыражения Эта оптимизация идентифицирует повторное вычисление одного и того же подвыражения и пытается удалить все, кроме одного. В моей версии opt эта оптимизация включается переключателем -early-cse.

...