diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
index e080d317e..929ac7419 100644
--- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
+++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
@@ -58,6 +58,8 @@ namespace ICSharpCode.Decompiler.CSharp
new SplitVariables(),
new ILInlining(),
new DetectPinnedRegions(), // must run after inlining but before non-critical control flow transforms
+ new BlockILTransform(new ExpressionTransforms()), // for RemoveDeadVariableInit
+ new RemoveDeadVariableInit(), // must run after ExpressionTransforms because it does not handle stobj(ldloca V, ...)
new SwitchDetection(),
new LoopDetection(),
new IntroduceExitPoints(),
@@ -76,9 +78,6 @@ namespace ICSharpCode.Decompiler.CSharp
new ILInlining()
)
),
- //new InlineCompilerGeneratedVariables(),
- // -- isn't InlineCompilerGeneratedVariables redundant now that we have variable splitting?
- new RemoveDeadVariableInit(), // must run after ExpressionTransforms because it does not handle stobj(ldloca V, ...)
new DelegateConstruction(),
};
}
diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
index e962a6467..81c7f7e00 100644
--- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
+++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
@@ -138,7 +138,6 @@
-
diff --git a/ICSharpCode.Decompiler/IL/Transforms/InlineCompilerGeneratedVariables.cs b/ICSharpCode.Decompiler/IL/Transforms/InlineCompilerGeneratedVariables.cs
deleted file mode 100644
index 14fb5d10d..000000000
--- a/ICSharpCode.Decompiler/IL/Transforms/InlineCompilerGeneratedVariables.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2014 Daniel Grunwald
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this
-// software and associated documentation files (the "Software"), to deal in the Software
-// without restriction, including without limitation the rights to use, copy, modify, merge,
-// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
-// to whom the Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all copies or
-// substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
-// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-
-namespace ICSharpCode.Decompiler.IL.Transforms
-{
- ///
- /// Inline compiler-generated variables.
- /// Unlike normal inlining that acts on stack variables which have only one use,
- /// this transform will also perform inlining if the variables are re-used.
- ///
- ///
- /// Should run after ControlFlowSimplification duplicates the return blocks.
- /// Should run after a regular round of inlining, so that stack variables
- /// don't prevent us from determining whether a variable is likely to be compiler-generated.
- ///
- public class InlineCompilerGeneratedVariables : IILTransform
- {
- public void Run(ILFunction function, ILTransformContext context)
- {
- List storesToInline = new List();
- List deadStores = new List();
- foreach (var g in function.Descendants.OfType().GroupBy(inst => inst.Variable)) {
- storesToInline.Clear();
- deadStores.Clear();
- if (CanInlineVariable(g.Key, g, storesToInline, deadStores)) {
- foreach (var stloc in storesToInline) {
- ILInlining.InlineOne(stloc, aggressive: false, context: context);
- }
- foreach (var stloc in deadStores) {
- if (SemanticHelper.IsPure(stloc.Flags)) {
- ((Block)stloc.Parent).Instructions.RemoveAt(stloc.ChildIndex);
- }
- }
- }
- }
- }
-
- bool CanInlineVariable(ILVariable v, IEnumerable stores, /*out*/ List storesToInline, /*out*/ List deadStores)
- {
- if (v.Kind != VariableKind.Local) {
- return false;
- }
- if (v.HasInitialValue) {
- return false; // cannot handle variables that are implicitly initialized at the beginning of the function
- }
- Debug.Assert(v.StoreCount == stores.Count());
- // We expect there to be one store for every load,
- // and potentially also some dead stores.
- if (v.StoreCount < v.LoadCount || v.AddressCount != 0)
- return false;
- int loadsAccountedFor = 0;
- foreach (var stloc in stores) {
- Block block = stloc.Parent as Block;
- if (block == null)
- return false;
- ILInstruction next = block.Instructions.ElementAtOrDefault(stloc.ChildIndex + 1);
- // NB: next==null is considerd as a dead store
- if (ILInlining.CanInlineInto(next, v, stloc.Value)) {
- loadsAccountedFor++;
- storesToInline.Add(stloc);
- } else {
- // a dead store (but only if this method returns true)
- deadStores.Add(stloc);
- }
- }
- return v.LoadCount == loadsAccountedFor;
- }
- }
-}