Есть ли способ избежать удаления дублирующейся инструкции загрузки при компиляции с использованием LLVM
Я работаю над созданием проходного модуля LLVM. Итак, в основном мне нужно продублировать все инструкции по загрузке и сохранить в другом реестре. При значении -O0 для инструмента clang, opt и llc эта дублированная инструкция загрузки удаляется. Я посмотрел на окончательную сборку, используя objdump, я мог видеть, что дублирующая инструкция загрузки была удалена. Я хочу решение, которое как-то не удаляет дубликат загрузки инструкции.
Фактическая программа на С есть,
int main(){
int* p = (int *)(0x600000);//Some address
int x=0x01, y=0x01;
int z;
z=x+y;
*p=z;
}
Соответствующий ИК есть,
define i32 @main() #0 {
entry:
%p = alloca i32*, align 8
%x = alloca i32, align 4
%y = alloca i32, align 4
%z = alloca i32, align 4
store i32* inttoptr (i64 6291456 to i32*), i32** %p, align 8
store i32 1, i32* %x, align 4
store i32 1, i32* %y, align 4
%0 = load i32, i32* %x, align 4
%1 = load i32, i32* %y, align 4
%add = add nsw i32 %0, %1
store i32 %add, i32* %z, align 4
%2 = load i32, i32* %z, align 4
%3 = load i32*, i32** %p, align 8
store i32 %2, i32* %3, align 4
ret i32 0
}
Но когда мой проход включен, этот IR изменится, и я дублирую только инструкции по загрузке с адресом загрузки, являющимся одним и тем же запоминающим устройством, даже для дублированной загрузки.
Измененный IR будет,
define i32 @main() #0 {
entry:
%p = alloca i32*, align 8
%x = alloca i32, align 4
%y = alloca i32, align 4
%z = alloca i32, align 4
store i32* inttoptr (i64 6291456 to i32*), i32** %p, align 8
store i32 1, i32* %x, align 4
store i32 1, i32* %y, align 4
%0 = load i32, i32* %x, align 4
%1 = load i32, i32* %y, align 4
%2 = load i32, i32* %x, align 4 //Added
%3 = load i32, i32* %y, align 4 //Added
%add = add nsw i32 %0, %1
store i32 %add, i32* %z, align 4
%4 = load i32, i32* %z, align 4
%5 = load i32*, i32** %p, align 8
%6 = load i32, i32* %z, align 4 //Added
%7 = load i32*, i32** %p, align 8 //Added
store i32 %4, i32* %5, align 4
ret i32 0
}
Я могу видеть измененный IR на уровне IR, но не на уровне окончательной сборки после llc. Я думаю, что ООО удаляет все дублированные нагрузки. Как мне остановить ООО от удаления?
Примечание: я попытался сделать все переменные изменчивыми. Для этого это работает, я могу видеть дублированные нагрузки после ООО. Но это не правильное решение. Я не могу сделать все тысячи переменных изменчивыми:(.