示例#1
0
		public bool InlineAllVariables()
		{
			bool modified = false;
			AstInlining i = new AstInlining(method);
			foreach (AstBlock block in method.GetSelfAndChildrenRecursive<AstBlock>())
				modified |= i.InlineAllInBlock(block);
			return modified;
		}
示例#2
0
        public bool InlineAllVariables()
        {
            bool        modified = false;
            AstInlining i        = new AstInlining(method);

            foreach (AstBlock block in method.GetSelfAndChildrenRecursive <AstBlock>())
            {
                modified |= i.InlineAllInBlock(block);
            }
            return(modified);
        }
示例#3
0
        bool MakeAssignmentExpression(List <AstNode> body, AstExpression expr, int pos)
        {
            // exprVar = ...
            // stloc(v, exprVar)
            // ->
            // exprVar = stloc(v, ...))
            AstVariable   exprVar;
            AstExpression initializer;

            if (!(expr.Match(AstCode.Stloc, out exprVar, out initializer) && exprVar.IsGenerated))
            {
                return(false);
            }
            var           nextExpr = body.ElementAtOrDefault(pos + 1) as AstExpression;
            AstVariable   v;
            AstExpression stLocArg;

            if (nextExpr.Match(AstCode.Stloc, out v, out stLocArg) && stLocArg.MatchLdloc(exprVar))
            {
                var store2 = body.ElementAtOrDefault(pos + 2) as AstExpression;
                if (StoreCanBeConvertedToAssignment(store2, exprVar))
                {
                    // expr_44 = ...
                    // stloc(v1, expr_44)
                    // anystore(v2, expr_44)
                    // ->
                    // stloc(v1, anystore(v2, ...))
                    var inlining = new AstInlining(method);
                    if (inlining.numLdloc.GetOrDefault(exprVar) == 2 && inlining.numStloc.GetOrDefault(exprVar) == 1)
                    {
                        body.RemoveAt(pos + 2); // remove store2
                        body.RemoveAt(pos);     // remove expr = ...
                        nextExpr.Arguments[0] = store2;
                        store2.Arguments[store2.Arguments.Count - 1] = initializer;

                        inlining.InlineIfPossible(body, ref pos);

                        return(true);
                    }
                }

                body.RemoveAt(pos + 1); // remove stloc
                nextExpr.Arguments[0] = initializer;
                ((AstExpression)body[pos]).Arguments[0] = nextExpr;
                return(true);
            }

            if ((nextExpr != null) && (nextExpr.Code == AstCode.Stsfld) && nextExpr.Arguments.Count == 1)
            {
                // exprVar = ...
                // stsfld(fld, exprVar)
                // ->
                // exprVar = stsfld(fld, ...))
                if (nextExpr.Arguments[0].MatchLdloc(exprVar))
                {
                    body.RemoveAt(pos + 1); // remove stsfld
                    nextExpr.Arguments[0] = initializer;
                    ((AstExpression)body[pos]).Arguments[0] = nextExpr;
                    return(true);
                }
            }
            return(false);
        }
