Предположите инструкцию add
. У вас есть BinaryOperator
, который имеет два операнда, например:. %op = add i32 10, 32
Вы берете их как Value *lhs = op->getOperand(0);
и Value *rhs = op->getOperand(1);
Так тариф так хорошо. Теперь вы создаете две новые команды add
перед фактическим добавлением, так как вы строите свой IRBuilder
с опцией в качестве точки вставки.
%add1 = add i32 10, 32
%add2 = add i32 10, 32
%op = add i32 10, 32
Наконец вы обновляете пользователей исходной инструкции, например, что-то вроде другой BinaryOperator
: %0 = mul i32 %op, %op
Когда вы посмотрите внимательно на вашем цикле вы увидите, что вы установили оба (add1 и add2) к тому же операндом Пользователя. После вашего цикла умножение будет выглядеть %0 = mul i32 %add2, %add2
Если сбросить BasicBlock
где инструкции вставлены непосредственно после установки, вы должны увидеть что-то вроде:
%add1 = add i32 10, 32
%add2 = add i32 10, 32
%op = add i32 10, 32
%0 = mul i32 %add2, %add2
Но если запустить другой LLVM Pass, выполняющие мертвыми устранение кода (например, InstCombine), вы будете в конечном итоге с:
%add2 = add i32 10, 32
%0 = mul i32 %add2, %add2
Поскольку add1
не имеет пользователей. Вы немедленно заменили использование add1
на add2
. И op также ушел, потому что теперь все пользователи используют add2
вместо op
.
С вашего вопроса трудно угадать, что вы намеревались с вашим кодом, но вот почему вы увидите только одну из своих инструкций в финальном IR.
Большое спасибо, лучше используйте clone() для репликации инструкций –