Skip to content

Commit baad46f

Browse files
authored
refactor: simplify flat constant structural comparison
1 parent 0c059a4 commit baad46f

1 file changed

Lines changed: 25 additions & 57 deletions

File tree

src/FastExpressionCompiler.LightExpression/FlatExpression.cs

Lines changed: 25 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1839,7 +1839,10 @@ public bool Eq(ref ExprTree xTree, ref ExprTree yTree)
18391839

18401840
var frame = _eqFrames[_eqFrames.Count - 1];
18411841
_eqFrames.Count--;
1842-
RestoreParameterScope(frame.XParameterCount, frame.YParameterCount);
1842+
if (frame.XParameterCount >= 0)
1843+
_xParameterIds.Count = frame.XParameterCount;
1844+
if (frame.YParameterCount >= 0)
1845+
_yParameterIds.Count = frame.YParameterCount;
18431846
if (frame.RemainingSiblingsAfterNode != 0)
18441847
{
18451848
xIdx = frame.XNextIdx;
@@ -1891,19 +1894,8 @@ private static bool AreEquivalentParameterDeclarations(ref ExprNode x, ref ExprN
18911894
y.NodeType == ExpressionType.Parameter &&
18921895
x.HasSameShapeExceptLinks(ref y);
18931896

1894-
private static bool EqObj(ref ExprNode x, ref ExprNode y)
1895-
{
1896-
return ReferenceEquals(x.Obj, y.Obj) || Equals(x.Obj, y.Obj);
1897-
}
1898-
1899-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
1900-
private void RestoreParameterScope(int xParameterCount, int yParameterCount)
1901-
{
1902-
if (xParameterCount >= 0)
1903-
_xParameterIds.Count = xParameterCount;
1904-
if (yParameterCount >= 0)
1905-
_yParameterIds.Count = yParameterCount;
1906-
}
1897+
private static bool EqObj(ref ExprNode x, ref ExprNode y) =>
1898+
ReferenceEquals(x.Obj, y.Obj) || Equals(x.Obj, y.Obj);
19071899

19081900
private int HashNode(ref ExprTree tree, int idx)
19091901
{
@@ -2041,75 +2033,51 @@ private static bool AreConstantsEqual(ref ExprTree xTree, ref ExprNode x, ref Ex
20412033
Debug.Assert(!ExprNode.RequiresInlineConstantStorage(x.Type, x.Obj, x.NodeType));
20422034
var xObj = GetStoredConstantValue(ref xTree, ref x);
20432035
var yObj = GetStoredConstantValue(ref yTree, ref y);
2044-
return ReferenceEquals(xObj, yObj) || Equals(xObj, yObj);
2036+
return xObj?.Equals(yObj) ?? yObj == null;
20452037
}
20462038

20472039
if (x.Type.IsEnum)
20482040
return x.InlineValue == y.InlineValue;
20492041

2050-
return Type.GetTypeCode(x.Type) switch
2051-
{
2052-
TypeCode.Boolean => x.InlineValue == y.InlineValue,
2053-
TypeCode.Byte => x.InlineValue == y.InlineValue,
2054-
TypeCode.SByte => x.InlineValue == y.InlineValue,
2055-
TypeCode.Char => x.InlineValue == y.InlineValue,
2056-
TypeCode.Int16 => x.InlineValue == y.InlineValue,
2057-
TypeCode.UInt16 => x.InlineValue == y.InlineValue,
2058-
TypeCode.Int32 => x.InlineValue == y.InlineValue,
2059-
TypeCode.UInt32 => x.InlineValue == y.InlineValue,
2060-
TypeCode.Single => FloatBits.ToFloat(x.InlineValue).Equals(FloatBits.ToFloat(y.InlineValue)),
2061-
_ => FlatExpressionThrow.UnsupportedInlineConstantType<bool>(x.Type)
2062-
};
2042+
var typeCode = Type.GetTypeCode(x.Type);
2043+
Debug.Assert(IsSmallPrimitive(typeCode));
2044+
return typeCode != TypeCode.Single
2045+
? x.InlineValue == y.InlineValue
2046+
: FloatBits.ToFloat(x.InlineValue).Equals(FloatBits.ToFloat(y.InlineValue));
20632047
}
20642048

20652049
private static object GetStoredConstantValue(ref ExprTree tree, ref ExprNode node) =>
20662050
ReferenceEquals(node.Obj, ClosureConstantMarker) ? tree.ClosureConstants[node.ChildIdx] : node.Obj;
20672051

20682052
private static int GetInlineConstantHashCode(Type type, uint data)
20692053
{
2070-
if (type.IsEnum)
2071-
return Type.GetTypeCode(Enum.GetUnderlyingType(type)) switch
2072-
{
2073-
TypeCode.Byte => ((byte)data).GetHashCode(),
2074-
TypeCode.SByte => ((sbyte)(byte)data).GetHashCode(),
2075-
TypeCode.Char => ((char)(ushort)data).GetHashCode(),
2076-
TypeCode.Int16 => ((short)(ushort)data).GetHashCode(),
2077-
TypeCode.UInt16 => ((ushort)data).GetHashCode(),
2078-
TypeCode.Int32 => ((int)data).GetHashCode(),
2079-
TypeCode.UInt32 => data.GetHashCode(),
2080-
var tc => FlatExpressionThrow.UnsupportedInlineConstantType<int>(type, tc)
2081-
};
2082-
2083-
return Type.GetTypeCode(type) switch
2054+
if (!type.IsEnum)
20842055
{
2085-
TypeCode.Boolean => (data != 0).GetHashCode(),
2086-
TypeCode.Byte => ((byte)data).GetHashCode(),
2087-
TypeCode.SByte => ((sbyte)(byte)data).GetHashCode(),
2088-
TypeCode.Char => ((char)(ushort)data).GetHashCode(),
2089-
TypeCode.Int16 => ((short)(ushort)data).GetHashCode(),
2090-
TypeCode.UInt16 => ((ushort)data).GetHashCode(),
2091-
TypeCode.Int32 => ((int)data).GetHashCode(),
2092-
TypeCode.UInt32 => data.GetHashCode(),
2093-
TypeCode.Single => FloatBits.ToFloat(data).GetHashCode(),
2094-
_ => FlatExpressionThrow.UnsupportedInlineConstantType<int>(type)
2095-
};
2056+
var typeCode = Type.GetTypeCode(type);
2057+
Debug.Assert(IsSmallPrimitive(typeCode));
2058+
if (typeCode == TypeCode.Single)
2059+
return FloatBits.ToFloat(data).GetHashCode();
2060+
}
2061+
2062+
return data.GetHashCode();
20962063
}
20972064

2065+
[StructLayout(LayoutKind.Sequential)]
20982066
private struct TraversalFrame
20992067
{
2100-
public readonly int XNextIdx;
2101-
public readonly int YNextIdx;
21022068
public readonly int RemainingSiblingsAfterNode;
21032069
public readonly int XParameterCount;
21042070
public readonly int YParameterCount;
2071+
public readonly ushort XNextIdx;
2072+
public readonly ushort YNextIdx;
21052073

21062074
public TraversalFrame(int xNextIdx, int yNextIdx, int remainingSiblingsAfterNode, int xParameterCount, int yParameterCount)
21072075
{
2108-
XNextIdx = xNextIdx;
2109-
YNextIdx = yNextIdx;
21102076
RemainingSiblingsAfterNode = remainingSiblingsAfterNode;
21112077
XParameterCount = xParameterCount;
21122078
YParameterCount = yParameterCount;
2079+
XNextIdx = checked((ushort)xNextIdx);
2080+
YNextIdx = checked((ushort)yNextIdx);
21132081
}
21142082
}
21152083
}

0 commit comments

Comments
 (0)