示例#4
0
        public void Optimize(AstOptimizationStep abortBeforeStep = AstOptimizationStep.None)
        {
            if (abortBeforeStep == AstOptimizationStep.RemoveRedundantCode)
            {
                return;
            }
            RemoveRedundantCode(method);

            if (abortBeforeStep == AstOptimizationStep.ReduceBranchInstructionSet)
            {
                return;
            }
            foreach (AstBlock block in method.GetSelfAndChildrenRecursive <AstBlock>())
            {
                ReduceBranchInstructionSet(block);
            }
            // ReduceBranchInstructionSet runs before inlining because the non-aggressive inlining heuristic
            // looks at which type of instruction consumes the inlined variable.

            if (abortBeforeStep == AstOptimizationStep.InlineVariables)
            {
                return;
            }
            // Works better after simple goto removal because of the following debug pattern: stloc X; br Next; Next:; ldloc X
            var inlining1 = new AstInlining(method);

            inlining1.InlineAllVariables();

            if (abortBeforeStep == AstOptimizationStep.CopyPropagation)
            {
                return;
            }
            inlining1.CopyPropagation();

            if (abortBeforeStep == AstOptimizationStep.SplitToMovableBlocks)
            {
                return;
            }
            foreach (var block in method.GetSelfAndChildrenRecursive <AstBlock>())
            {
                SplitToBasicBlocks(block);
            }

            if (abortBeforeStep == AstOptimizationStep.TypeInference)
            {
                return;
            }
            // Types are needed for the ternary operator optimization
            TypeAnalysis.Run(context, method);

            foreach (AstBlock block in method.GetSelfAndChildrenRecursive <AstBlock>())
            {
                bool modified;
                do
                {
                    modified = false;

                    if (abortBeforeStep == AstOptimizationStep.SimplifyNullCoalescing)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(new SimpleControlFlow(context, method).SimplifyNullCoalescing);

                    if (abortBeforeStep == AstOptimizationStep.JoinBasicBlocks)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(new SimpleControlFlow(context, method).JoinBasicBlocks);

                    if (abortBeforeStep == AstOptimizationStep.SimplifyShiftOperators)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(SimplifyShiftOperators);

                    if (abortBeforeStep == AstOptimizationStep.TransformDecimalCtorToConstant)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(TransformDecimalCtorToConstant);
                    modified |= block.RunOptimization(SimplifyLdcI4ConvI8);

                    if (abortBeforeStep == AstOptimizationStep.SimplifyLdObjAndStObj)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(SimplifyLdObjAndStObj);

                    if (abortBeforeStep == AstOptimizationStep.TransformArrayInitializers)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(TransformArrayInitializers);

                    if (abortBeforeStep == AstOptimizationStep.TransformMultidimensionalArrayInitializers)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(TransformMultidimensionalArrayInitializers);

                    if (abortBeforeStep == AstOptimizationStep.MakeAssignmentExpression)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(MakeAssignmentExpression);
#if COMPOUNDASSIGNMENT
                    modified |= block.RunOptimization(MakeCompoundAssignments);
#endif

#if POSTINCREMENT
                    if (abortBeforeStep == AstOptimizationStep.IntroducePostIncrement)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(IntroducePostIncrement);
#endif

                    if (abortBeforeStep == AstOptimizationStep.InlineExpressionTreeParameterDeclarations)
                    {
                        return;
                    }
                    if (context.Settings.ExpressionTrees)
                    {
                        modified |= block.RunOptimization(InlineExpressionTreeParameterDeclarations);
                    }

                    if (abortBeforeStep == AstOptimizationStep.InlineVariables2)
                    {
                        return;
                    }
                    modified |= new AstInlining(method).InlineAllInBlock(block);
                    new AstInlining(method).CopyPropagation();
                } while (modified);
            }

            /*if (abortBeforeStep == AstOptimizationStep.FindLoops) return;
             * foreach (AstBlock block in method.GetSelfAndChildrenRecursive<AstBlock>())
             * {
             *  new LoopsAndConditions(context).FindLoops(block);
             * }
             */

            /*if (abortBeforeStep == AstOptimizationStep.FindConditions) return;
             * foreach (AstBlock block in method.GetSelfAndChildrenRecursive<AstBlock>())
             * {
             *  new LoopsAndConditions(context).FindConditions(block);
             * }*/

            if (abortBeforeStep == AstOptimizationStep.FlattenNestedMovableBlocks)
            {
                return;
            }
            FlattenBasicBlocks(method);

            if (abortBeforeStep == AstOptimizationStep.RemoveEndFinally)
            {
                return;
            }
            RemoveEndFinally(method);

            if (abortBeforeStep == AstOptimizationStep.RemoveRedundantCode2)
            {
                return;
            }
            RemoveRedundantCode(method);

            if (abortBeforeStep == AstOptimizationStep.GotoRemoval)
            {
                return;
            }
            new GotoRemoval().RemoveGotos(method);

            if (abortBeforeStep == AstOptimizationStep.DuplicateReturns)
            {
                return;
            }
            DuplicateReturnStatements(method);

            if (abortBeforeStep == AstOptimizationStep.GotoRemoval2)
            {
                return;
            }
            new GotoRemoval().RemoveGotos(method);

            if (abortBeforeStep == AstOptimizationStep.InlineVariables3)
            {
                return;
            }
            // The 2nd inlining pass is necessary because DuplicateReturns and the introduction of ternary operators
            // open up additional inlining possibilities.
            new AstInlining(method).InlineAllVariables();

            if (abortBeforeStep == AstOptimizationStep.RecombineVariables)
            {
                return;
            }
            //RecombineVariables(method); // We do not recombine variables because the RL code depends on it.

            if (abortBeforeStep == AstOptimizationStep.TypeInference2)
            {
                return;
            }
            TypeAnalysis.Reset(method);
            TypeAnalysis.Run(context, method);

            if (abortBeforeStep == AstOptimizationStep.RemoveRedundantCode3)
            {
                return;
            }
            GotoRemoval.RemoveRedundantCode(method);

            // ReportUnassignedILRanges(method);
        }
示例#5
0
        bool MakeAssignmentExpression(List<AstNode> body, AstExpression expr, int pos)
        {
            // exprVar = ...
            // stloc(v, exprVar)
            // ->
            // exprVar = stloc(v, ...))
            AstVariable exprVar;
            AstExpression initializer;
            if (!(expr.Match(AstCode.Stloc, out exprVar, out initializer) && exprVar.IsGenerated))
                return false;
            var nextExpr = body.ElementAtOrDefault(pos + 1) as AstExpression;
            AstVariable v;
            AstExpression stLocArg;
            if (nextExpr.Match(AstCode.Stloc, out v, out stLocArg) && stLocArg.MatchLdloc(exprVar))
            {
                var store2 = body.ElementAtOrDefault(pos + 2) as AstExpression;
                if (StoreCanBeConvertedToAssignment(store2, exprVar))
                {
                    // expr_44 = ...
                    // stloc(v1, expr_44)
                    // anystore(v2, expr_44)
                    // ->
                    // stloc(v1, anystore(v2, ...))
                    var inlining = new AstInlining(method);
                    if (inlining.numLdloc.GetOrDefault(exprVar) == 2 && inlining.numStloc.GetOrDefault(exprVar) == 1)
                    {
                        body.RemoveAt(pos + 2); // remove store2
                        body.RemoveAt(pos); // remove expr = ...
                        nextExpr.Arguments[0] = store2;
                        store2.Arguments[store2.Arguments.Count - 1] = initializer;

                        inlining.InlineIfPossible(body, ref pos);

                        return true;
                    }
                }

                body.RemoveAt(pos + 1); // remove stloc
                nextExpr.Arguments[0] = initializer;
                ((AstExpression)body[pos]).Arguments[0] = nextExpr;
                return true;
            }
            
            if ((nextExpr != null) && (nextExpr.Code == AstCode.Stsfld) && nextExpr.Arguments.Count == 1)
            {
                // exprVar = ...
                // stsfld(fld, exprVar)
                // ->
                // exprVar = stsfld(fld, ...))
                if (nextExpr.Arguments[0].MatchLdloc(exprVar))
                {
                    body.RemoveAt(pos + 1); // remove stsfld
                    nextExpr.Arguments[0] = initializer;
                    ((AstExpression)body[pos]).Arguments[0] = nextExpr;
                    return true;
                }
            }
            return false;
        }