public void Split(Block rightBlock) { int splitIndex = BinarySearch(OpCodes, rightBlock.Address); if (OpCodes[splitIndex].Address < rightBlock.Address) { splitIndex++; } int splitCount = OpCodes.Count - splitIndex; if (splitCount <= 0) { throw new ArgumentException("Can't split at right block address."); } rightBlock.EndAddress = EndAddress; rightBlock.Successors.AddRange(Successors); rightBlock.Predecessors.Add(this); EndAddress = rightBlock.Address; Successors.Clear(); Successors.Add(rightBlock); // Move ops. rightBlock.OpCodes.AddRange(OpCodes.GetRange(splitIndex, splitCount)); OpCodes.RemoveRange(splitIndex, splitCount); // Update push consumers that points to this block. foreach (SyncTarget syncTarget in SyncTargets.Values) { PushOpInfo pushOpInfo = syncTarget.PushOpInfo; Operand local = pushOpInfo.Consumers[this]; pushOpInfo.Consumers.Remove(this); pushOpInfo.Consumers.Add(rightBlock, local); } foreach ((ulong key, SyncTarget value) in SyncTargets) { rightBlock.SyncTargets.Add(key, value); } SyncTargets.Clear(); // Move push ops. for (int i = 0; i < PushOpCodes.Count; i++) { if (PushOpCodes[i].Op.Address >= rightBlock.Address) { int count = PushOpCodes.Count - i; rightBlock.PushOpCodes.AddRange(PushOpCodes.Skip(i)); PushOpCodes.RemoveRange(i, count); break; } } }
public SyncTarget(PushOpInfo pushOpInfo, int pushOpId) { PushOpInfo = pushOpInfo; PushOpId = pushOpId; }