154 lines
4.6 KiB
C#
154 lines
4.6 KiB
C#
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<LocalSymbol> stackLocals)
|
|
{
|
|
PooledDictionary<LocalSymbol, LocalDefUseInfo> instance = PooledDictionary<LocalSymbol, LocalDefUseInfo>.GetInstance();
|
|
src = (BoundStatement)StackOptimizerPass1.Analyze(src, (Dictionary<LocalSymbol, LocalDefUseInfo>)(object)instance, debugFriendly);
|
|
FilterValidStackLocals((Dictionary<LocalSymbol, LocalDefUseInfo>)(object)instance);
|
|
BoundStatement result;
|
|
if (((Dictionary<LocalSymbol, LocalDefUseInfo>)(object)instance).Count == 0)
|
|
{
|
|
stackLocals = null;
|
|
result = src;
|
|
}
|
|
else
|
|
{
|
|
stackLocals = new HashSet<LocalSymbol>(((Dictionary<LocalSymbol, LocalDefUseInfo>)(object)instance).Keys);
|
|
result = StackOptimizerPass2.Rewrite(src, (Dictionary<LocalSymbol, LocalDefUseInfo>)(object)instance);
|
|
}
|
|
foreach (LocalDefUseInfo value in ((Dictionary<LocalSymbol, LocalDefUseInfo>)(object)instance).Values)
|
|
{
|
|
value.Free();
|
|
}
|
|
instance.Free();
|
|
return result;
|
|
}
|
|
|
|
private static void FilterValidStackLocals(Dictionary<LocalSymbol, LocalDefUseInfo> 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<LocalDefUseInfo> instance = ArrayBuilder<LocalDefUseInfo>.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<LocalDefUseInfo> enumerator = instance.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
enumerator.Current.Free();
|
|
}
|
|
instance.Free();
|
|
}
|
|
|
|
private static void RemoveIntersectingLocals(Dictionary<LocalSymbol, LocalDefUseInfo> info, ArrayBuilder<LocalDefUseInfo> 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<LocalDefUseSpan> instance = ArrayBuilder<LocalDefUseSpan>.GetInstance(dummies.Count);
|
|
Enumerator<LocalDefUseInfo> enumerator = dummies.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
Enumerator<LocalDefUseSpan> 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<LocalSymbol, LocalDefUseInfo> i)
|
|
{
|
|
KeyValuePair<LocalSymbol, LocalDefUseInfo> keyValuePair = i;
|
|
return (IEnumerable<LocalDefUseSpan>)keyValuePair.Value.LocalDefs;
|
|
}, (KeyValuePair<LocalSymbol, LocalDefUseInfo> 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();
|
|
}
|
|
}
|