/// <summary> /// Returns true if any branches were optimized (that does not include shortening) /// We need this because optimizing a branch may result in unreachable code that needs to be eliminated. /// /// === Example: /// /// x = 1; /// /// if (blah) /// { /// global = 1; /// } /// else /// { /// throw null; /// } /// /// return x; /// /// === rewrites into /// /// push 1; /// /// if (blah) /// { /// global = 1; /// ret; /// } /// else /// { /// throw null; /// } /// /// // this ret unreachable now! /// // even worse - empty stack is assumed thus the ret is illegal. /// ret; /// /// </summary> private bool ComputeOffsetsAndAdjustBranches() { ComputeOffsets(); bool branchesOptimized = false; int delta; do { delta = 0; BasicBlock current = leaderBlock; while (current != null) { current.AdjustForDelta(delta); if (_optimizations == OptimizationLevel.Release) { branchesOptimized |= current.OptimizeBranches(ref delta); } current.ShortenBranches(ref delta); current = current.NextBlock; } } while (delta < 0); // shortening some branches may enable more branches for shortening. return(branchesOptimized); }