<div dir="ltr">Hi Dean,<div><br></div><div>Thanks for your reply.</div><div><br></div><div>That's exactly what I am doing, but I was looking for a default optimization or pass implementation if there was.</div><div><br></div><div>I used BasicBlock::splitBasicBlock() but it puts "br" end of original basic block. I tried to delete the br instruction by using eraseFromParent() but it didn't work.</div><div><br></div><div>I had to rewrite my own splitBasicBlock() by modifying the original one. Just removed the br instruction creation lines.</div><div><br></div><div><div>>> Just curious, how are you getting return instructions in the middle of a basic block?<div>My code generation pass allows multiple return instruction generation since that simplifies front-end significantly.<br></div></div><div><br></div><div>Here is the code if anyone would like to use it:</div><div><br></div><div><font face="monospace, monospace">void CodeGenPass::DeleteDeadCode(llvm::BasicBlock * basicBlock)<br></font></div><div><div><font face="monospace, monospace">{</font></div><div><font face="monospace, monospace"> for (auto it = basicBlock->begin(); it != basicBlock->end(); ++it)</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> // Split after first return instruction.</font></div><div><font face="monospace, monospace"> if (it->getOpcode() == llvm::Instruction::Ret)</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> ++it;</font></div><div><font face="monospace, monospace"> // Split only if there is a following instruction.</font></div><div><font face="monospace, monospace"> if (it != basicBlock->getInstList().end())</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> auto deadCodeBlock = SplitBasicBlock(basicBlock, it);</font></div><div><span style="font-family:monospace,monospace"> deadCodeBlock->eraseFromParent();</span><br></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"> return;</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace">}</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">llvm::BasicBlock * CodeGenPass::SplitBasicBlock(llvm::BasicBlock * basicBlock, llvm::BasicBlock::iterator it)</font></div><div><font face="monospace, monospace">{</font></div><div><font face="monospace, monospace"> assert(basicBlock->getTerminator() && "Block must have terminator instruction.");</font></div><div><font face="monospace, monospace"> assert(it != basicBlock->getInstList().end() && "Can't split block since there is no following instruction in the basic block.");</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> auto newBlock = llvm::BasicBlock::Create(basicBlock->getContext(), "splitedBlock", basicBlock->getParent(), basicBlock->getNextNode());</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> // Move all of the instructions from original block into new block.</font></div><div><font face="monospace, monospace"> newBlock->getInstList().splice(newBlock->end(), basicBlock->getInstList(), it, basicBlock->end());</font></div><div><font face="monospace, monospace"><br></font></div><div><span style="font-family:monospace,monospace"> // Now we must loop through all of the successors of the New block (which</span><br></div><div><font face="monospace, monospace"> // _were_ the successors of the 'this' block), and update any PHI nodes in</font></div><div><font face="monospace, monospace"> // successors. If there were PHI nodes in the successors, then they need to</font></div><div><font face="monospace, monospace"> // know that incoming branches will be from New, not from Old.</font></div><div><font face="monospace, monospace"> //</font></div><div><font face="monospace, monospace"> for (llvm::succ_iterator I = llvm::succ_begin(newBlock), E = llvm::succ_end(newBlock); I != E; ++I)</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> // Loop over any phi nodes in the basic block, updating the BB field of</font></div><div><font face="monospace, monospace"> // incoming values...</font></div><div><font face="monospace, monospace"> llvm::BasicBlock *Successor = *I;</font></div><div><font face="monospace, monospace"> for (auto &PN : Successor->phis())</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> int Idx = PN.getBasicBlockIndex(basicBlock);</font></div><div><font face="monospace, monospace"> while (Idx != -1)</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> PN.setIncomingBlock((unsigned)Idx, newBlock);</font></div><div><font face="monospace, monospace"> Idx = PN.getBasicBlockIndex(basicBlock);</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"> }</font></div><div><br></div><div><font face="monospace, monospace"> return newBlock;</font></div><div><font face="monospace, monospace">}</font></div></div><div><br></div><div><br></div><div>Best,</div><div> </div><div>Aaron</div><div><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, May 24, 2018 at 9:22 AM, Dean Michael Berris <span dir="ltr"><<a href="mailto:dean.berris@gmail.com" target="_blank">dean.berris@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><span class="gmail-"><br>
<br>
> On 25 May 2018, at 01:46, Aaron via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br>
> <br>
> Hi all,<br>
> <br>
> LLVM optimization pass gives an error "Terminator found in the middle of a basic block!" since basic block IR may have multiple "ret" instructions. It seems LLVM does not accept multiple return in a basic block by default. <br>
> <br>
<br>
</span>Yes, if you’re inserting terminators in a basic block at the IR level, you’re going to have to split it into two different blocks yourself. Essentially you’re encountering a legaliser failure here — it’s an invariant of a BasicBlock that there are no terminator instructions in the body, and the last instruction should be a terminator.<br>
<span class="gmail-"><br>
> Is there a specific optimization or pass that I can enable to remove unreachable codes in basic blocks?<br>
> <br>
<br>
</span>If you’re writing your own pass, you can do this yourself — after you insert the return instruction, just delete the rest of the instructions in the basic block after that instruction.<br>
<br>
Just curious, how are you getting return instructions in the middle of a basic block?<br>
<br>
> Best,<br>
> <br>
> Aaron<br>
> <br>
> ______________________________<wbr>_________________<br>
> LLVM Developers mailing list<br>
> <a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><br>
<span class="gmail-HOEnZb"><font color="#888888"><br>
-- Dean<br>
<br>
</font></span></blockquote></div><br></div></div></div>