【问题标题】:deleting a range of instructions in llvm删除llvm中的一系列指令
【发布时间】:2017-06-12 16:07:11
【问题描述】:

我正在尝试删除一系列指令(指定为 [startIns , endIns) 之间)。 endIns 可能与 start 不在同一个基本块中。

尝试删除最后一条指令时,我不断收到以下错误 - reference llvm::ilist_iterator, false, false>::operator*() const [OptionsT = llvm::ilist_detail::node_options, IsReverse = false, IsConst = false]: 断言 `!NodePtr->isKnownSentinel()'失败。

以下是我的 C++ 代码 -

//删除[start,end)之间的所有指令

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

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

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

任何帮助将不胜感激。

谢谢。

【问题讨论】:

    标签: llvm instructions


    【解决方案1】:

    首先看一下this 的答案以了解isKnownSentinel() 的含义。

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

    【讨论】:

    • 我已经知道 sentinel 对 llvm 意味着什么,并且您对我在迭代时修改 BB 的事实是正确的。因此,我只是将指令存储在一个向量中,然后再删除它们。
    【解决方案2】:

    我的猜测是 ret 是一个终结者,删除它会使 IR 无效。 引用this question:

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

    我建议将终止符指令替换为无条件跳转到下一个块(未测试):

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-20
      • 2015-12-15
      • 1970-01-01
      • 2017-09-04
      相关资源
      最近更新 更多