TailCallAnalyzer.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / XmlUtils / System / Xml / Xsl / IlGen / TailCallAnalyzer.cs / 1 / TailCallAnalyzer.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
using System; 
using System.Diagnostics; 
using System.Xml.Xsl.Qil;
 
namespace System.Xml.Xsl.IlGen {

    /// 
    /// This analyzer walks each function in the graph and annotates Invoke nodes which can 
    /// be compiled using the IL .tailcall instruction.  This instruction will discard the
    /// current stack frame before calling the new function. 
    ///  
    internal static class TailCallAnalyzer {
 
        /// 
        /// Perform tail-call analysis on the functions in the specified QilExpression.
        /// 
        public static void Analyze(QilExpression qil) { 
            foreach (QilFunction ndFunc in qil.FunctionList) {
                // Only analyze functions which are pushed to the writer, since otherwise code 
                // is generated after the call instruction in order to process cached results 
                if (XmlILConstructInfo.Read(ndFunc).ConstructMethod == XmlILConstructMethod.Writer)
                    AnalyzeDefinition(ndFunc.Definition); 
            }
        }

        ///  
        /// Recursively analyze the definition of a function.
        ///  
        private static void AnalyzeDefinition(QilNode nd) { 
            Debug.Assert(XmlILConstructInfo.Read(nd).PushToWriterLast,
                         "Only need to analyze expressions which will be compiled in push mode."); 

            switch (nd.NodeType) {
                case QilNodeType.Invoke:
                    // Invoke node can either be compiled as IteratorThenWriter, or Writer. 
                    // Since IteratorThenWriter involves caching the results of the function call
                    // and iterating over them, .tailcall cannot be used 
                    if (XmlILConstructInfo.Read(nd).ConstructMethod == XmlILConstructMethod.Writer) 
                        OptimizerPatterns.Write(nd).AddPattern(OptimizerPatternName.TailCall);
                    break; 

                case QilNodeType.Loop: {
                    // Recursively analyze Loop return value
                    QilLoop ndLoop = (QilLoop) nd; 
                    if (ndLoop.Variable.NodeType == QilNodeType.Let || !ndLoop.Variable.Binding.XmlType.MaybeMany)
                        AnalyzeDefinition(ndLoop.Body); 
                    break; 
                }
 
                case QilNodeType.Sequence: {
                    // Recursively analyze last expression in Sequence
                    QilList ndSeq = (QilList) nd;
                    if (ndSeq.Count > 0) 
                        AnalyzeDefinition(ndSeq[ndSeq.Count - 1]);
                    break; 
                } 

                case QilNodeType.Choice: { 
                    // Recursively analyze Choice branches
                    QilChoice ndChoice = (QilChoice) nd;
                    for (int i = 0; i < ndChoice.Branches.Count; i++)
                        AnalyzeDefinition(ndChoice.Branches[i]); 
                    break;
                } 
 
                case QilNodeType.Conditional: {
                    // Recursively analyze Conditional branches 
                    QilTernary ndCond = (QilTernary) nd;
                    AnalyzeDefinition(ndCond.Center);
                    AnalyzeDefinition(ndCond.Right);
                    break; 
                }
 
                case QilNodeType.Nop: 
                    AnalyzeDefinition(((QilUnary) nd).Child);
                    break; 
            }
        }
    }
} 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
using System; 
using System.Diagnostics; 
using System.Xml.Xsl.Qil;
 
namespace System.Xml.Xsl.IlGen {

    /// 
    /// This analyzer walks each function in the graph and annotates Invoke nodes which can 
    /// be compiled using the IL .tailcall instruction.  This instruction will discard the
    /// current stack frame before calling the new function. 
    ///  
    internal static class TailCallAnalyzer {
 
        /// 
        /// Perform tail-call analysis on the functions in the specified QilExpression.
        /// 
        public static void Analyze(QilExpression qil) { 
            foreach (QilFunction ndFunc in qil.FunctionList) {
                // Only analyze functions which are pushed to the writer, since otherwise code 
                // is generated after the call instruction in order to process cached results 
                if (XmlILConstructInfo.Read(ndFunc).ConstructMethod == XmlILConstructMethod.Writer)
                    AnalyzeDefinition(ndFunc.Definition); 
            }
        }

        ///  
        /// Recursively analyze the definition of a function.
        ///  
        private static void AnalyzeDefinition(QilNode nd) { 
            Debug.Assert(XmlILConstructInfo.Read(nd).PushToWriterLast,
                         "Only need to analyze expressions which will be compiled in push mode."); 

            switch (nd.NodeType) {
                case QilNodeType.Invoke:
                    // Invoke node can either be compiled as IteratorThenWriter, or Writer. 
                    // Since IteratorThenWriter involves caching the results of the function call
                    // and iterating over them, .tailcall cannot be used 
                    if (XmlILConstructInfo.Read(nd).ConstructMethod == XmlILConstructMethod.Writer) 
                        OptimizerPatterns.Write(nd).AddPattern(OptimizerPatternName.TailCall);
                    break; 

                case QilNodeType.Loop: {
                    // Recursively analyze Loop return value
                    QilLoop ndLoop = (QilLoop) nd; 
                    if (ndLoop.Variable.NodeType == QilNodeType.Let || !ndLoop.Variable.Binding.XmlType.MaybeMany)
                        AnalyzeDefinition(ndLoop.Body); 
                    break; 
                }
 
                case QilNodeType.Sequence: {
                    // Recursively analyze last expression in Sequence
                    QilList ndSeq = (QilList) nd;
                    if (ndSeq.Count > 0) 
                        AnalyzeDefinition(ndSeq[ndSeq.Count - 1]);
                    break; 
                } 

                case QilNodeType.Choice: { 
                    // Recursively analyze Choice branches
                    QilChoice ndChoice = (QilChoice) nd;
                    for (int i = 0; i < ndChoice.Branches.Count; i++)
                        AnalyzeDefinition(ndChoice.Branches[i]); 
                    break;
                } 
 
                case QilNodeType.Conditional: {
                    // Recursively analyze Conditional branches 
                    QilTernary ndCond = (QilTernary) nd;
                    AnalyzeDefinition(ndCond.Center);
                    AnalyzeDefinition(ndCond.Right);
                    break; 
                }
 
                case QilNodeType.Nop: 
                    AnalyzeDefinition(((QilUnary) nd).Child);
                    break; 
            }
        }
    }
} 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK