public override ICodeNode VisitMethodInvocationExpression(MethodInvocationExpression node)
        {
            node.MethodExpression = (MethodReferenceExpression)Visit(node.MethodExpression);
            if (status != InliningResult.NotFound)
            {
                return node;
            }

            MethodReference methodRef = node.MethodExpression.Method;

            for (int i = 0; i < node.Arguments.Count; i++)
            {
                if (!methodRef.Parameters[i].ParameterType.IsByReference)
                {
                    node.Arguments[i] = (Expression)Visit(node.Arguments[i]);

                    if (status != InliningResult.NotFound)
                    {
                        return node;
                    }
                }
                else if (valueHasSideEffects)
                {
                    SideEffectsFinder sideEffectsFinder = new SideEffectsFinder();
                    if (sideEffectsFinder.HasSideEffectsRecursive(node.Arguments[i]))
                    {
                        status = InliningResult.Abort;
                        return node;
                    }
                }
            }

            return node;
        }
        public override ICodeNode VisitMethodInvocationExpression(MethodInvocationExpression node)
        {
            node.MethodExpression = (MethodReferenceExpression)Visit(node.MethodExpression);
            if (status != InliningResult.NotFound)
            {
                return(node);
            }

            MethodReference methodRef = node.MethodExpression.Method;

            for (int i = 0; i < node.Arguments.Count; i++)
            {
                if (!methodRef.Parameters[i].ParameterType.IsByReference)
                {
                    node.Arguments[i] = (Expression)Visit(node.Arguments[i]);

                    if (status != InliningResult.NotFound)
                    {
                        return(node);
                    }
                }
                else if (valueHasSideEffects)
                {
                    SideEffectsFinder sideEffectsFinder = new SideEffectsFinder();
                    if (sideEffectsFinder.HasSideEffectsRecursive(node.Arguments[i]))
                    {
                        status = InliningResult.Abort;
                        return(node);
                    }
                }
            }

            return(node);
        }
        public bool TryInlineVariable(VariableDefinition variableDef, Expression value, ICodeNode target, bool aggressive, out ICodeNode result)
        {
            this.variableDef = variableDef;
            this.value = value;

            if (!aggressive)
            {
                ASTNodeCounter counter = new ASTNodeCounter();
                if (counter.CountNodes(value) + counter.CountNodes(target) - 1 > MaxCount)
                {
                    result = target;
                    return false;
                }
            }

            SideEffectsFinder sideEffectsFinder = new SideEffectsFinder();
            valueHasSideEffects = sideEffectsFinder.HasSideEffectsRecursive(value);

            status = InliningResult.NotFound;
            result = Visit(target);
            return status == InliningResult.Success;
        }
