替换LLVM IR中的指令
Replacing instructions in LLVM IR
我写了一段代码,通过创建Value*将LLVM IR中的add指令替换为子指令。我正试图用%5 = sub i8 0, %4
代替%inc = add i8 %2, 1
。
我的问题是如何使更改出现在LLVM IR文件?我可以在屏幕上打印新值*,但不能在LLVM IR文件中打印。
for (auto &B : F) {
for (BasicBlock::iterator DI = B.begin(); DI != B.end(); ) {
Instruction *Inst = &*DI++;
if (auto *op = dyn_cast<BinaryOperator>(&*Inst)) {
// Insert at the point where the instruction `op` appears.
IRBuilder<> builder(op);
std::string opcd,opcd_change;
opcd=Inst->getOpcodeName();
// Make a multiply with the same operands as `op`.
srand((unsigned)time(NULL));
if (opcd=="add"){
errs() <<"instruction ";
Inst->print(errs());
//errs() <<'n'<<"instruction opcode changed"<<opcd_change<<'n';
errs() <<" instruction opcode "<<opcd<<'n';
Value *lhs = op->getOperand(0);
Value *rhs = op->getOperand(1);
Instruction* neg = BinaryOperator::CreateNeg(rhs);
errs() <<"instruction opcode changed "<<opcd_change<<'n';
Instruction* newInst = BinaryOperator::CreateSub(lhs, neg, "test");
errs() << "NewInst:n" << *newInst << "n";
ReplaceInstWithInst(op,newInst);
errs()<< "Instruction replaced ";
errs() <<'n'<<'n';
}
}
}
}
我无法理解这个错误是什么意思。我对LLVM相当陌生,所以我不明白它的意思。**编辑显示使用ReplaceInstWithInst后的错误**
'opt: /home/zainub/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp:211: void llvm::ReplaceInstWithInst(llvm::BasicBlock::InstListType&, llvm::BasicBlock::iterator&, llvm::Instruction*): Assertion `I->getParent() == nullptr && "ReplaceInstWithInst: Instruction already inserted into basic block!"' failed.
#0 0x00000000027abd3a llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/usr/local/bin/opt+0x27abd3a)
#1 0x00000000027ac08e PrintStackTraceSignalHandler(void*) (/usr/local/bin/opt+0x27ac08e)
#2 0x00000000027aa4e6 llvm::sys::RunSignalHandlers() (/usr/local/bin/opt+0x27aa4e6)
#3 0x00000000027ab687 SignalHandler(int) (/usr/local/bin/opt+0x27ab687)
#4 0x00007fbb71d32d10 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x10d10)
#5 0x00007fbb71160267 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x35267)
#6 0x00007fbb71161eca abort (/lib/x86_64-linux-gnu/libc.so.6+0x36eca)
#7 0x00007fbb7115903d (/lib/x86_64-linux-gnu/libc.so.6+0x2e03d)
#8 0x00007fbb711590f2 (/lib/x86_64-linux-gnu/libc.so.6+0x2e0f2)
#9 0x00000000027cfa1c llvm::ReplaceInstWithInst(llvm::SymbolTableList<llvm::Instruction>&, llvm::ilist_iterator<llvm::Instruction>&, llvm::Instruction*) (/usr/local/bin/opt+0x27cfa1c)
#10 0x00000000027cfb2b llvm::ReplaceInstWithInst(llvm::Instruction*, llvm::Instruction*) (/usr/local/bin/opt+0x27cfb2b)
#11 0x00007fbb70f1d027 (anonymous namespace)::Fundep::runOnFunction(llvm::Function&) /home/zainub/llvm/lib/Transforms/Fundep/Fundep.cpp:161:0
#12 0x0000000002246841 llvm::FPPassManager::runOnFunction(llvm::Function&) (/usr/local/bin/opt+0x2246841)
#13 0x00000000022469f8 llvm::FPPassManager::runOnModule(llvm::Module&) (/usr/local/bin/opt+0x22469f8)
#14 0x0000000002246db5 (anonymous namespace)::MPPassManager::runOnModule(llvm::Module&) (/usr/local/bin/opt+0x2246db5)
#15 0x0000000002247539 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/usr/local/bin/opt+0x2247539)
#16 0x0000000002247779 llvm::legacy::PassManager::run(llvm::Module&) (/usr/local/bin/opt+0x2247779)
#17 0x00000000010583e9 main (/usr/local/bin/opt+0x10583e9)
#18 0x00007fbb7114ba40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20a40)
#19 0x0000000001033119 _start (/usr/local/bin/opt+0x1033119)
Stack dump:
0. Program arguments: /usr/local/bin/opt -load /home/zainub/build/lib/LLVMFundep.so -Fundep
1. Running pass 'Function Pass Manager' on module '<stdin>'.
2. Running pass 'Fundep Pass' on function '@main'
Aborted (core dumps)
Edit-2
生成有问题的IR
instruction %add115 = add i64 %86, 20 instruction opcode add
NewInst:
%test = sub i64 %86, <badref>
op %add115 = add i64 %86, 20
Instruction replaced %test = sub i64 %86, <badref>
我不知道为什么你的代码片段不起作用,但在任何情况下,用另一条指令替换一条指令的规范方法是使用ReplaceInstWithInst。
Instruction
子类Value
和BinaryOperation
子类Instruction
,所以ReplaceInstWithInst的第一个参数将只是你的op
。第二个参数应该是CreateSub的返回值——你可以把它dyn_cast到一个Instruction
,它很可能会成功。
有一个机会CreateSub将返回的东西不是一个指令,虽然,万一编译器设法折叠你的新创建的指令更简单的东西(例如一个常数)。如果这种情况是你关心的,使用ReplaceInstWithValue代替,传递你的B->getInstList()
和DI
。
相关文章:
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- C++:对不存在的命名空间使用命名空间指令
- 函数名是c中该函数的第一条指令的地址吗
- 错误:无效的预处理指令 #i 的意思是 #if?
- 组装指令中乘法的下部和上部是什么
- OpenMP 与有序和关键指令并行
- C++中的移动分配出现问题.非法指令: 4.
- 嵌套命名空间的"using"指令,但需要命名内部命名空间
- C++CMake编译指令与
- 使用宏扩展的泛型:为什么指令缓存使用不当?
- 如何在 c++ 中确定一条指令(以字节为单位)在哪里结束,另一条指令从哪里开始?
- AVX 指令中寄存器和指针之间的客观差异
- while 循环 c++ 中的非法指令
- 如何在编译时定义C++预处理器指令的值?
- LLVM 编译:目标的配方 '../lib/IR/Release+Asserts/Intrinsics.gen.tmp' failed
- LLVM IR:具有可变基本块目标的分支指令
- 如何在LLVM IR中检查指令是否为PHI指令
- 如何为llvm IR调用指令创建结构参数
- 替换LLVM IR中的指令