diff --git a/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs b/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs index 0543d10b0..2b71fb712 100644 --- a/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs +++ b/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs @@ -46,9 +46,10 @@ namespace ICSharpCode.Decompiler.ILAst TransformDecimalCtorToConstant, SimplifyLdObjAndStObj, SimplifyCustomShortCircuit, + SimplifyShiftOperators, + SimplifyNullableOperators, TransformArrayInitializers, TransformObjectInitializers, - SimplifyNullableOperators, MakeAssignmentExpression, IntroducePostIncrement, InlineVariables2, @@ -145,15 +146,18 @@ namespace ICSharpCode.Decompiler.ILAst if (abortBeforeStep == ILAstOptimizationStep.SimplifyCustomShortCircuit) return; modified |= block.RunOptimization(new SimpleControlFlow(context, method).SimplifyCustomShortCircuit); + + if (abortBeforeStep == ILAstOptimizationStep.SimplifyShiftOperators) return; + modified |= block.RunOptimization(SimplifyShiftOperators); + + if (abortBeforeStep == ILAstOptimizationStep.SimplifyNullableOperators) return; + modified |= block.RunOptimization(SimplifyNullableOperators); if (abortBeforeStep == ILAstOptimizationStep.TransformArrayInitializers) return; modified |= block.RunOptimization(TransformArrayInitializers); if (abortBeforeStep == ILAstOptimizationStep.TransformObjectInitializers) return; modified |= block.RunOptimization(TransformObjectInitializers); - - if (abortBeforeStep == ILAstOptimizationStep.SimplifyNullableOperators) return; - modified |= block.RunOptimization(SimplifyNullableOperators); if (abortBeforeStep == ILAstOptimizationStep.MakeAssignmentExpression) return; modified |= block.RunOptimization(MakeAssignmentExpression); diff --git a/ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs b/ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs index 247a50c33..7b68bdac6 100644 --- a/ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs +++ b/ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs @@ -940,5 +940,40 @@ namespace ICSharpCode.Decompiler.ILAst return true; } #endregion + + #region SimplifyShiftOperators + static bool SimplifyShiftOperators(List body, ILExpression expr, int pos) + { + bool modified = false; + SimplifyShiftOperators(expr, ref modified); + return modified; + } + + static void SimplifyShiftOperators(ILExpression expr, ref bool modified) + { + for (int i = 0; i < expr.Arguments.Count; i++) SimplifyShiftOperators(expr.Arguments[i], ref modified); + if (expr.Code != ILCode.Shl && expr.Code != ILCode.Shr && expr.Code != ILCode.Shr_Un) return; + var a = expr.Arguments[1]; + if (a.Code != ILCode.And || a.Arguments[1].Code != ILCode.Ldc_I4 || expr.InferredType == null) return; + int mask; + switch (expr.InferredType.MetadataType) { + case MetadataType.Byte: + case MetadataType.SByte: + case MetadataType.Int16: + case MetadataType.UInt16: + case MetadataType.Int32: + case MetadataType.UInt32: mask = 31; break; + case MetadataType.Int64: + case MetadataType.UInt64: mask = 63; break; + default: return; + } + if ((int)a.Arguments[1].Operand != mask) return; + var res = a.Arguments[0]; + res.ILRanges.AddRange(a.ILRanges); + res.ILRanges.AddRange(a.Arguments[1].ILRanges); + expr.Arguments[1] = res; + modified = true; + } + #endregion } }