private bool TryOptimizeCompareWithZero(ILCompilationUnit unit, ILFlagsVariable fl, ILVariableExpression flUsage)
        {
            if (fl.ImplicitAssignments.Count != 1)
            {
                return(false);
            }

            var flAssignment = fl.ImplicitAssignments.First();

            MatchResult match;

            if ((match = ComparePattern.Match(flAssignment)).Success) // (cmp(a, b); equals(FL, 0)) <=> (a == b)
            {
                return(TryOptimizeToEquals(unit, fl, flUsage, flAssignment, match));
            }
            if ((match = BigRelationalPattern.Match(flAssignment)).Success)
            {
                return(TryOptimizeToLessThan(unit, fl, flUsage, flAssignment, match));
            }
            if ((match = AndRegistersPattern.Match(flAssignment)).Success)
            {
                return(TryOptimizeToGreaterThan(unit, fl, flUsage, flAssignment, match));
            }

            return(false);
        }
        private bool TryOptimizeToEquals(
            ILCompilationUnit unit,
            ILFlagsVariable fl,
            ILVariableExpression flUsage,
            ILExpression flAssignment,
            MatchResult match)
        {
            // Replace FL operation with the new comparison operation.
            ILOpCode opcode;

            switch (((ILInstructionExpression)flAssignment).OpCode.Code)
            {
            case ILCode.CMP:
                opcode = ILOpCodes.__EQUALS_OBJECT;
                break;

            case ILCode.CMP_R32:
                opcode = ILOpCodes.__EQUALS_R32;
                break;

            case ILCode.CMP_R64:
                opcode = ILOpCodes.__EQUALS_R64;
                break;

            case ILCode.CMP_DWORD:
                opcode = ILOpCodes.__EQUALS_DWORD;
                break;

            case ILCode.CMP_QWORD:
                opcode = ILOpCodes.__EQUALS_QWORD;
                break;

            default:
                return(false);
            }

            // Introduce new variable for storing the result of the comparison.
            var resultVar = unit.GetOrCreateVariable($"simplified_{fl.Name}");

            resultVar.VariableType = VMType.Dword;

            var assignment = new ILAssignmentStatement(resultVar,
                                                       new ILInstructionExpression(-1, opcode, null, VMType.Dword)
            {
                Arguments =
                {
                    (ILExpression)match.Captures["left"][0].Remove(),
                    (ILExpression)match.Captures["right"][0].Remove()
                }
            });

            fl.ImplicitAssignments.Remove(flAssignment);
            flAssignment.Parent.ReplaceWith(assignment);

            // Replace FL reference with new variable.
            flUsage.Variable = null;
            flUsage.Parent.Parent.ReplaceWith(new ILVariableExpression(resultVar));

            return(true);
        }
Esempio n. 3
0
        private static void ReplaceRawLocalReferences(ILCompilationUnit unit, ILogger logger)
        {
            // Find in each block the patterns for loading and/or storing local variable values,
            // and replace them with a normal variable expression or assignment statement.

            foreach (var node in unit.ControlFlowGraph.Nodes)
            {
                var block = (ILAstBlock)node.UserData[ILAstBlock.AstBlockProperty];

                for (int i = 0; i < block.Statements.Count; i++)
                {
                    // TODO: Might need some extra checks after the match of a pattern.
                    //       Variables referenced in the expressions are not checked for
                    //       equality.

                    MatchResult match;
                    if ((match = StoreToLocalPattern.Match(block.Statements, i)).Success)
                    {
                        ReplaceStoreToLocal(unit, match, logger);
                    }
                    else if ((match = LoadLocalPattern.Match(block.Statements, i)).Success)
                    {
                        ReplaceLoadToLocal(unit, match, logger);
                    }
                    else if ((match = LoadLocalRefPattern.Match(block.Statements, i)).Success)
                    {
                        ReplaceLoadLocalRef(unit, match, logger);
                    }
                }
            }
        }
