<div dir="ltr"><div><div>> I’m just wondering why not have a ‘br’ to an exit basic block instead of ‘ret’ mid-stream of instructions.</div><div>> Have you considered this approach instead?</div><div><br></div><div><div>Thanks for bringing this up.</div></div><div><br></div><div>Yes. In fact, I tried that approach/pattern first. Simply, you create default exit block and a local return variable (to track return value) per function, but it requires extra flags and variables to track function exit block and return value anytime during code generation (which my approach does not need to do these). </div><div><br></div><div>When generating code, every time you see a return instruction, you store return value into that local variable (if it returns a value) and create branch instruction to function's exit block. Then function can generate return instruction by using local return variable or just ret void.</div><div><br></div><div>entry:</div><div>  <this is the entry block></div><div>  <alloc local return variable></div><div>  <…></div><div>  <store return value into local return variable, if returns a value></div><div>  br .exit</div><div><br></div><div>.bb0:</div><div>  <this is by definition unreachable></div><div>  <…></div><div>  <store return value into local return variables, if returns a value></div><div>  br .exit</div><div><br></div><div>.exit:</div><div>  ret <local return value> OR ret void.</div><div><br></div><div><br></div><div>But this approach still does not resolve the issue I had. Front-end still can create multiple "br" instruction per block. Now we hit the original problem: we can't create multiple terminator instructions in a block.</div><div><br></div><div>One or the other pattern could have advantages based on language spec or the way you implement front-end. Who knows, I may want to return back to this approach in the future if creates better advantages. I'm constantly considering alternatives. The simplest / cleanest design wins.</div><div><br></div><div>Best,<br></div><div><br></div><div>Aaron</div></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, May 25, 2018 at 1:41 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:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
> On 25 May 2018, at 03:53, Aaron <<a href="mailto:acraft@gmail.com">acraft@gmail.com</a>> wrote:<br>
> <br>
> Hi Dean,<br>
> <br>
> Thanks for your reply.<br>
> <br>
> That's exactly what I am doing, but I was looking for a default optimization or pass implementation if there was.<br>
> <br>
<br>
</span>There’s a dead code elimination pass, but it works with a control flow graph (it removes basic blocks that are unreachable after constant propagation and other passes earlier on have run).<br>
<span class=""><br>
> 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.<br>
> <br>
<br>
</span>This is working as intended. All LLVM BasicBlocks *must* have a terminator as the last instruction.<br>
<span class=""><br>
> I had to rewrite my own splitBasicBlock() by modifying the original one. Just removed the br instruction creation lines.<br>
> <br>
<br>
</span>It sounds like it would have just been easier to replace the branch instruction into a ret, then remove all successors of the original br instruction. There’s nothing special here, this is how it’s supposed to be done.<br>
<span class=""><br>
> >> Just curious, how are you getting return instructions in the middle of a basic block?<br>
> My code generation pass allows multiple return instruction generation since that simplifies front-end significantly.<br>
> <br>
<br>
</span>I’m just wondering why not have a ‘br’ to an exit basic block instead of ‘ret’ mid-stream of instructions. That way you don’t need to do any special post-processing while you’re emitting the LLVM IR, you end up with valid basic blocks all the time, and you can leverage all the other passes that come with LLVM already.<br>
<br>
That at least sounds simpler to me.<br>
<br>
I’m not sure whether you can have non-entry blocks with no predecessors in LLVM (need to look up the langref about that) but I can imagine it’s a fairly useful construct to support. e.g. something like (pseudo-IR):<br>
<br>
.entry:<br>
  <this is the entry block><br>
  <…><br>
  br .exit<br>
<br>
.bb0:<br>
  <this is by definition unreachable><br>
  <…><br>
  br .exit<br>
<br>
.exit:<br>
  ret<br>
<br>
This structure makes it easier for dead code elimination to determine that .bb0 is unreachable from .entry and can elide it safely. From your front-end, you can have a single ‘.exit’ block in a function and let the optimisations do the basic-block merging later on.<br>
<br>
Have you considered this approach instead?<br>
<span class="HOEnZb"><font color="#888888"><br>
-- Dean<br>
<br>
</font></span></blockquote></div><br></div>