2017-06-12 90 views
0

我试图删除一系列指令(在[startIns,endIns之间指定))。 endIns可能与开始时不在同一个基本块中。删除llvm中的一系列指令

我不断收到试图删除最后一个指令时,下面的错误 - 参考LLVM :: ilist_iterator,假的,假> ::运算符*()const的[OptionsT = LLVM :: ilist_detail :: node_options,IsReverse = false,IsConst = false]:声明`!NodePtr-> isKnownSentinel()'失败。

以下是我的C++代码 -

//删除之间的[开始所有指令,结束)

// startInst是在下面IR "%res = alloca i8 "

// endInst是"%resclone0 = alloca i10"在下面IR。

void deleteAllInstructionsInRange(Instruction* startInst,Instruction* endInst) 
    { 
     BasicBlock::iterator it(startInst); 
     BasicBlock::iterator it_end(endInst); 

     Instruction* currentInst ; 

     while(it != it_end) 
     { 
      currentInst = &*it; 

      ++it; 


      if (!currentInst->use_empty()) 
      { 
       currentInst->replaceAllUsesWith(UndefValue::get(currentInst->getType())); 
      } 

      currentInst->eraseFromParent(); 

     } 



    } 

以下是相关的IR

define i32 @test2() { 
entry: 
    %calltmp = call i32 @UInt() 
    %datasize = alloca i32 
    switch i32 %calltmp, label %sw.bb.0 [ 
    i32 1, label %sw.bb.1 
    i32 2, label %sw.bb.2 
    i32 3, label %sw.bb.3 
    ] 
; %res = alloca i8      ===> deleted 
    ;store i8 0, i8* %res     ===> deleted 
    ;%datasize1 = load i32, i32* %datasize ===> deleted 

    ret i32 %datasize1      ===> UNABLE to delete 

sw.bb.0:           ; preds = %entry 
    %resclone0 = alloca i10 
    store i10 0, i10* %resclone0 
    %datasize1clone0 = load i32, i32* %datasize 

任何帮助将不胜感激。

谢谢。

回答

0

首先看看this答案,以了解什么是KnownSentinel()的意思。

我的猜测是,由于您在修改基本块的同时迭代它,这是不安全的,并且您正在收到错误。

+0

我已经知道什么是定点的LLVM,和你有关的事实,我修改了正确的BB,同时迭代。因此我简单地将指令存储在一个向量中,并在稍后删除它们。 – mal

0

我的猜测是ret终止符并删除它会使IR无效。 引用this question

每个基本块必须以终止符结束。

我建议用uncondicional跳代替终止指令到下一个块(未测试):

if (currentInst->isTerminator()) { 
    // works only if block has only one successor 
    currentInst->replaceAllUsesWith(
     builder->CreateBr(
      builder->GetInsertBlock()->getSingleSuccessor())); 
}