Пример #4
0
        public bool TryInlineVariable(VariableDefinition variableDef, Expression value, ICodeNode target, bool aggressive, out ICodeNode result)
        {
            this.variableDef = variableDef;
            this.value       = value;

            if (!aggressive)
            {
                ASTNodeCounter counter = new ASTNodeCounter();
                if (counter.CountNodes(value) + counter.CountNodes(target) - 1 > MaxCount)
                {
                    result = target;
                    return(false);
                }
            }

            SideEffectsFinder sideEffectsFinder = new SideEffectsFinder();

            valueHasSideEffects = sideEffectsFinder.HasSideEffectsRecursive(value);

            status = InliningResult.NotFound;
            result = Visit(target);
            return(status == InliningResult.Success);
        }
        private void InlineAssignmentInSameBlock()
        {
            foreach (KeyValuePair <int, IList <Expression> > offsetToExpressionsPair in methodContext.Expressions.BlockExpressions)
            {
                IList <Expression> blockExpressions = offsetToExpressionsPair.Value;
                for (int i = 0; i < blockExpressions.Count - 1; i++)
                {
                    BinaryExpression binaryExpression = blockExpressions[i] as BinaryExpression;
                    if (binaryExpression == null || !binaryExpression.IsAssignmentExpression || binaryExpression.Left.CodeNodeType != CodeNodeType.VariableReferenceExpression)
                    {
                        continue;
                    }

                    VariableDefinition varDef = (binaryExpression.Left as VariableReferenceExpression).Variable.Resolve();
                    if (!variablesToInline.Contains(varDef))
                    {
                        continue;
                    }

                    Expression        value                    = binaryExpression.Right;
                    SideEffectsFinder sideEffectsFinder        = new SideEffectsFinder();
                    bool valueHasSideEffects                   = sideEffectsFinder.HasSideEffectsRecursive(value);
                    VariablesAndArgumentsFinder variableFinder = new VariablesAndArgumentsFinder();
                    variableFinder.Visit(value);
                    VariableReferenceFinder referenceFinder = new VariableReferenceFinder(variableFinder.Variables, variableFinder.Parameters);

                    for (int j = i + 1; j < blockExpressions.Count; j++)
                    {
                        ICodeNode result;
                        if (inliner.TryInlineVariable(varDef, value, blockExpressions[j], true, out result))
                        {
                            FixContextAfterInlining(varDef);
                            variablesToInline.Remove(varDef);

                            blockExpressions[j] = (Expression)result;
                            blockExpressions.RemoveAt(i);
                            i -= i > 0 ? 2 : 1;
                            break;
                        }
                        else if (valueHasSideEffects && sideEffectsFinder.HasSideEffectsRecursive(blockExpressions[j]))
                        {
                            break;
                        }
                        else if (referenceFinder.ContainsReference(blockExpressions[j]))
                        {
                            break;
                        }
                        else if (blockExpressions[j].CodeNodeType == CodeNodeType.BinaryExpression && (blockExpressions[j] as BinaryExpression).IsAssignmentExpression)
                        {
                            Expression assigned = (blockExpressions[j] as BinaryExpression).Left;
                            if (assigned.CodeNodeType == CodeNodeType.ArgumentReferenceExpression &&
                                variableFinder.Parameters.Contains((assigned as ArgumentReferenceExpression).Parameter.Resolve()) ||
                                assigned.CodeNodeType == CodeNodeType.VariableReferenceExpression &&
                                variableFinder.Variables.Contains((assigned as VariableReferenceExpression).Variable.Resolve()))
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }
 private void InlineAssignmentInSameBlock()
 {
     V_0 = this.methodContext.get_Expressions().get_BlockExpressions().GetEnumerator();
     try
     {
         while (V_0.MoveNext())
         {
             V_1 = V_0.get_Current();
             V_2 = V_1.get_Value();
             V_3 = 0;
             while (V_3 < V_2.get_Count() - 1)
             {
                 V_4 = V_2.get_Item(V_3) as BinaryExpression;
                 if (V_4 != null && V_4.get_IsAssignmentExpression() && V_4.get_Left().get_CodeNodeType() == 26)
                 {
                     V_5 = (V_4.get_Left() as VariableReferenceExpression).get_Variable().Resolve();
                     if (this.variablesToInline.Contains(V_5))
                     {
                         V_6 = V_4.get_Right();
                         V_7 = new SideEffectsFinder();
                         V_8 = V_7.HasSideEffectsRecursive(V_6);
                         V_9 = new StackVariablesInliner.VariablesArgumentsAndFieldsFinder();
                         V_9.Visit(V_6);
                         V_10 = new StackVariablesInliner.VariableReferenceFinder(V_9.get_Variables(), V_9.get_Parameters());
                         V_11 = V_3 + 1;
                         while (V_11 < V_2.get_Count())
                         {
                             if (!this.inliner.TryInlineVariable(V_5, V_6, V_2.get_Item(V_11), true, out V_12))
                             {
                                 if (V_8 && V_7.HasSideEffectsRecursive(V_2.get_Item(V_11)) || V_10.ContainsReference(V_2.get_Item(V_11)))
                                 {
                                     break;
                                 }
                                 if (V_2.get_Item(V_11).get_CodeNodeType() == 24 && (V_2.get_Item(V_11) as BinaryExpression).get_IsAssignmentExpression())
                                 {
                                     V_13 = (V_2.get_Item(V_11) as BinaryExpression).get_Left();
                                     if (V_13.get_CodeNodeType() == 25 && V_9.get_Parameters().Contains((V_13 as ArgumentReferenceExpression).get_Parameter().Resolve()) || V_13.get_CodeNodeType() == 26 && V_9.get_Variables().Contains((V_13 as VariableReferenceExpression).get_Variable().Resolve()) || V_13.get_CodeNodeType() == 30 && V_9.get_Fields().Contains((V_13 as FieldReferenceExpression).get_Field().Resolve()))
                                     {
                                         break;
                                     }
                                 }
                                 V_11 = V_11 + 1;
                             }
                             else
                             {
                                 this.FixContextAfterInlining(V_5);
                                 dummyVar0 = this.variablesToInline.Remove(V_5);
                                 V_2.set_Item(V_11, (Expression)V_12);
                                 V_2.RemoveAt(V_3);
                                 stackVariable141 = V_3;
                                 if (V_3 > 0)
                                 {
                                     stackVariable144 = 2;
                                 }
                                 else
                                 {
                                     stackVariable144 = 1;
                                 }
                                 V_3 = stackVariable141 - stackVariable144;
                                 break;
                             }
                         }
                     }
                 }
                 V_3 = V_3 + 1;
             }
         }
     }
     finally
     {
         ((IDisposable)V_0).Dispose();
     }
     return;
 }