2016-11-17 217 views
3

我編寫了一個代碼,它可以通過創建值*來替代LLVM IR中的添加指令和子指令。我試圖用%5 = sub i8 0, %4替換%inc = add i8 %2, 1替換LLVM IR中的指令

我的問題是如何使更改顯示在LLVM IR文件中?我可以在屏幕上打印新的Value *,但不能在我的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' 

中止(核心轉儲)

編輯-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> 
+0

您是否嘗試過使用[ReplaceInstWithInst](http://llvm.org/docs/doxygen/html/namespacellvm.html#a58cb353f6bb490b0c689f5f2a830414d)? – Oak

+0

我很新,所以我只是在嘗試。我必須用減法指令替換加法指令。在這種情況下,我有Value * sub有我的新指令。我如何在ReplaceInstWithInst中使用Value *?你能幫我一下嗎? –

回答

1

我不確定爲什麼你的代碼段不起作用,但無論如何,這是取代規範的方法一條指令與另一條指令使用ReplaceInstWithInst

Instruction sublasses ValueBinaryOperationInstruction,所以第一個參數ReplaceInstWithInst將只是你的op。第二個參數應該是CreateSub的返回值 - 你可以dyn_cast到Instruction,它可能會成功。

但是,如果編譯器設法將新創建的指令摺疊到更簡單的(例如常量),CreateSub會返回一些不是指令的東西。如果您遇到這種情況,請使用ReplaceInstWithValue,並將其傳遞給您B->getInstList()DI

+0

我編輯了問題後,使用ReplaceInstWithInst後顯示錯誤。請檢查。 –

+0

@MBaloch問題在於,您作爲ReplaceInstWithInst的第二個參數提供的指令已經放置在某個基本塊中。如果你更新你的問題中的代碼,我可以看看它。 – Oak

+0

嘿,對不起橡樹,我剛剛檢查了你的回覆,因爲我正在忙於另一個模塊的工作,我更新了代碼。錯誤仍然保持不變 –