예제 #1
0
        public static void ReplaceVariables(ILNode node, Func <ILVariable, ILVariable> variableMapping)
        {
            ILExpression expr = node as ILExpression;

            if (expr != null)
            {
                ILVariable v = expr.Operand as ILVariable;
                if (v != null)
                {
                    expr.Operand = variableMapping(v);
                }
                foreach (ILExpression child in expr.Arguments)
                {
                    ReplaceVariables(child, variableMapping);
                }
            }
            else
            {
                var catchBlock = node as ILTryCatchBlock.CatchBlock;
                if (catchBlock != null && catchBlock.ExceptionVariable != null)
                {
                    catchBlock.ExceptionVariable = variableMapping(catchBlock.ExceptionVariable);
                }

                foreach (ILNode child in node.GetChildren())
                {
                    ReplaceVariables(child, variableMapping);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Converts call and callvirt instructions that read/write properties into CallGetter/CallSetter instructions.
        ///
        /// CallGetter/CallSetter is used to allow the ILAst to represent "while ((SomeProperty = value) != null)".
        ///
        /// Also simplifies 'newobj(SomeDelegate, target, ldvirtftn(F, target))' to 'newobj(SomeDelegate, target, ldvirtftn(F))'
        /// </summary>
        void IntroducePropertyAccessInstructions(ILNode node)
        {
            ILExpression parentExpr = node as ILExpression;

            if (parentExpr != null)
            {
                for (int i = 0; i < parentExpr.Arguments.Count; i++)
                {
                    ILExpression expr = parentExpr.Arguments[i];
                    IntroducePropertyAccessInstructions(expr);
                    IntroducePropertyAccessInstructions(expr, parentExpr, i);
                }
            }
            else
            {
                foreach (ILNode child in node.GetChildren())
                {
                    IntroducePropertyAccessInstructions(child);
                    ILExpression expr = child as ILExpression;
                    if (expr != null)
                    {
                        IntroducePropertyAccessInstructions(expr, null, -1);
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Reduce the nesting of conditions.
        /// It should be done on flat data that already had most gotos removed
        /// </summary>
        void ReduceIfNesting(ILNode node)
        {
            ILBlock block = node as ILBlock;

            if (block != null)
            {
                for (int i = 0; i < block.Body.Count; i++)
                {
                    ILCondition cond = block.Body[i] as ILCondition;
                    if (cond != null)
                    {
                        bool trueExits  = cond.TrueBlock.Body.LastOrDefault().IsUnconditionalControlFlow();
                        bool falseExits = cond.FalseBlock.Body.LastOrDefault().IsUnconditionalControlFlow();

                        if (trueExits)
                        {
                            // Move the false block after the condition
                            block.Body.InsertRange(i + 1, cond.FalseBlock.GetChildren());
                            cond.FalseBlock = new ILBlock();
                        }
                        else if (falseExits)
                        {
                            // Move the true block after the condition
                            block.Body.InsertRange(i + 1, cond.TrueBlock.GetChildren());
                            cond.TrueBlock = new ILBlock();
                        }

                        // Eliminate empty true block
                        if (!cond.TrueBlock.GetChildren().Any() && cond.FalseBlock.GetChildren().Any())
                        {
                            // Swap bodies
                            ILBlock tmp = cond.TrueBlock;
                            cond.TrueBlock  = cond.FalseBlock;
                            cond.FalseBlock = tmp;
                            cond.Condition  = new ILExpression(ILCode.LogicNot, null, cond.Condition);
                        }
                    }
                }
            }

            // We are changing the number of blocks so we use plain old recursion to get all blocks
            foreach (ILNode child in node.GetChildren())
            {
                if (child != null && !(child is ILExpression))
                {
                    ReduceIfNesting(child);
                }
            }
        }
예제 #4
0
파일: ILInlining.cs 프로젝트: ropean/Usable
        void AnalyzeNode(ILNode node)
        {
            ILExpression expr = node as ILExpression;

            if (expr != null)
            {
                ILVariable locVar = expr.Operand as ILVariable;
                if (locVar != null)
                {
                    if (expr.Code == ILCode.Stloc)
                    {
                        numStloc[locVar] = numStloc.GetOrDefault(locVar) + 1;
                    }
                    else if (expr.Code == ILCode.Ldloc)
                    {
                        numLdloc[locVar] = numLdloc.GetOrDefault(locVar) + 1;
                    }
                    else if (expr.Code == ILCode.Ldloca)
                    {
                        numLdloca[locVar] = numLdloca.GetOrDefault(locVar) + 1;
                    }
                    else
                    {
                        throw new NotSupportedException(expr.Code.ToString());
                    }
                }
                foreach (ILExpression child in expr.Arguments)
                {
                    AnalyzeNode(child);
                }
            }
            else
            {
                var catchBlock = node as ILTryCatchBlock.CatchBlock;
                if (catchBlock != null && catchBlock.ExceptionVariable != null)
                {
                    numStloc[catchBlock.ExceptionVariable] = numStloc.GetOrDefault(catchBlock.ExceptionVariable) + 1;
                }

                foreach (ILNode child in node.GetChildren())
                {
                    AnalyzeNode(child);
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Flattens all nested basic blocks, except the the top level 'node' argument
        /// </summary>
        void FlattenBasicBlocks(ILNode node)
        {
            ILBlock block = node as ILBlock;

            if (block != null)
            {
                List <ILNode> flatBody = new List <ILNode>();
                foreach (ILNode child in block.GetChildren())
                {
                    FlattenBasicBlocks(child);
                    ILBasicBlock childAsBB = child as ILBasicBlock;
                    if (childAsBB != null)
                    {
                        if (!(childAsBB.Body.FirstOrDefault() is ILLabel))
                        {
                            throw new Exception("Basic block has to start with a label. \n" + childAsBB.ToString());
                        }
                        if (childAsBB.Body.LastOrDefault() is ILExpression && !childAsBB.Body.LastOrDefault().IsUnconditionalControlFlow())
                        {
                            throw new Exception("Basci block has to end with unconditional control flow. \n" + childAsBB.ToString());
                        }
                        flatBody.AddRange(childAsBB.GetChildren());
                    }
                    else
                    {
                        flatBody.Add(child);
                    }
                }
                block.EntryGoto = null;
                block.Body      = flatBody;
            }
            else if (node is ILExpression)
            {
                // Optimization - no need to check expressions
            }
            else if (node != null)
            {
                // Recursively find all ILBlocks
                foreach (ILNode child in node.GetChildren())
                {
                    FlattenBasicBlocks(child);
                }
            }
        }