2016-09-16 10 views
0

Я работаю над анализом использованных инструкций. Учитывая, что я нашел интересную инструкцию, я хочу отменить все использованные операции и переменные . Например, следующий цикл в 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()?

ответ

0
  • getCondition() is getOperand (0).
  • Я не вижу computesCondition() в вашем коде?
  • usesOperand() что-то вроде llvm::find_if(prevInst->operands(), [&] (Uses &U) { return isa<Instruction>(&U) && cast<Instruction>(&U) == I; });. Но обратите внимание также, что из условного или любого значения вы можете легко найти все виды использования.