Compiler construction 在LLVM自定义优化过程中删除指令时出现SEGFULT

Compiler construction 在LLVM自定义优化过程中删除指令时出现SEGFULT,compiler-construction,llvm,compiler-optimization,llvm-ir,llvm-c++-api,Compiler Construction,Llvm,Compiler Optimization,Llvm Ir,Llvm C++ Api,这是我写的优化通行证。它将任何以零作为其操作数之一的乘法替换为简单的零 struct FoldConstant : public llvm::FunctionPass { static char ID; FoldConstant() : llvm::FunctionPass(ID) {} bool runOnFunction(llvm::Function &func) override { for (auto &block : func)

这是我写的优化通行证。它将任何以零作为其操作数之一的乘法替换为简单的零

struct FoldConstant : public llvm::FunctionPass {
    static char ID;
    FoldConstant() : llvm::FunctionPass(ID) {}
    bool runOnFunction(llvm::Function &func) override {
        for (auto &block : func) {
            for (auto &inst : block) {
                if (inst.isBinaryOp()) {
                    llvm::Value *left = inst.getOperand(0);
                    llvm::Value *right = inst.getOperand(1);
                    if (inst.getOpcode() == 17) {
                        if (llvm::ConstantInt *lc =
                                llvm::dyn_cast<llvm::ConstantInt>(left)) {
                            if (lc->getSExtValue() == 0) {
                                inst.replaceAllUsesWith(left);
                                inst.eraseFromParent();
                            }
                        }
                        if (llvm::ConstantInt *rc =
                                llvm::dyn_cast<llvm::ConstantInt>(right)) {
                            if (rc->getSExtValue() == 0) {
                                inst.replaceAllUsesWith(right);
                                inst.eraseFromParent();
                            }
                        }
                    }
                }
            }
        }
        return true;
    }
};
它给出一个segfault,下面是堆栈跟踪

sumit@HAL9001:~/Coding/cc$ opt -S -load ./opt.so -foldconst < output.ll
Stack dump:
0.  Program arguments: opt -S -load ./opt.so -foldconst 
1.  Running pass 'Function Pass Manager' on module '<stdin>'.
2.  Running pass 'constant folding' on function '@constant_folding'
 #0 0x00007f5e0522e4ff llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/lib/x86_64-linux-gnu/libLLVM-10.so.1+0x9814ff)
 #1 0x00007f5e0522c7b0 llvm::sys::RunSignalHandlers() (/lib/x86_64-linux-gnu/libLLVM-10.so.1+0x97f7b0)
 #2 0x00007f5e0522eac5 (/lib/x86_64-linux-gnu/libLLVM-10.so.1+0x981ac5)
 #3 0x00007f5e08f563c0 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x153c0)
 #4 0x00007f5e08f73986 llvm::Value::getValueID() const /usr/lib/llvm-10/include/llvm/IR/Value.h:485:12
 #5 0x00007f5e08f73ae2 llvm::Instruction::getOpcode() const /usr/lib/llvm-10/include/llvm/IR/Instruction.h:125:54
 #6 0x00007f5e08f73b04 llvm::Instruction::isBinaryOp() const /usr/lib/llvm-10/include/llvm/IR/Instruction.h:130:46
 #7 0x00007f5e08f74857 FoldConstant::runOnFunction(llvm::Function&) /home/sumit/Coding/cc/c.opt.cpp:75:17
 #8 0x00007f5e05333d76 llvm::FPPassManager::runOnFunction(llvm::Function&) (/lib/x86_64-linux-gnu/libLLVM-10.so.1+0xa86d76)
 #9 0x00007f5e05333ff3 llvm::FPPassManager::runOnModule(llvm::Module&) (/lib/x86_64-linux-gnu/libLLVM-10.so.1+0xa86ff3)
#10 0x00007f5e053344a0 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/lib/x86_64-linux-gnu/libLLVM-10.so.1+0xa874a0)
#11 0x00000000004bf3f8 main (/usr/lib/llvm-10/bin/opt+0x4bf3f8)
#12 0x00007f5e043970b3 __libc_start_main /build/glibc-ZN95T4/glibc-2.31/csu/../csu/libc-start.c:342:3
#13 0x00000000004ad0de _start (/usr/lib/llvm-10/bin/opt+0x4ad0de)
Segmentation fault (core dumped)

但这没什么区别。任何帮助都将不胜感激。

就像对我的问题的评论中指出的@500内部服务器错误一样,SEGFULT是由于我在循环过程中从容器(基本块)中删除元素(指令)而产生的。我现在正在使用下面的代码,它按预期工作

struct FoldConstant : public llvm::FunctionPass {
    static char ID;
    FoldConstant() : llvm::FunctionPass(ID) {}
    bool runOnFunction(llvm::Function &func) override {
        bool changed = false;
        vector<llvm::Instruction *> instsToDelete;

        for (auto &block : func) {
            for (auto &inst : block) {
                if (inst.isBinaryOp()) {
                    llvm::Value *left = inst.getOperand(0);
                    llvm::Value *right = inst.getOperand(1);
                    if (inst.getOpcode() == 17) {
                        if (llvm::ConstantInt *lc =
                                llvm::dyn_cast<llvm::ConstantInt>(left)) {
                            if (lc->getSExtValue() == 0) {
                                instsToDelete.push_back(&inst);
                                inst.replaceAllUsesWith(left);
                                changed = true;
                            }
                        }
                        if (llvm::ConstantInt *rc =
                                llvm::dyn_cast<llvm::ConstantInt>(right)) {
                            if (rc->getSExtValue() == 0) {
                                instsToDelete.push_back(&inst);
                                inst.replaceAllUsesWith(right);
                                changed = true;
                            }
                        }
                    }
                    
                }
            }
        }
        for (auto inst : instsToDelete) {
            inst->eraseFromParent();
        }
        return changed;
    }
};
struct FoldConstant:public llvm::FunctionPass{
静态字符ID;
FoldConstant():llvm::FunctionPass(ID){}
bool runOnFunction(llvm::Function&func)重写{
bool-changed=false;
向量instsToDelete;
用于(自动阻止:func(&B){
用于(自动和安装:块){
if(inst.isBinaryOp()){
llvm::Value*left=inst.getOperator(0);
llvm::Value*right=inst.getOperator(1);
如果(指令getOpcode()==17){
if(llvm::ConstantInt*lc)=
llvm::dyn_演员阵容(左)){
如果(lc->getSExtValue()==0){
instsToDelete.向后推(&inst);
仪表更换(左);
更改=正确;
}
}
if(llvm::ConstantInt*rc)=
llvm::dyn_cast(右)){
如果(rc->getSExtValue()==0){
instsToDelete.向后推(&inst);
仪器替换为(右);
更改=正确;
}
}
}
}
}
}
用于(自动安装:instsToDelete){
inst->ERASETFROMPARENT();
}
回报发生变化;
}
};

我将指向我需要删除的指令的指针存储在一个向量中,并在以后删除它们。

就像对我的问题的评论中指出的@500内部服务器错误一样,segfault是由于我在循环过程中从容器(基本块)中删除元素(指令)而产生的。我现在正在使用下面的代码,它按预期工作

struct FoldConstant : public llvm::FunctionPass {
    static char ID;
    FoldConstant() : llvm::FunctionPass(ID) {}
    bool runOnFunction(llvm::Function &func) override {
        bool changed = false;
        vector<llvm::Instruction *> instsToDelete;

        for (auto &block : func) {
            for (auto &inst : block) {
                if (inst.isBinaryOp()) {
                    llvm::Value *left = inst.getOperand(0);
                    llvm::Value *right = inst.getOperand(1);
                    if (inst.getOpcode() == 17) {
                        if (llvm::ConstantInt *lc =
                                llvm::dyn_cast<llvm::ConstantInt>(left)) {
                            if (lc->getSExtValue() == 0) {
                                instsToDelete.push_back(&inst);
                                inst.replaceAllUsesWith(left);
                                changed = true;
                            }
                        }
                        if (llvm::ConstantInt *rc =
                                llvm::dyn_cast<llvm::ConstantInt>(right)) {
                            if (rc->getSExtValue() == 0) {
                                instsToDelete.push_back(&inst);
                                inst.replaceAllUsesWith(right);
                                changed = true;
                            }
                        }
                    }
                    
                }
            }
        }
        for (auto inst : instsToDelete) {
            inst->eraseFromParent();
        }
        return changed;
    }
};
struct FoldConstant:public llvm::FunctionPass{
静态字符ID;
FoldConstant():llvm::FunctionPass(ID){}
bool runOnFunction(llvm::Function&func)重写{
bool-changed=false;
向量instsToDelete;
用于(自动阻止:func(&B){
用于(自动和安装:块){
if(inst.isBinaryOp()){
llvm::Value*left=inst.getOperator(0);
llvm::Value*right=inst.getOperator(1);
如果(指令getOpcode()==17){
if(llvm::ConstantInt*lc)=
llvm::dyn_演员阵容(左)){
如果(lc->getSExtValue()==0){
instsToDelete.向后推(&inst);
仪表更换(左);
更改=正确;
}
}
if(llvm::ConstantInt*rc)=
llvm::dyn_cast(右)){
如果(rc->getSExtValue()==0){
instsToDelete.向后推(&inst);
仪器替换为(右);
更改=正确;
}
}
}
}
}
}
用于(自动安装:instsToDelete){
inst->ERASETFROMPARENT();
}
回报发生变化;
}
};