Esempio n. 4
0
        public bool ApplyTransformation(ILCompilationUnit unit, ILogger logger)
        {
            int iteration = 0;

            bool changed = true;

            while (changed && iteration < MaxIterations)
            {
                iteration++;
                logger.Debug2(Name, $"Started iteration {iteration.ToString()}...");
                OnIterationStart();

                changed = PerformSingleIteration(unit, logger, iteration);

                logger.Debug2(Name, $"Finished iteration {iteration.ToString()} (AST has changed: {changed.ToString()}).");
                OnIterationEnd();
            }

            if (iteration == MaxIterations && changed)
            {
                logger.Warning(Name,
                               $"Reached maximum amount of iterations of {MaxIterations.ToString()} and AST is "
                               + "still changing. This might be a bug in the transformer pipeline where transforms keep "
                               + "cancelling each other out, or the method to devirtualise is too complex for the provided "
                               + "upper bound of iterations.");
            }

            return(iteration > 1);
        }
Esempio n. 5
0
        private static ILVariable ResolveVariable(ILCompilationUnit unit, int offset, ILogger logger)
        {
            var field = unit.FrameLayout.Resolve(offset);

            if (!field.IsValid)
            {
                switch (field.FieldKind)
                {
                case FrameFieldKind.Parameter:
                    logger.Warning(Tag, $"Reference to non-existing parameter {field.Index} detected.");
                    break;

                case FrameFieldKind.ReturnAddress:
                    logger.Warning(Tag, $"Reference to return address detected.");
                    break;

                case FrameFieldKind.CallersBasePointer:
                    logger.Warning(Tag, $"Reference to callers base pointer detected.");
                    break;

                case FrameFieldKind.LocalVariable:
                    logger.Warning(Tag, $"Reference to non-existing local variable {field.Index} detected.");
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            return(unit.GetOrCreateVariable(field));
        }
Esempio n. 6
0
        private static void DetermineAndDeclareLocals(ILCompilationUnit unit)
        {
            int localsCount = DetermineLocalCountFromPrologue(unit);

            for (int i = 0; i < localsCount; i++)
            {
                unit.GetOrCreateVariable("local_" + i);
            }
        }
Esempio n. 7
0
        public void ApplyTransformation(ILCompilationUnit unit, ILogger logger)
        {
            var classes = ObtainPhiCongruenceClasses(unit);

            foreach (var @class in classes)
            {
                @class.ReplaceVarsWithRepresentative();
                @class.RemovePhiNodes();
            }
        }
Esempio n. 8
0
        public virtual bool VisitCompilationUnit(ILCompilationUnit unit)
        {
            bool changed = false;

            foreach (var node in unit.ControlFlowGraph.Nodes)
            {
                var block = (ILAstBlock)node.UserData[ILAstBlock.AstBlockProperty];
                changed |= block.AcceptVisitor(this);
            }

            return(changed);
        }
Esempio n. 9
0
        public virtual bool ApplyTransformation(ILCompilationUnit unit, ILogger logger)
        {
            bool changed = false;

            while (unit.AcceptVisitor(this))
            {
                changed = true;
                // Repeat until no more changes.
            }

            return(changed);
        }
Esempio n. 10
0
        private static int DetermineLocalCountFromPrologue(ILCompilationUnit unit)
        {
            var entryBlock = (ILAstBlock)unit.ControlFlowGraph.Entrypoint.UserData[ILAstBlock.AstBlockProperty];

            var match = AllocateLocalsPattern.FindMatch(entryBlock.Statements);

            if (match.Success)
            {
                var pushLocalCount = (ILInstructionExpression)match.Captures["push_local_count"][0];
                return(Convert.ToInt32(pushLocalCount.Operand));
            }

            return(0);
        }
Esempio n. 11
0
        private bool TryOptimizeFlagComparison(ILCompilationUnit unit, ILVariableExpression flagUsage, ILFlagsVariable fl, VMFlags flags)
        {
            // TODO: support other flag combinations.
            bool changed = false;

            switch (flags)
            {
            case VMFlags.ZERO:
                changed |= TryOptimizeCompareWithZero(unit, fl, flagUsage);
                break;
            }

            return(changed);
        }
Esempio n. 12
0
        private bool PerformSingleIteration(ILCompilationUnit unit, ILogger logger, int iterationNumber)
        {
            bool changed = false;

            foreach (var transform in Transforms)
            {
                logger.Debug2(Name, "Applying " + transform.Name + "...");
                OnTransformStart(new ILTransformEventArgs(unit, transform, iterationNumber));
                changed |= transform.ApplyTransformation(unit, logger);
                OnTransformEnd(new ILTransformEventArgs(unit, transform, iterationNumber));
            }

            return(changed);
        }
Esempio n. 13
0
        private static void RemoveSPAssignments(ILCompilationUnit unit)
        {
            // We assume all stack related operations are already handled.
            // We can therefore safely remove any reference to SP.

            var sp = unit.GetOrCreateVariable("SP");

            foreach (var assign in sp.AssignedBy.ToArray())
            {
                assign.Variable = null;
                foreach (var use in assign.Value.AcceptVisitor(VariableUsageCollector.Instance))
                {
                    use.Variable = null;
                }
                assign.Remove();
            }
        }
Esempio n. 14
0
        public void VisitCompilationUnit(ILCompilationUnit unit)
        {
            _offsets.Clear();
            foreach (var variable in unit.Variables.OfType <ILFlagsVariable>())
            {
                foreach (int dataSource in variable.DataSources)
                {
                    _offsets.Add(dataSource, variable);
                }
            }

            foreach (var node in unit.ControlFlowGraph.Nodes)
            {
                var block = (ILAstBlock)node.UserData[ILAstBlock.AstBlockProperty];
                block.AcceptVisitor(this);
            }
        }
Esempio n. 15
0
        private static void ReplaceLoadToLocal(ILCompilationUnit unit, MatchResult match, ILogger logger)
        {
            // Obtain variable that is referenced.
            var pushOffset = (ILInstructionExpression)match.Captures["push_offset"][0];
            int offset     = unchecked ((int)Convert.ToUInt32(pushOffset.Operand));
            var variable   = ResolveVariable(unit, offset, logger);

            // Remove the original expression containing the address and unregister the
            // associated variable.
            var lindExpr = (ILInstructionExpression)match.Captures["load"][0];
            var address  = (ILVariableExpression)lindExpr.Arguments[0].Remove();

            address.Variable = null;

            // Replace with normal variable expression.
            lindExpr.ReplaceWith(new ILVariableExpression(variable));
        }
Esempio n. 16
0
        private static void ReplaceLoadLocalRef(ILCompilationUnit unit, MatchResult match, ILogger logger)
        {
            // Obtain variable that is referenced.
            var pushOffset = (ILInstructionExpression)match.Captures["push_offset"][0];
            int offset     = unchecked ((int)Convert.ToUInt32(pushOffset.Operand));
            var variable   = ResolveVariable(unit, offset, logger);

            // Obtain reference to final loaded value of the variable.
            var finalValue = (ILVariableExpression)match.Captures["final_value"][0];

            finalValue.Variable = null;

            // Replace with normal variable expression.
            finalValue.ReplaceWith(new ILVariableExpression(variable)
            {
                IsReference    = true,
                ExpressionType = VMType.Object
            });
        }
Esempio n. 17
0
        private static void ReplaceStoreToLocal(ILCompilationUnit unit, MatchResult match, ILogger logger)
        {
            // Obtain variable that is referenced.
            var pushOffset = (ILInstructionExpression)match.Captures["push_offset"][0];
            int offset     = unchecked ((int)Convert.ToUInt32(pushOffset.Operand));
            var variable   = ResolveVariable(unit, offset, logger);

            // Obtain SIND_xxxx expression.
            var statement = (ILExpressionStatement)match.Captures["store"][0];
            var sindExpr  = (ILInstructionExpression)statement.Expression;

            // Remove value.
            var value = (ILExpression)sindExpr.Arguments[0].Remove();

            // Remove the original expression containing the address and unregister the
            // associated variable.
            var address = (ILVariableExpression)sindExpr.Arguments[0].Remove();

            address.Variable = null;

            // Replace with normal assignment.
            statement.ReplaceWith(new ILAssignmentStatement(variable, value));
        }
Esempio n. 18
0
        public override bool VisitCompilationUnit(ILCompilationUnit unit)
        {
            bool changed      = false;
            bool continueLoop = true;

            while (continueLoop)
            {
                continueLoop = false;

                foreach (var variable in unit.Variables.OfType <ILFlagsVariable>())
                {
                    if (variable.UsedBy.Count == 1)
                    {
                        var use = variable.UsedBy[0];

                        var andExpression = use.Parent.Parent;
                        var andMatch      = FLAndConstantPattern.Match(andExpression);
                        if (andMatch.Success)
                        {
                            var fl       = (ILFlagsVariable)((ILVariableExpression)andMatch.Captures["fl"][0]).Variable;
                            var constant = (ILInstructionExpression)andMatch.Captures["constant"][0];
                            var flags    = _constants.ToFlags((byte)(uint)constant.Operand);

                            continueLoop = TryOptimizeFlagComparison(unit, use, fl, flags);
                            if (continueLoop)
                            {
                                changed = true;
                                break;
                            }
                        }
                    }
                }
            }

            return(changed);
        }
Esempio n. 19
0
 void IILAstTransform.ApplyTransformation(ILCompilationUnit unit, ILogger logger)
 {
     ApplyTransformation(unit, logger);
 }
Esempio n. 20
0
        private static IEnumerable <PhiCongruenceClass> ObtainPhiCongruenceClasses(ILCompilationUnit unit)
        {
            var classes         = new HashSet <PhiCongruenceClass>();
            var variableToClass = new Dictionary <ILVariable, PhiCongruenceClass>();

            foreach (var variable in unit.Variables.ToArray())
            {
                // Phi nodes are always present in the form:
                // v = phi(v1, v2, ..., vn)

                // A situation like the following might happen:
                //
                // a3 = phi(a1, a2)
                // ...
                // a5 = phi(a3, a5)
                //
                // Here, a3 and a5 are connected and form an equivalence class.
                //

                if (variable.AssignedBy.Count == 1 && variable.AssignedBy[0].Value is ILPhiExpression phi)
                {
                    // Check if variable does not belong to any equivalence class already.
                    var connectedVariables = new HashSet <ILVariable>(phi.Variables.Select(x => x.Variable))
                    {
                        variable
                    };

                    var congruenceClasses = new List <PhiCongruenceClass>();
                    foreach (var connectedVar in connectedVariables.ToArray())
                    {
                        if (variableToClass.TryGetValue(connectedVar, out var congruenceClass))
                        {
                            // The referenced variable is already part of another class, we need to combine the
                            // two classes together.
                            congruenceClasses.Add(congruenceClass);
                            classes.Remove(congruenceClass);
                            connectedVariables.UnionWith(congruenceClass.Variables);
                        }
                    }

                    PhiCongruenceClass finalClass;
                    if (congruenceClasses.Count == 0)
                    {
                        // No variable was part of a class yet => We need a new one.
                        var representative = unit.GetOrCreateVariable("phi_" + variableToClass.Count);
                        representative.IsVirtual    = connectedVariables.First().IsVirtual;
                        representative.VariableType = variable.VariableType;
                        finalClass = new PhiCongruenceClass(representative);
                    }
                    else
                    {
                        // At least one of the variables was part of a class already.
                        // Pick one class that we are going to expand.
                        finalClass = congruenceClasses[0];
                    }

                    // Add all connected variables to the new class.
                    finalClass.Variables.UnionWith(connectedVariables);
                    foreach (var connectedVar in connectedVariables)
                    {
                        variableToClass[connectedVar] = finalClass;
                    }

                    classes.Add(finalClass);
                }
            }

            return(classes);
        }
Esempio n. 21
0
 public override bool ApplyTransformation(ILCompilationUnit unit, ILogger logger)
 {
     return(base.ApplyTransformation(unit, logger) && unit.RemoveNonUsedVariables());
 }
Esempio n. 22
0
        private static Dictionary <Node, ICollection <ILAssignmentStatement> > InsertPhiNodes(ILCompilationUnit unit)
        {
            var result = unit.ControlFlowGraph.Nodes.ToDictionary(
                x => x,
                x => (ICollection <ILAssignmentStatement>) new List <ILAssignmentStatement>());

            // We try to find all variables that have more than one assignment, and therefore have multiple
            // versions of it during execution of the program. This is only a problem when they have different
            // values at join nodes, as depicted below. We therefore need to get to the dominance frontier of
            // those nodes and insert phi nodes there.
            //
            //  [ x1 <- value1 ]         [ x2 <- value2 ]
            //        |                        |
            //        '------------+-----------'
            //                     |
            //          [ x3 <- phi(x1, x2) ]
            //

            // Collect all nodes that contain a variable assignment (i.e. a new definition).
            var variableBlocks = unit.Variables.ToDictionary(
                x => x,
                x => new HashSet <Node>(x.AssignedBy.Select(a => a.GetParentNode())));

            foreach (var variable in unit.Variables.Where(x =>
                                                          x.AssignedBy.Count > 1 || // If the variable has more than one definition
                                                          GetNodesReferencingVariable(x).Count() > 1) // Or is used in multiple nodes.
                     )
            {
                var agenda = new Queue <Node>(variableBlocks[variable]);
                while (agenda.Count > 0)
                {
                    var current = agenda.Dequeue();
                    foreach (var frontierNode in unit.DominatorInfo.GetDominanceFrontier(current))
                    {
                        // If the frontier node does not define a phi node already for this variable, we need to add it.
                        if (result[frontierNode].All(x => x.Variable != variable))
                        {
                            // Check if the variable is defined in the frontier node.
                            bool defined = variableBlocks[variable].Contains(frontierNode);

                            // Build phi node.
                            // The number of different versions of the variable is equal to the amount of predecessors.
                            var phiExpression = new ILPhiExpression(Enumerable
                                                                    .Repeat(variable, frontierNode.InDegree)
                                                                    .Select(v => new ILVariableExpression(v)));

                            var phiNode = new ILAssignmentStatement(variable, phiExpression);

                            // Insert at top of the current block.
                            var block = (ILAstBlock)frontierNode.UserData[ILAstBlock.AstBlockProperty];
                            block.Statements.Insert(0, phiNode);

                            // Register phi node.
                            result[frontierNode].Add(phiNode);

                            // We might have to check this node again if we introduce a new version of this variable
                            // at this node.
                            if (!defined)
                            {
                                agenda.Enqueue(frontierNode);
                            }
                        }
                    }
                }
            }

            return(result);
        }
Esempio n. 23
0
        public void ApplyTransformation(ILCompilationUnit unit, ILogger logger)
        {
            var phiNodes = InsertPhiNodes(unit);

            RenameVariables(unit, phiNodes);
        }
Esempio n. 24
0
        private static void RenameVariables(ILCompilationUnit unit,
                                            IDictionary <Node, ICollection <ILAssignmentStatement> > phiNodes)
        {
            // We keep track of two variables for each variable.
            // - A counter to introduce new variables with new names that are unique throughout the entire function.
            // - A stack containing the current versions of the variable.
            var counter = new Dictionary <ILVariable, int>();
            var stack   = new Dictionary <ILVariable, Stack <ILVariable> >();

            foreach (var variable in unit.Variables.Union(unit.Parameters))
            {
                counter[variable] = 0;
                stack[variable]   = new Stack <ILVariable>();

                // Note: This is a slight deviation of the original algorithm.
                // Some variables (such as registers) do not have an initial value specified in the method.
                // To avoid problems, we add the "global" definition to the stack.
                stack[variable].Push(variable);
            }

            // Start at the entry point of the graph.
            Rename(unit.ControlFlowGraph.Entrypoint);

            void Rename(Node n)
            {
                var block        = (ILAstBlock)n.UserData[ILAstBlock.AstBlockProperty];
                var originalVars = new Dictionary <ILAssignmentStatement, ILVariable>();

                foreach (var statement in block.Statements)
                {
                    bool updateVariables = true;

                    if (statement is ILAssignmentStatement assignment)
                    {
                        var variable = assignment.Variable;
                        originalVars.Add(assignment, variable);

                        // We have a new version of a variable. Let's introduce a new version.
                        counter[variable]++;
                        var newVariable = unit.GetOrCreateVariable($"{variable.Name}_v{counter[variable].ToString()}");
                        newVariable.IsVirtual    = variable.IsVirtual;
                        newVariable.VariableType = variable.VariableType;
                        stack[variable].Push(newVariable);

                        // Update the variable in the assignment.
                        assignment.Variable = newVariable;

                        // Don't update arguments of phi nodes. They are updated somewhere else.
                        if (assignment.Value is ILPhiExpression)
                        {
                            updateVariables = false;
                        }
                    }

                    if (updateVariables)
                    {
                        // Update variables inside the statement with the new versions.
                        foreach (var use in statement.AcceptVisitor(VariableUsageCollector.Instance))
                        {
                            use.Variable = stack[use.Variable].Peek();
                        }
                    }
                }

                // Update phi statements in successor nodes.
                foreach (var successor in n.GetSuccessors())
                {
                    // Determine the index of the phi expression argument.
                    // TODO: Might be inefficient to do an OrderBy every time.
                    //       Maybe optimise by ordering (e.g. numbering) the edges beforehand?
                    int argumentIndex = successor.GetPredecessors()
                                        .OrderBy(x => x.Name)
                                        .ToList()
                                        .IndexOf(n);

                    // Update all variables in the phi nodes to the new versions.
                    foreach (var phiNode in phiNodes[successor])
                    {
                        var phiExpression = (ILPhiExpression)phiNode.Value;
                        var oldVariable   = phiExpression.Variables[argumentIndex].Variable;
                        var newVariable   = stack[oldVariable].Peek();
                        phiExpression.Variables[argumentIndex].Variable = newVariable;
                    }
                }

                foreach (var child in unit.DominatorTree.Nodes[n.Name].GetSuccessors())
                {
                    Rename(unit.ControlFlowGraph.Nodes[child.Name]);
                }

                // We are done with the newly introduced variables.
                // Pop all new versions of the variable from their stacks.
                foreach (var entry in originalVars)
                {
                    stack[entry.Value].Pop();
                }
            }
        }
Esempio n. 25
0
 public ILTransformEventArgs(ILCompilationUnit unit, IILAstTransform transform, int iteration)
 {
     Unit      = unit;
     Transform = transform;
     Iteration = iteration;
 }
Esempio n. 26
0
 public string VisitCompilationUnit(ILCompilationUnit unit) => "unit";
Esempio n. 27
0
        private bool TryOptimizeToGreaterThan(
            ILCompilationUnit unit,
            ILFlagsVariable fl,
            ILVariableExpression flUsage,
            ILExpression flAssignment,
            MatchResult match)
        {
            var root            = flUsage.Parent?.Parent?.Parent?.Parent;
            var relationalMatch = BigRelationalPattern.Match(root);

            if (!relationalMatch.Success || !ValidateRelationalMatch(relationalMatch, out var variable))
            {
                return(false);
            }

            if (!ValidateRemainingRelationalNodes(match, variable, VMFlags.OVERFLOW | VMFlags.SIGN | VMFlags.ZERO,
                                                  out var varAssignment, out var flAssignment2, out var cmpMatch))
            {
                return(false);
            }

            // We have a match! Decide which opcode to use based on the original comparison that was made.
            ILOpCode opcode;

            switch (((ILInstructionExpression)flAssignment2).OpCode.Code)
            {
            case ILCode.CMP_R32:
                opcode = ILOpCodes.__GT_R64;
                break;

            case ILCode.CMP_R64:
                opcode = ILOpCodes.__GT_R64;
                break;

            case ILCode.CMP_DWORD:
                opcode = ILOpCodes.__GT_DWORD;
                break;

            case ILCode.CMP_QWORD:
                opcode = ILOpCodes.__GT_QWORD;
                break;

            default:
                return(false);
            }

            // Introduce new variable for storing the result of the comparison.
            var resultVar = unit.GetOrCreateVariable("simplified_" + fl.Name);

            resultVar.VariableType = VMType.Dword;

            var newAssignment = new ILAssignmentStatement(resultVar,
                                                          new ILInstructionExpression(-1, opcode, null, VMType.Dword)
            {
                Arguments =
                {
                    (ILExpression)cmpMatch.Captures["left"][0].Remove(),
                    (ILExpression)cmpMatch.Captures["right"][0].Remove()
                }
            });

            // Remove var0 assignment.
            varAssignment.Variable = null;
            varAssignment.Remove();

            // Remove comparison.
            flAssignment2.Parent.Remove();

            // Clear references to variables.
            var referencesToRemove = new List <ILVariableExpression>();

            referencesToRemove.AddRange(root.AcceptVisitor(VariableUsageCollector.Instance));
            referencesToRemove.AddRange(flAssignment.AcceptVisitor(VariableUsageCollector.Instance));
            referencesToRemove.AddRange(varAssignment.AcceptVisitor(VariableUsageCollector.Instance));
            referencesToRemove.AddRange(flAssignment2.AcceptVisitor(VariableUsageCollector.Instance));

            foreach (var reference in referencesToRemove)
            {
                reference.Variable = null;
                reference.Remove();
            }

            // Replace assignment and use of FL with new variable.
            flAssignment.FlagsVariable = null;
            flAssignment.Parent.ReplaceWith(newAssignment);
            root.ReplaceWith(new ILVariableExpression(resultVar));

            return(true);
        }
Esempio n. 28
0
 public void ApplyTransformation(ILCompilationUnit unit, ILogger logger)
 {
     RemoveSPAssignments(unit);
     DetermineAndDeclareLocals(unit);
     ReplaceRawLocalReferences(unit, logger);
 }