using System.Collections.Generic; using System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.PooledObjects; namespace Microsoft.CodeAnalysis.CSharp.CodeGen; internal class Optimizer { public static BoundStatement Optimize(BoundStatement src, bool debugFriendly, out HashSet stackLocals) { PooledDictionary instance = PooledDictionary.GetInstance(); src = (BoundStatement)StackOptimizerPass1.Analyze(src, (Dictionary)(object)instance, debugFriendly); FilterValidStackLocals((Dictionary)(object)instance); BoundStatement result; if (((Dictionary)(object)instance).Count == 0) { stackLocals = null; result = src; } else { stackLocals = new HashSet(((Dictionary)(object)instance).Keys); result = StackOptimizerPass2.Rewrite(src, (Dictionary)(object)instance); } foreach (LocalDefUseInfo value in ((Dictionary)(object)instance).Values) { value.Free(); } instance.Free(); return result; } private static void FilterValidStackLocals(Dictionary info) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) ArrayBuilder instance = ArrayBuilder.GetInstance(); LocalSymbol[] array = info.Keys.ToArray(); foreach (LocalSymbol localSymbol in array) { LocalDefUseInfo localDefUseInfo = info[localSymbol]; if ((int)localSymbol.SynthesizedKind == -3) { instance.Add(localDefUseInfo); info.Remove(localSymbol); } else if (localDefUseInfo.CannotSchedule) { localDefUseInfo.Free(); info.Remove(localSymbol); } } if (info.Count != 0) { RemoveIntersectingLocals(info, instance); } Enumerator enumerator = instance.GetEnumerator(); while (enumerator.MoveNext()) { enumerator.Current.Free(); } instance.Free(); } private static void RemoveIntersectingLocals(Dictionary info, ArrayBuilder dummies) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) ArrayBuilder instance = ArrayBuilder.GetInstance(dummies.Count); Enumerator enumerator = dummies.GetEnumerator(); while (enumerator.MoveNext()) { Enumerator enumerator2 = enumerator.Current.LocalDefs.GetEnumerator(); while (enumerator2.MoveNext()) { LocalDefUseSpan current = enumerator2.Current; if (current.Start != current.End) { instance.Add(current); } } } int count = instance.Count; foreach (var item in from _003C_003Eh__TransparentIdentifier0 in info.SelectMany(delegate(KeyValuePair i) { KeyValuePair keyValuePair = i; return (IEnumerable)keyValuePair.Value.LocalDefs; }, (KeyValuePair i, LocalDefUseSpan d2) => new { i = i, d = d2 }) orderby _003C_003Eh__TransparentIdentifier0.d.End - _003C_003Eh__TransparentIdentifier0.d.Start, _003C_003Eh__TransparentIdentifier0.d.End select new { i = _003C_003Eh__TransparentIdentifier0.i.Key, d = _003C_003Eh__TransparentIdentifier0.d }) { if (!info.ContainsKey(item.i)) { continue; } LocalDefUseSpan d = item.d; int count2 = instance.Count; bool flag; if (count2 > 5000) { flag = true; } else { flag = false; for (int num = 0; num < count; num++) { LocalDefUseSpan dummy = instance[num]; if (d.ConflictsWithDummy(dummy)) { flag = true; break; } } if (!flag) { for (int num2 = count; num2 < count2; num2++) { LocalDefUseSpan other = instance[num2]; if (d.ConflictsWith(other)) { flag = true; break; } } } } if (flag) { info[item.i].LocalDefs.Free(); info.Remove(item.i); } else { instance.Add(d); } } instance.Free(); } }