我把指针存储在向量中需要删除的指令中,然后删除它们。

这里只问一个基本的C++问题(不是修辞学):<代码> >(Auto & Nist:Bug){< /Cord>支持从C++中从“代码”>块/代码>容器中删除项目的场景?@ 500内部服务器错误。您是对的!这就是问题所在。我四处寻找在C++中循环的时候删除元素的正确方法,但最后还是用了一个更简单的解决方案,以便我的代码是可读的。我将把它作为我的任务的答案。只是问一个基本的C++问题(不是修辞):<代码> >(Auto & Nist:Bug){< /Cord>支持从C++中从“代码”>块/代码>容器中删除项目的场景?@ 500内部服务器错误。您是对的!这就是问题所在。我四处寻找在C++中循环的时候删除元素的正确方法,但最后还是用了一个更简单的解决方案,以便我的代码是可读的。我将把它作为我的任务的答案。离子。
struct FoldConstant : public llvm::FunctionPass {
    static char ID;
    FoldConstant() : llvm::FunctionPass(ID) {}
    bool runOnFunction(llvm::Function &func) override {
        bool changed = false;
        vector<llvm::Instruction *> instsToDelete;

        for (auto &block : func) {
            for (auto &inst : block) {
                if (inst.isBinaryOp()) {
                    llvm::Value *left = inst.getOperand(0);
                    llvm::Value *right = inst.getOperand(1);
                    if (inst.getOpcode() == 17) {
                        if (llvm::ConstantInt *lc =
                                llvm::dyn_cast<llvm::ConstantInt>(left)) {
                            if (lc->getSExtValue() == 0) {
                                instsToDelete.push_back(&inst);
                                inst.replaceAllUsesWith(left);
                                changed = true;
                            }
                        }
                        if (llvm::ConstantInt *rc =
                                llvm::dyn_cast<llvm::ConstantInt>(right)) {
                            if (rc->getSExtValue() == 0) {
                                instsToDelete.push_back(&inst);
                                inst.replaceAllUsesWith(right);
                                changed = true;
                            }
                        }
                    }
                    
                }
            }
        }
        for (auto inst : instsToDelete) {
            inst->eraseFromParent();
        }
        return changed;
    }
};