Я работаю над анализом использованных инструкций. Учитывая, что я нашел интересную инструкцию, я хочу отменить все использованные операции и переменные . Например, следующий цикл в LLVM IR.Операции и операнды Backtrack в LLVM
%i.01 = phi i32 [ 0, %0 ], [ %4, %2 ]
%3 = icmp eq i32 %i.01, 0
%bar.foobar.i = select i1 %3, void()* @bar, void()* @foobar
tail call void %bar.foobar.i() #2
%4 = add nuw nsw i32 %i.01, 1
%exitcond = icmp eq i32 %4, 10
br i1 %exitcond, label %1, label %2
Мне интересно, например, во всех задействованных данных в последней ветке. Условие вычисляется одной инструкцией перед использованием ICompInst
, которая включает переменную %4
и константу 10
. %4
вычисляется на один шаг перед использованием добавления. И так далее и т. Д. ...
Учитывая, что я нашел интересующую нас инструкцию, в данном случае BranchInst
, я хочу начать обратный путь.
if(BranchInst* BI = dyn_cast<BranchInst>(&I)) {
if(BI->isConditional()) {
backtrack(BI, &I);
}
}
Для реализации такого алгоритма у меня есть два вопроса. Имея инструкцию ветвления, как я могу получить условие для начала обратного отслеживания? Во-вторых, как я могу определить, используется ли условие в предыдущей инструкции? Чтобы понять это проще, у меня есть следующий код псевдо:
void backtrack(BranchInst* BI, Instruction* I) {
Value* condition = BI->getCondition();
Instruction* prevInst = I;
do {
prevInst = prev(prevInst);
if(prevInst->prevInst(condition)) {
backTrackOperand(prevInst->getOperand(0), prevInst);
backTrackOperand(prevInst->getOperand(1), prevInst);
break;
}
} while(1);
}
void backTrackOperand(Value* operand, Instruction* I) {
Instruction* prevInst = I;
do {
prevInst = prev(prevInst);
if(prevInst->usesOperand(operand)) {
...
}
}
}
Так как я мог реализовать функцию getCondition()
, computesCondition()
и usesOperand()
?