static Leave CombineExits(Block block) { if (!(block.Instructions.SecondToLastOrDefault() is IfInstruction ifInst && block.Instructions.LastOrDefault() is Leave leaveElse)) { return(null); } if (!ifInst.FalseInst.MatchNop()) { return(null); } // try to unwrap true branch to single instruction: var trueInstruction = Block.Unwrap(ifInst.TrueInst); // if the true branch is a block with multiple instructions: // try to apply the combine exits transform to the nested block // and then continue on that transformed block. // Example: // if (cond) { // if (cond2) { // leave (value) // } // leave (value2) // } // leave (value3) // => // leave (if (cond) value else if (cond2) value2 else value3) if (trueInstruction is Block nestedBlock && nestedBlock.Instructions.Count == 2) { trueInstruction = CombineExits(nestedBlock); } if (!(trueInstruction is Leave leave)) { return(null); } if (!(leave.IsLeavingFunction && leaveElse.IsLeavingFunction)) { return(null); } if (leave.Value.MatchNop() || leaveElse.Value.MatchNop()) { return(null); } // if (cond) { // leave (value) // } // leave (elseValue) // => // leave (if (cond) value else elseValue) IfInstruction value = new IfInstruction(ifInst.Condition, leave.Value, leaveElse.Value); value.AddILRange(ifInst); Leave combinedLeave = new Leave(leave.TargetContainer, value); combinedLeave.AddILRange(leaveElse); combinedLeave.AddILRange(leave); ifInst.ReplaceWith(combinedLeave); block.Instructions.RemoveAt(combinedLeave.ChildIndex + 1); return(combinedLeave); }