示例#1
0
        void IMethodCompilerStage.Run()
        {
            if (AreExceptions)
                return;

            foreach (var block in this.basicBlocks)
                if (block.NextBlocks.Count == 0 && block.PreviousBlocks.Count == 0)
                    return;

            this.dominanceCalculationStage = this.methodCompiler.Pipeline.FindFirst<DominanceCalculationStage>() as IDominanceProvider;
            this.phiPlacementStage = this.methodCompiler.Pipeline.FindFirst<PhiPlacementStage>();

            var numberOfParameters = this.methodCompiler.Method.Parameters.Count;
            if (this.methodCompiler.Method.Signature.HasThis)
                ++numberOfParameters;

            foreach (var name in this.phiPlacementStage.Assignments.Keys)
                this.variableInformation[name] = new VariableInformation();

            for (var i = 0; i < numberOfParameters; ++i)
            {
                var op = this.methodCompiler.GetParameterOperand(i);
                var name = NameForOperand(op);
                this.variableInformation[name].Stack.Push(0);
                this.variableInformation[name].Count = 1;
            }

            for (var i = 0; methodCompiler.LocalVariables != null && i < methodCompiler.LocalVariables.Length; ++i)
            {
                var op = methodCompiler.LocalVariables[i];
                var name = NameForOperand(op);
                if (!this.variableInformation.ContainsKey(name))
                    this.variableInformation[name] = new VariableInformation();
                this.variableInformation[name].Stack.Push(0);
                this.variableInformation[name].Count = 1;
            }
            this.RenameVariables(this.FindBlock(-1).NextBlocks[0]);
            Debug.WriteLine("ESSA: " + this.methodCompiler.Method.FullName);
        }
示例#2
0
        /// <summary>
        /// Enters the SSA.
        /// </summary>
        /// <param name="headBlock">The head block.</param>
        private void EnterSSA(BasicBlock headBlock)
        {
            dominanceCalculation = methodCompiler.Pipeline.FindFirst<DominanceCalculationStage>().GetDominanceProvider(headBlock);
            variables = new Dictionary<Operand, Stack<int>>();
            counts = new Dictionary<Operand, int>();

            foreach (var op in phiPlacementStage.Assignments.Keys)
            {
                AddToAssignments(op);
            }

            foreach (var op in methodCompiler.Parameters)
            {
                AddToAssignments(op);
            }

            if (methodCompiler.LocalVariables != null)
            {
                foreach (var op in methodCompiler.LocalVariables)
                {
                    if (op.Uses.Count != 0)
                    {
                        AddToAssignments(op);
                    }
                }
            }

            if (headBlock.NextBlocks.Count > 0)
            {
                RenameVariables(headBlock.NextBlocks[0]);
            }

            // Clean up
            dominanceCalculation = null;
            variables = null;
            counts = null;
        }
示例#3
0
        /// <summary>
        /// Renames the variables.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <param name="dominanceCalculation">The dominance calculation.</param>
        /// <param name="variables">The variables.</param>
        private void RenameVariables(BasicBlock block, IDominanceProvider dominanceCalculation, Dictionary<Operand, Stack<int>> variables)
        {
            for (var context = new Context(instructionSet, block); !context.EndOfInstruction; context.GotoNext())
            {
                if (!(context.Instruction is Phi))
                {
                    for (var i = 0; i < context.OperandCount; ++i)
                    {
                        var op = context.GetOperand(i);

                        if (!(op is StackOperand))
                            continue;

                        if (!variables.ContainsKey(op))
                            throw new Exception(op.ToString() + " is not in dictionary [block = " + block + "]");

                        var index = variables[op].Peek();
                        context.SetOperand(i, CreateSsaOperand(context.GetOperand(i), index));
                    }
                }

                if (PhiPlacementStage.IsAssignmentToStackVariable(context))
                {
                    var op = context.Result;
                    var index = variables[op].Count;
                    context.SetResult(CreateSsaOperand(op, index));
                    variables[op].Push(index);
                }
            }

            foreach (var s in block.NextBlocks)
            {
                var j = WhichPredecessor(s, block);

                for (var context = new Context(instructionSet, s); !context.EndOfInstruction; context.GotoNext())
                {
                    if (!(context.Instruction is Phi))
                        continue;

                    var op = context.GetOperand(j);

                    if (variables[op].Count > 0)
                    {
                        var index = variables[op].Peek();
                        context.SetOperand(j, CreateSsaOperand(context.GetOperand(j), index));
                    }
                }
            }

            foreach (var s in dominanceCalculation.GetChildren(block))
            {
                RenameVariables(s, dominanceCalculation, variables);
            }
        }
        internal static void Dump(BasicBlocks basicBlocks, IDominanceProvider provider)
        {
            foreach (var b in basicBlocks)
            {
                Console.WriteLine(b.ToString() + " -> " + provider.GetImmediateDominator(b));
            }

            Console.WriteLine();

            foreach (var b in basicBlocks)
            {
                Console.Write(b.ToString() + " -> ");

                foreach (var d in provider.GetDominators(b))
                    Console.Write(d.ToString() + " ");

                Console.WriteLine();
            }

            return;
        }
示例#5
0
文件: EnterSSA.cs 项目: djlw78/Mosa
        /// <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));
                    }
                }
            }
        }