2017-09-04 67 views
0

以下是我在LLVM LoopPass中的代码。在LLVM LOOP PASS中,我想复制并粘贴一组指令。复制icmp和分支指令时发生错误

virtual bool runOnLoop(Loop* L, LPPassManager &LPM) { 
    BasicBlock& loopCondBlock = *(L->getHeader()); 
    BasicBlock& loopIncBlock = *(L->getLoopLatch()); 
    BranchInst* brInsInLoopInc = dyn_cast<BranchInst>(loopIncBlock.getTerminator()); 
    for (auto &inst: loopCondBlock) { 
     auto *new_inst = inst.clone(); 
     new_inst->insertBefore(brInsInLoopInc); 
     llvm::ValueToValueMapTy vmap; 
     llvm::RemapInstruction(new_inst, vmap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); 
    } 
    return true; 
} 

我想在for.cond中复制指令并将它们粘贴到for.inc上,然后再转到for.cond指令。

例原IR:

for.cond:           ; preds = %for.inc, %entry 
    %0 = load i32, i32* %i, align 4 
    %cmp = icmp ult i32 %0, 50000000 
    br i1 %cmp, label %for.body, label %for.end 

for.body:           ; preds = %for.cond 
    ... 

for.inc:           ; preds = %for.body 
    ... 
    br label %for.cond 

IR预计:

for.cond:           ; preds = %for.inc, %entry 
    %0 = load i32, i32* %i, align 4 
    %cmp = icmp ult i32 %0, 50000000 
    br i1 %cmp, label %for.body, label %for.end 

for.body:           ; preds = %for.cond 
    ... 

for.inc:           ; preds = %for.body 
    ... 
    // ******PASS ADDED****** 
    %4 = load i32, i32* %i, align 4 
    %cmp2 = icmp ult i32 %4, 50000000 
    br i1 %cmp2, label %for.body, label %for.end 
    // ******PASS ADDED****** 

我的循环及格成绩:

for.cond:           ; preds = %for.inc, %entry 
    %0 = load i32, i32* %i, align 4 
    %cmp = icmp ult i32 %0, 50000000 
    br i1 %cmp, label %for.body, label %for.end 

for.body:           ; preds = %for.inc, %for.cond 
    ... 

for.inc:           ; preds = %for.body 
    ... 
    // ******PASS ADDED****** 
    %4 = load i32, i32* %i, align 4 
    %5 = icmp ult i32 %0, 50000000 
    br i1 %cmp, label %for.body, label %for.end 
    // ******PASS ADDED****** 
    br label %for.cond 

如何修复ICMP和相关的分支指令是正确的,删除“br标签%for.cond”?

谢谢你的帮助。

回答

0

我觉得你忘了实际上将值填充到重映射调用中使用的值映射中,映射从原始映射到副本。

根据the manual,删除说明应通过调用eraseFromParent来工作。

此代码是未经测试,所以它可能会包含错误,但它应该传达的理念:

virtual bool runOnLoop(Loop* L, LPPassManager &LPM) { 
    BasicBlock& loopCondBlock = *(L->getHeader()); 
    BasicBlock& loopIncBlock = *(L->getLoopLatch()); 
    BranchInst* brInsInLoopInc = dyn_cast<BranchInst>(loopIncBlock.getTerminator()); 
    llvm::ValueToValueMapTy vmap; 
    for (auto &inst: loopCondBlock) { 
     auto *new_inst = inst.clone(); 
     new_inst->insertBefore(brInsInLoopInc); 
     // map each instruction to its copy 
     vmap[&inst] = new_inst; 
     // now this should remap each instruction to its copy 
     llvm::RemapInstruction(new_inst, vmap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); 
    } 
    // now erase the original branch 
    brInsInLoopInc->eraseFromParent(); 
} 
+0

谢谢你。我在另一篇文章中看到了这一点,但是它在这一行“vmap [inst] = newInst;”上造成了更多的错误。 –

+0

看到编辑,我忘了“&”。如果您发布了错误消息,我可以早点解决这个问题:-) – PaulR

+0

感谢您的回复。但它也会产生如下错误的IR: “%5 = icmp ult i32%0,50000000”和“br i1%5,标签%for.body,标签%for.end”。它应该使用%cmp进行更正。 –

0

我解决我的问题,只是添加下面的代码后“inst.clone();”。

if(inst.hasName()) { 
    new_inst->setName(inst.getName()+NameSuffix); 
}