Beispiel #1
0
        /// <summary>
        /// Performs stage specific processing on the compiler context.
        /// </summary>
        public void Run()
        {
            // Previous stage
            IPipelineStage prevStage = MethodCompiler.GetPreviousStage(typeof(IMethodCompilerStage));

            // Line number
            int index = 1;

            Debug.WriteLine(String.Format("IR representation of method {0} after stage {1}", MethodCompiler.Method, prevStage.Name));

            foreach (BasicBlock block in BasicBlocks)
            {
                Debug.WriteLine(String.Format("Block #{0} - label L_{1:X4}", index, block.Label));

                foreach (BasicBlock prev in block.PreviousBlocks)
                {
                    Debug.WriteLine(String.Format("  Prev: L_{0:X4}", prev.Label));
                }

                Debug.Indent();
                LogInstructions(new Context(InstructionSet, block));
                Debug.Unindent();

                foreach (BasicBlock next in block.NextBlocks)
                {
                    Debug.WriteLine(String.Format("  Next: L_{0:X4}", next.Label));
                }

                index++;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Performs stage specific processing on the compiler context.
        /// </summary>
        public void Run()
        {
            _dominanceProvider = (IDominanceProvider)MethodCompiler.GetPreviousStage(typeof(IDominanceProvider));
            Debug.Assert(_dominanceProvider != null, "SSA Conversion requires a dominance provider.");
            if (_dominanceProvider == null)
            {
                throw new InvalidOperationException("SSA Conversion requires a dominance provider.");
            }

            // Allocate space for live outs
            _liveness = new IDictionary <StackOperand, StackOperand> [BasicBlocks.Count];
            // Retrieve the dominance frontier Blocks
            _dominanceFrontierBlocks = _dominanceProvider.GetDominanceFrontier();

            // Add ref/out parameters to the epilogue block to have uses there...
            AddPhiFunctionsForOutParameters();

            // Transformation worklist
            Queue <WorkItem> workList = new Queue <WorkItem> ();

            /* Move parameter operands into the dictionary as version 0,
             * because they are live at entry and maybe referenced. Anyways, an
             * assignment to a parameter is also SSA related.
             */
            IDictionary <StackOperand, StackOperand> liveIn = new Dictionary <StackOperand, StackOperand> (s_comparer);
            int i = 0;

            if (MethodCompiler.Method.Signature.HasThis)
            {
                StackOperand param = (StackOperand)MethodCompiler.GetParameterOperand(0);
                liveIn.Add(param, param);
                i++;
            }
            for (int j = 0; j < MethodCompiler.Method.Parameters.Count; j++)
            {
                StackOperand param = (StackOperand)MethodCompiler.GetParameterOperand(i + j);
                liveIn.Add(param, param);
            }

            // Start with the very first block
            workList.Enqueue(new WorkItem(BasicBlocks[0], null, liveIn));

            // Iterate until the worklist is empty
            while (workList.Count != 0)
            {
                // Remove the block From the queue
                WorkItem workItem = workList.Dequeue();

                // Transform the block
                BasicBlock block    = workItem.block;
                bool       schedule = TransformToSsaForm(new Context(InstructionSet, block), workItem.caller, workItem.liveIn, out liveIn);
                _liveness[block.Sequence] = liveIn;

                if (schedule)
                {
                    // Add all branch targets to the work list
                    foreach (BasicBlock next in block.NextBlocks)
                    {
                        // Only follow backward branches, if we've redefined a variable
                        // this may force us to reinsert a PHI function in a block we
                        // already have completed processing on.
                        workList.Enqueue(new WorkItem(next, block, liveIn));
                    }
                }
            }
        }
        /// <summary>
        /// Runs the specified compiler.
        /// </summary>
        public void Run()
        {
            if (!methodCount.ContainsKey(MethodCompiler.Method.Name))
            {
                methodCount[MethodCompiler.Method.Name] = 0;
            }

            ++methodCount[MethodCompiler.Method.Name];

            // Retreive the first block
            firstBlock = FindBlock(-1);

            workList = new Stack <BasicBlock> ();
            workList.Push(firstBlock);
            workArray = new BitArray(BasicBlocks.Count);

            string methodName = MethodCompiler.Method.Name;

            methodName = methodName.Replace("<", "");
            methodName = methodName.Replace(">", "");
            methodName = methodName.Replace("$", "");
            methodName = methodName.Replace(".", "");
            IPipelineStage previousStage = MethodCompiler.GetPreviousStage(typeof(IMethodCompilerStage));

            dotFile.WriteLine("subgraph cluster" + methodName + "_FlowGraph {");
            dotFile.WriteLine("label = \"Method: " + methodName + "(" + MethodCompiler.Method.Signature + ") after " + previousStage.Name + "\"");
            //dotFile.WriteLine("graph [rankdir = \"TB\"];");

            string nodes = string.Empty;
            string edges = string.Empty;

            foreach (BasicBlock block in BasicBlocks)
            {
                string nodeName    = string.Empty;
                string nodeContent = string.Empty;
                string nextNode    = string.Empty;

                nodeName = methodName + "_" + block.ToString();
                //nodeName = nodeName.Replace("-", "_");

                nodeContent += "<tr><td bgcolor=\"black\" align=\"center\" colspan=\"4\"><font face=\"Courier\" color=\"white\">L_" + block.Label.ToString("x4") + "</font></td></tr>";

                int field = 0;
                int i     = 0;

                for (Context ctx = new Context(InstructionSet, block); !ctx.EndOfInstruction; ctx.GotoNext())
                {
                    if (ctx.Instruction == null)
                    {
                        continue;
                    }

                    string color;
                    string inst = ctx.Instruction.ToString(ctx).Replace("&", "&amp;");
                    inst = inst.Replace("<", "&lt;");
                    inst = inst.Replace(">", "&gt;");

                    if (inst.StartsWith("IL") || inst.StartsWith("T_"))
                    {
                        color = "#0000ff5f";
                    }
                    else if (inst.StartsWith("IR"))
                    {
                        color = "#ff00005f";
                    }
                    else
                    {
                        color = "#CFD6CEff";
                    }


                    nodeContent += "<tr height=\"20\"><td bgcolor=\"white\" align=\"right\" width=\"20\"><img src=\"icon.png\"/></td><td bgcolor=\"white\" align=\"right\">" + (i++) + "</td><td bgcolor=\"" + color + "\" align=\"center\" colspan=\"2\"><font face=\"Courier\">" + inst + "</font></td></tr>";

                    ++field;
                }

                if (nodeContent != string.Empty && nodeContent[nodeContent.Length - 1] == '|')
                {
                    nodeContent = nodeContent.Substring(0, nodeContent.Length - 2);
                }

                if (nodeContent != string.Empty)
                {
                    nodes += "\"" + nodeName + "\" [label = <<table border=\"1\" cellborder=\"0\" cellpadding=\"3\" bgcolor=\"white\">" + nodeContent + "</table>> shape = \"Mrecord\"];\r\n";
                }


                foreach (BasicBlock nextBlock in block.NextBlocks)
                {
                    nextNode = methodName + "_" + nextBlock.ToString();

                    edges += "\"" + nodeName + "\"" + " -> " + "\"" + nextNode + "\";\r\n";
                }
            }

            dotFile.WriteLine(nodes);
            dotFile.WriteLine(edges);
            dotFile.WriteLine("};");
        }