C++ 如何避免使用'ReplaceInstWithValue()'使迭代器无效?

C++ 如何避免使用'ReplaceInstWithValue()'使迭代器无效?,c++,c++11,clang,llvm,clang++,C++,C++11,Clang,Llvm,Clang++,在下面的程序中,当我使用ReplaceInstWithValue()时,它进入无限循环,因为我用包含add指令的指令序列替换add指令。因此,该程序沿着xor,add,mul 我想问题与插入BasicBlock指令列表的指令有关,即执行迭代的列表 如何解决该问题,以便继续处理列表中的下一个元素,而忽略插入的指令 是将所有插入点放入数据结构并在迭代完成后执行替换的唯一方法吗 #include "llvm/Pass.h" #include "llvm/IR/Function.h" #include

在下面的程序中,当我使用
ReplaceInstWithValue()
时,它进入无限循环,因为我用包含
add
指令的指令序列替换
add
指令。因此,该程序沿着
xor
add
mul

我想问题与插入
BasicBlock
指令列表的指令有关,即执行迭代的列表

如何解决该问题,以便继续处理列表中的下一个元素,而忽略插入的指令

是将所有插入点放入数据结构并在迭代完成后执行替换的唯一方法吗

#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include <map>
#include <string>

using namespace llvm;

namespace {
struct CountOp : public FunctionPass {    
    static char ID;

    CountOp() : FunctionPass(ID) {}

    virtual bool runOnFunction(Function &F) {

        for (Function::iterator bs = F.begin(), be = F.end(); bs != be; ++be) {
            for (BasicBlock::iterator is = bs->begin(), ie = be->end(); is != ie; ++is) {
                Instruction& inst  = *is;
                BinaryOperator* binop = dyn_cast<BinaryOperator>(&inst);
                if (!binop) {
                    continue;
                }
                unsigned opcode = binop->getOpcode();
                errs() << binop->getOpcodeName() << "\n";

                if (opcode != Instruction::Add) {

                    continue;
                }

                IRBuilder<> builder(binop);
                Value* v = builder.CreateAdd(builder.CreateXor(binop->getOperand(0), binop->getOperand(1)), 
                                             builder.CreateMul(ConstantInt::get(binop->getType(), 2), 
                                                               builder.CreateAnd(binop->getOperand(0), binop->getOperand(1))));

                ReplaceInstWithValue(bs->getInstList(), is, v);
            } 
        }

        errs() << "\n";
        return true;
    }
};
}

char CountOp::ID = 0;
static RegisterPass<CountOp> X("opCounter", "Counts opcodes per functions", false, false);
#包括“llvm/Pass.h”
#包括“llvm/IR/Function.h”
#包括“llvm/IR/BasicBlock.h”
#包括“llvm/IR/Instructions.h”
#包括“llvm/IR/IRBuilder.h”
#包括“llvm/Support/raw_ostream.h”
#包括“llvm/Transforms/Utils/BasicBlockUtils.h”
#包括
#包括
使用名称空间llvm;
名称空间{
结构CountOp:public FunctionPass{
静态字符ID;
CountOp():FunctionPass(ID){}
虚拟布尔运行函数(函数&F){
对于(函数::迭代器bs=F.begin(),be=F.end();bs!=be;++be){
对于(基本块::迭代器is=bs->begin(),ie=be->end();is!=ie;++is){
指令和指令=*is;
二进制运算符*binop=dyn_cast(&inst);
如果(!binop){
继续;
}
无符号操作码=binop->getOpcode();
errs()getOpcodeName()getOperator(0),binop->getOperator(1)),
CreateMul(ConstantInt::get(binop->getType(),2),
CreateAnd(binop->getOperand(0),binop->getOperand(1));
ReplaceInstWithValue(bs->getInstList(),is,v);
} 
}

errs()正如w1ck3dg0ph3r所指出的,当应该递增
bs
时,在外部循环中递增
be
。这应该可以解决无限循环的问题。
llvm::IRBuilder
在迭代器指向构造函数的指令之前插入指令,因此不需要进行任何其他更改anges.

为什么要在外循环中增加?这是基本块。实际上,更改为
++bs
并不能解决问题。我仍然会进入无限循环。你是否建议我用其他东西替换
ReplaceInstWithValue
?这很奇怪。你记得重新编译你的通行证吗?你能提供一个例子吗VM IR input?我自己测试过,效果很好:我稍后会上传,但它基本上只是一个简单的.ll文件,包含一个主函数、两个变量、变量的添加和结果的返回。是的,我重新编译了:)