public bool InlineAllVariables() { bool modified = false; AstInlining i = new AstInlining(method); foreach (AstBlock block in method.GetSelfAndChildrenRecursive<AstBlock>()) modified |= i.InlineAllInBlock(block); return modified; }
public bool InlineAllVariables() { bool modified = false; AstInlining i = new AstInlining(method); foreach (AstBlock block in method.GetSelfAndChildrenRecursive <AstBlock>()) { modified |= i.InlineAllInBlock(block); } return(modified); }
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); }
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); }
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; }