public void ContinueWith(BoundBlock block) { if (_codegen.IsGenerated(block)) { // backward edge; // or the block was already emitted, branch there: IL.EmitBranch(ILOpCode.Br, block); return; } if (block.IsDead || block.FlowState == null) { // ignore dead/unreachable blocks return; } if (block.Ordinal < _from) { throw new InvalidOperationException("block miss"); } if (IsIn(block)) { // TODO: avoid branching to a guarded scope // e.g. goto x; try { x: } if (_blocks == null || _blocks.Count == 0 || _blocks.Comparer.Compare(block, _blocks.First()) < 0) { if (_blocks != null) { _blocks.Remove(block); } // continue with the block _codegen.GenerateBlock(block); return; } } // forward edge: // note: if block will follow immediately, .br will be ignored IL.EmitBranch(ILOpCode.Br, block); this.Enqueue(block); }
public void ContinueWith(BoundBlock block) { if (_codegen.IsGenerated(block)) { // backward edge; // or the block was already emitted, branch there: IL.EmitBranch(ILOpCode.Br, block); return; } if (block.IsDead) { return; } if (block.Ordinal < _from) { throw new InvalidOperationException("block miss"); } if (block.Ordinal < _to) // is in { // TODO: avoid branching to a guarded scope // e.g. goto x; try { x: } if (_blocks != null) { _blocks.Remove(block); } // continue with the block _codegen.GenerateBlock(block); } else { // forward edge: IL.EmitBranch(ILOpCode.Br, block); // TODO: avoid branch instruction if block will follow immediately Parent.Enqueue(block); } }