Browse Source

Fix #2092: aggressively inline code in compiler-generated lambdas and expression trees.

pull/2447/head
Siegfried Pammer 4 years ago
parent
commit
8eafbb3d90
  1. 6
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 9
      ICSharpCode.Decompiler/CSharp/Transforms/CombineQueryExpressions.cs
  3. 15
      ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs

6
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -419,6 +419,12 @@ namespace ICSharpCode.Decompiler.CSharp @@ -419,6 +419,12 @@ namespace ICSharpCode.Decompiler.CSharp
return true;
return type.BaseType.IsKnownType(metadata, KnownTypeCode.Object) && !type.GetInterfaceImplementations().Any();
}
internal static bool IsTransparentIdentifier(string identifier)
{
return identifier.StartsWith("<>", StringComparison.Ordinal)
&& (identifier.Contains("TransparentIdentifier") || identifier.Contains("TranspIdent"));
}
#endregion
static PEFile LoadPEFile(string fileName, DecompilerSettings settings)

9
ICSharpCode.Decompiler/CSharp/Transforms/CombineQueryExpressions.cs

@ -103,14 +103,9 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -103,14 +103,9 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
}
};
bool IsTransparentIdentifier(string identifier)
{
return identifier.StartsWith("<>", StringComparison.Ordinal) && (identifier.Contains("TransparentIdentifier") || identifier.Contains("TranspIdent"));
}
bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery, Dictionary<string, object> letClauses)
{
if (!IsTransparentIdentifier(fromClause.Identifier))
if (!CSharpDecompiler.IsTransparentIdentifier(fromClause.Identifier))
return false;
QuerySelectClause selectClause = innerQuery.Clauses.Last() as QuerySelectClause;
Match match = selectTransparentIdentifierPattern.Match(selectClause);
@ -174,7 +169,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -174,7 +169,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
if (mre != null)
{
IdentifierExpression ident = mre.Target as IdentifierExpression;
if (ident != null && IsTransparentIdentifier(ident.Identifier))
if (ident != null && CSharpDecompiler.IsTransparentIdentifier(ident.Identifier))
{
IdentifierExpression newIdent = new IdentifierExpression(mre.MemberName);
mre.TypeArguments.MoveTo(newIdent.TypeArguments);

15
ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs

@ -71,7 +71,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -71,7 +71,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
var function = block.Ancestors.OfType<ILFunction>().FirstOrDefault();
var inst = block.Instructions[pos];
if (IsInConstructorInitializer(function, inst))
if (IsInConstructorInitializer(function, inst) || PreferExpressionsOverStatements(function))
options |= InliningOptions.Aggressive;
}
if (!context.Settings.UseRefLocalsForAccurateOrderOfEvaluation)
@ -81,6 +81,19 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -81,6 +81,19 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return options;
}
static bool PreferExpressionsOverStatements(ILFunction function)
{
switch (function.Kind)
{
case ILFunctionKind.Delegate:
return function.Parameters.Any(p => CSharp.CSharpDecompiler.IsTransparentIdentifier(p.Name));
case ILFunctionKind.ExpressionTree:
return true;
default:
return false;
}
}
public static bool InlineAllInBlock(ILFunction function, Block block, ILTransformContext context)
{
bool modified = false;

Loading…
Cancel
Save