Прямой ответ на ваш вопрос - поместить этот код в пользовательский FunctionPass
:
virtual bool runOnFunction(Function &F) {
for (Function::iterator bb = F.begin(), bb_e = F.end(); bb != bb_e; ++bb) {
for (BasicBlock::iterator ii = bb->begin(), ii_e = bb->end(); ii != ii_e; ++ii) {
if (CmpInst *cmpInst = dyn_cast<CmpInst>(&*ii)) {
handle_cmp(cmpInst);
}
}
}
return false;
}
void handle_cmp(CmpInst *cmpInst) {
if (cmpInst->getPredicate() == CmpInst::ICMP_SGT) {
errs() << "In the following instruction, SGT predicate\n";
cmpInst->dump();
}
}
В последнее время вы, похоже, задаете много подобных вопросов, поэтому я хочу датьболее общий совет.
Каждая инструкция, которую вы видите в LLVM IR, является просто текстовым представлением класса команд, который существует в базе кода LLVM.В этом случае icmp
представляет ICmpInst
, который является подклассом CmpInst
.Как только вы узнаете, что имеете дело с CmpInst
, легко увидеть, как получить доступ к его атрибутам, просто прочитав объявление класса в заголовочном файле.Например, очевидно, что параметр «предиката» этой инструкции представляет sgt
и другие предикаты.
Но как узнать, на какой класс смотреть.Это легко сделать с помощью бэкэнда LLVM C ++, который выводит эквивалентный код C ++, необходимый для создания некоторого IR.Например, учитывая этот кусок IR:
%0 = load i32* %argc.addr, align 4
%cmp = icmp sgt i32 %0, 0
Он сбросит:
LoadInst* int32_19 = new LoadInst(ptr_argc_addr, "", false, label_entry_15);
int32_19->setAlignment(4);
ICmpInst* int1_cmp = new ICmpInst(*label_entry_15, ICmpInst::ICMP_SGT, int32_19, const_int32_8, "cmp");
BranchInst::Create(label_if_then, label_if_else, int1_cmp, label_entry_15);
Так что, просто взглянув на него, вы знаете, что вам нужно ICmpInst
, а такжепредикат ICMP_SGT
.
Чтобы запустить бэкэнд C ++ для некоторого текстового IR в .ll
файле, вы просто делаете:
llc -march=cpp -cppgen=program irfile.ll
Надеюсь, это поможет!