Skip to content

Commit

Permalink
Fix #2092: aggressively inline code in compiler-generated lambdas and…
Browse files Browse the repository at this point in the history
… expression trees.
  • Loading branch information
siegfriedpammer committed Jun 18, 2021
1 parent 164c888 commit 8eafbb3
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 8 deletions.
6 changes: 6 additions & 0 deletions ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,12 @@ static bool IsClosureType(SRM.TypeDefinition type, MetadataReader metadata)
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,9 @@ void CombineQueries(AstNode node, Dictionary<string, object> fromOrLetIdentifier
}
};

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);
Expand Down Expand Up @@ -174,7 +169,7 @@ void RemoveTransparentIdentifierReferences(AstNode node, Dictionary<string, obje
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);
Expand Down
15 changes: 14 additions & 1 deletion ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ internal static InliningOptions OptionsForBlock(Block block, int pos, ILTransfor
{
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)
Expand All @@ -81,6 +81,19 @@ internal static InliningOptions OptionsForBlock(Block block, int pos, ILTransfor
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;
Expand Down

0 comments on commit 8eafbb3

Please sign in to comment.