示例#1
0
 public void VisitBlock(ILAstBlock block)
 {
     foreach (var statement in block.Statements)
     {
         statement.AcceptVisitor(this);
     }
 }
示例#2
0
        public virtual bool VisitBlock(ILAstBlock block)
        {
            bool changed = false;

            foreach (var statement in block.Statements)
            {
                changed |= statement.AcceptVisitor(this);
            }
            return(changed);
        }
示例#3
0
 public string VisitBlock(ILAstBlock block) => "block";
示例#4
0
        public override bool VisitBlock(ILAstBlock block)
        {
            // Find all assignments of variables, and count the amount of usages for each variable.
            // If the variable is not used it can be removed. If it is only used once, it can be inlined.

            bool changed = false;

            for (var i = 0; i < block.Statements.Count; i++)
            {
                // Find assignment statement:
                var statement = block.Statements[i];
                if (statement is ILAssignmentStatement assignmentStatement && !(assignmentStatement.Variable is ILParameter))
                {
                    bool removeStatement = true;
                    var  usages          = assignmentStatement.Variable.UsedBy;

                    // Count usages.
                    switch (usages.Count)
                    {
                    case 0:
                    {
                        if (assignmentStatement.Variable is ILFlagsVariable)
                        {
                            removeStatement = false;
                        }
                        if (assignmentStatement.Value.HasPotentialSideEffects)
                        {
                            // If the value has side effects, it cannot be removed.
                            removeStatement = false;
                            assignmentStatement.ReplaceWith(new ILExpressionStatement((ILExpression)assignmentStatement.Value.Remove()));
                        }
                        else
                        {
                            // Find all variables that are referenced in the statement, and remove them from the
                            // usage lists.
                            var embeddedReferences = assignmentStatement.Value.AcceptVisitor(VariableUsageCollector.Instance);
                            foreach (var reference in embeddedReferences)
                            {
                                reference.Variable.UsedBy.Remove(reference);
                            }
                        }

                        break;
                    }

                    case 1 when assignmentStatement.Variable.IsVirtual
                        // We cannot inline into phi nodes.
                        && !(usages[0].Parent is ILPhiExpression)
                        // We also cannot insert phi nodes in arbitrary expressions other than assignments.
                        && !(assignmentStatement.Value is ILPhiExpression)
                        // Finally, we cannot inline expressions with side effects => depend on order of execution.
                        && (!assignmentStatement.Value.HasPotentialSideEffects || !HasNoSideEffectsInBetween(assignmentStatement, usages[0])):
                    {
                        // Inline the variable's value.
                        InlineVariable(usages[0], assignmentStatement);
                        usages.Clear();
                        break;
                    }

                    default:
                    {
                        removeStatement = false;
                        break;
                    }
                    }

                    if (removeStatement)
                    {
                        // We applied a transformation, remove the original statement.
                        block.Statements.RemoveAt(i);
                        i--;
                        changed = true;
                    }
                }
            }

            return(changed);
        }