# IRTools: how can I insert a shortcycling \`@ifsomething\` into IR?

**URL:** https://discourse.julialang.org/t/irtools-how-can-i-insert-a-shortcycling-ifsomething-into-ir/65593
**Category:** General Usage
**Tags:** question, ir
**Created:** [July 31, 2021, 10:53am UTC](https://discourse.julialang.org/t/irtools-how-can-i-insert-a-shortcycling-ifsomething-into-ir/65593 "2021-07-31T10:53:54Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)
#### Post date: [July 31, 2021, 10:53am UTC](https://discourse.julialang.org/t/irtools-how-can-i-insert-a-shortcycling-ifsomething-into-ir/65593/1 "2021-07-31T10:53:54Z")

</div>

Hi there,  
I am experimenting with IRTools and IR.  
So far I understood that branches, including return statements, always have to be last in a block.

Hence if I want to create a shortcycling statement like realised by the `@ifsomething` macro

```julia
macro ifsomething(ex)
    quote
        result = $(esc(ex))
        result === nothing && return nothing
        result
    end
end

```

I somehow need to split the original IR block into two

1. the `result === nothing && return nothing` needs to be added to the original block.
2. everything else in the original block needs to move to a new block, passing all necessary parameters.

Looking into documentation, examples, tests and source code of IRTools I still have no clue how to do this as of now.  
Any help or hint where else I might get help is highly appreciated!

---

<div class="post-metadata">

### Author: ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)
#### Post date: [August 1, 2021, 10:59am UTC](https://discourse.julialang.org/t/irtools-how-can-i-insert-a-shortcycling-ifsomething-into-ir/65593/2 "2021-08-01T10:59:01Z")

</div>

after getting into the internals of the IR representation, I was able to create a solution.

```julia
function shortcycle_if_nothing!(ir, var)
  oldblock, i_var_oldblock = IRTools.Inner.blockidx(ir, var)
  newblock = IRTools.block!(ir, oldblock.id+1) # insert right after given block

  # move next statements to new block
  oldblock_n_statements = length(IRTools.BasicBlock(oldblock).stmts)
  for j in (i_var_oldblock+1):oldblock_n_statements
      push!(newblock, oldblock[j])
      oldblock[j] = nothing
  end
  # move variable ids to new block
  for (i, (i_block, i_var_block)) in enumerate(ir.defs)
      if i_block == oldblock.id && i_var_block > i_var_oldblock
          ir.defs[i] = (newblock.id, i_var_block - i_var_oldblock)
      # we need to delete the original references which have been created for newblock
      elseif i_block == newblock.id
          ir.defs[i] = (-1, -1)
      end
  end

  # move branches to new block
  append!(IRTools.branches(newblock), IRTools.branches(oldblock))
  empty!(IRTools.branches(oldblock))

  # add shortcycling in the original branch if we found `nothing`
  var_isnothing = IRTools.insertafter!(ir, var, IRTools.xcall(===, var, nothing))
  IRTools.branch!(oldblock, newblock, unless = var_isnothing)
  IRTools.return!(oldblock, GlobalRef(Main, :nothing))
  return ir
end

```
