Пример #1
0
        /// <summary>
        /// Performs stage specific processing on the compiler context.
        /// </summary>
        public void Run()
        {
            bool remove = false;

            foreach (BasicBlock block in BasicBlocks)
            {
                for (Context ctx = new Context(InstructionSet, block); !ctx.EndOfInstruction; ctx.GotoNext())
                {
                    if (ctx.Instruction is IR.MoveInstruction || ctx.Instruction is CIL.StlocInstruction)
                    {
                        if (ctx.Operand1 is ConstantOperand)
                        {
                            // HACK: We can't track a constant through a register, so we keep those moves
                            if (ctx.Result is StackOperand)
                            {
                                Debug.Assert(ctx.Result.Definitions.Count == 1, @"Operand defined multiple times. Instruction stream not in SSA form!");
                                ctx.Result.Replace(ctx.Operand1, InstructionSet);
                                remove = true;
                            }
                        }
                    }
                    else if (ctx.Instruction is IR.PhiInstruction)
                    {
                        IR.PhiInstruction phi    = (IR.PhiInstruction)ctx.Instruction;
                        ConstantOperand   co     = ctx.Operand2 as ConstantOperand;
                        List <BasicBlock> blocks = ctx.Other as List <BasicBlock>;                              // FIXME PG / ctx has moved
                        if (co != null && blocks.Count == 1)
                        {
                            // We can remove the phi, as it is only defined once
                            // HACK: We can't track a constant through a register, so we keep those moves
                            if (!ctx.Result.IsRegister)
                            {
                                Debug.Assert(ctx.Result.Definitions.Count == 1, @"Operand defined multiple times. Instruction stream not in SSA form!");
                                ctx.Result.Replace(co, InstructionSet);
                                remove = true;
                            }
                        }
                    }

                    // Shall we remove this instruction?
                    if (remove)
                    {
                        ctx.Remove();
                        remove = false;
                    }
                }
            }
        }
Пример #2
0
        private void MergePhiInstructions(BasicBlock block, BasicBlock caller, IDictionary <StackOperand, StackOperand> liveIn)
        {
            for (Context ctx = new Context(InstructionSet, block); !ctx.EndOfInstruction; ctx.GotoNext())
            {
                IR.PhiInstruction phi = ctx.Instruction as IR.PhiInstruction;

                if (phi != null && liveIn.ContainsKey(ctx.Result as StackOperand))
                {
                    StackOperand value = liveIn[ctx.Result as StackOperand];

                    if (!IR.PhiInstruction.Contains(ctx, value) && (ctx.Result as StackOperand).Version != value.Version)
                    {
                        IR.PhiInstruction.AddValue(ctx, caller, value);
                    }
                }
            }
        }