示例#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;
                    }
                }
            }
        }
        /// <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;
                    }

                }
            }
        }
 /// <summary>
 /// Visitation function for <see cref="ICILVisitor.Dup"/>.
 /// </summary>
 /// <param name="ctx">The context.</param>
 void ICILVisitor.Dup(Context ctx)
 {
     // We don't need the dup anymore.
     //Remove(ctx);
     ctx.Remove ();
 }
 /// <summary>
 /// Replaces the IL load instruction by an appropriate IR move instruction or removes it entirely, if
 /// it is a native size.
 /// </summary>
 /// <param name="ctx">Provides the transformation context.</param>
 private void ProcessLoadInstruction(Context ctx)
 {
     // We don't need to rewire the source/destination yet, its already there. :(
     //Remove(ctx);
     ctx.Remove ();
 }
        /// <summary>
        /// Visitation function for <see cref="CIL.ICILVisitor.Switch"/>.
        /// </summary>
        /// <param name="ctx">The context.</param>
        void CIL.ICILVisitor.Switch(Context ctx)
        {
            IBranch branch = ctx.Branch;
            Operand operand = ctx.Operand1;

            ctx.Remove();

            for (int i = 0; i < branch.Targets.Length - 1; ++i) {
                ctx.AppendInstruction(CPUx86.Instruction.CmpInstruction, operand, new ConstantOperand(new SigType(CilElementType.I), i));
                ctx.AppendInstruction(CPUx86.Instruction.BranchInstruction, IR.ConditionCode.Equal);
                ctx.SetBranch(branch.Targets[i]);
            }
        }
        /// <summary>
        /// Replaces the IL load instruction by an appropriate IR move instruction or removes it entirely, if
        /// it is a native size.
        /// </summary>
        /// <param name="ctx">Provides the transformation context.</param>
        private void ProcessLoadInstruction(Context ctx)
        {
            // We don't need to rewire the source/destination yet, its already there. :(
            //Remove(ctx);
            ctx.Remove();

            /* FIXME: This is only valid with reg alloc!
            Type type = null;

            load = load as LoadInstruction;

            // Is this a sign or zero-extending move?
            if (IsSignExtending(load.Source))
            {
                type = typeof(IR.SignExtendedMoveInstruction);
            }
            else if (IsZeroExtending(load.Source))
            {
                type = typeof(IR.ZeroExtendedMoveInstruction);
            }

            // Do we have a move replacement?
            if (null == type)
            {
                // No, we can safely drop the load instruction and can rewire the operands.
                /*if (1 == load.Destination.Definitions.Count && 1 == load.Destination.Uses.Count)
                {
                    load.Destination.Replace(load.Source);
                    Remove(ctx);
                }
                return;
            }
            else
            {
                Replace(ctx, Architecture.CreateInstruction(type, load.Destination, load.Source));
            }*/
        }
        /// <summary>
        /// Visitation function for <see cref="ICILVisitor.Call"/>.
        /// </summary>
        /// <param name="ctx">The context.</param>
        void ICILVisitor.Call(Context ctx)
        {
            if (this.CanSkipDueToRecursiveSystemObjectCtorCall(ctx) == true)
            {
                ctx.Remove();
                return;
            }

            if (this.ProcessIntrinsicCall(ctx) == false)
            {
                // Create a symbol operand for the invocation target
                RuntimeMethod invokeTarget = ctx.InvokeTarget;
                SymbolOperand symbolOperand = SymbolOperand.FromMethod(invokeTarget);

                this.ProcessInvokeInstruction(ctx, symbolOperand, ctx.Result, new List<Operand>(ctx.Operands));
            }
        }
        /// <summary>
        /// Visitation function for Call instruction.
        /// </summary>
        /// <param name="context">The context.</param>
        void CIL.ICILVisitor.Call(Context context)
        {
            if (this.CanSkipDueToRecursiveSystemObjectCtorCall(context))
            {
                context.Remove();
                return;
            }

            //if (ProcessVmCall(context))
            //    return;

            if (ProcessExternalCall(context))
                return;

            // Create a symbol operand for the invocation target
            RuntimeMethod invokeTarget = context.InvokeTarget;
            SymbolOperand symbolOperand = SymbolOperand.FromMethod(invokeTarget);

            ProcessInvokeInstruction(context, symbolOperand, context.Result, new List<Operand>(context.Operands));
        }
 /// <summary>
 /// Replaces the instrinsic call site
 /// </summary>
 /// <param name="context">The context.</param>
 public void ReplaceIntrinsicCall(Context context)
 {
     //			context.SetInstruction(IR.Instruction.JmpInstruction, );
     context.Remove();
 }
示例#10
0
 /// <summary>
 /// Replaces the instrinsic call site
 /// </summary>
 /// <param name="context">The context.</param>
 public void ReplaceIntrinsicCall(Context context)
 {
     // TODO
     context.Remove();
 }
 /// <summary>
 /// Visitation function for Ldloc instruction.
 /// </summary>
 /// <param name="context">The context.</param>
 public void Ldloc(Context context)
 {
     if (context.Ignore)
     {
         context.Remove();
     }
     else
     {
         this.ProcessLoadInstruction(context);
     }
 }
 /// <summary>
 /// Visitation function for Pop instruction.
 /// </summary>
 /// <param name="context">The context.</param>
 void CIL.ICILVisitor.Pop(Context context)
 {
     context.Remove();
 }
 /// <summary>
 /// Visitation function for Dup instruction.
 /// </summary>
 /// <param name="context">The context.</param>
 void CIL.ICILVisitor.Dup(Context context)
 {
     // We don't need the dup anymore.
     //Remove(context);
     context.Remove();
 }
示例#14
0
 /// <summary>
 /// Visitation function for <see cref="ICILVisitor.Pop"/>.
 /// </summary>
 /// <param name="ctx">The context.</param>
 void ICILVisitor.Pop(Context ctx)
 {
     ctx.Remove ();
 }
 /// <summary>
 /// Visitation function for <see cref="ICILVisitor.Ldloc"/>.
 /// </summary>
 /// <param name="ctx">The context.</param>
 public void Ldloc(Context ctx)
 {
     if (ctx.Ignore == true)
     {
         ctx.Remove();
     }
     else
     {
         this.ProcessLoadInstruction(ctx);
     }
 }
示例#16
0
 /// <summary>
 /// Replaces the instrinsic call site
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="typeSystem">The type system.</param>
 public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem)
 {
     // TODO
     context.Remove();
 }
        public void SwitchInstruction(Context context)
        {
            IBranch branch = context.Branch;
            Operand operand = context.Operand1;

            context.Remove();

            for (int i = 0; i < branch.Targets.Length - 1; ++i)
            {
                context.AppendInstruction(CPUx86.Instruction.CmpInstruction, operand, new ConstantOperand(new SigType(CilElementType.I), i));
                context.AppendInstruction(CPUx86.Instruction.BranchInstruction, IR.ConditionCode.Equal);
                context.SetBranch(branch.Targets[i]);
            }
        }