Exemple #1
0
        void VisitLogicNot(Comp inst, ILInstruction arg)
        {
            ILInstruction lhs, rhs;

            if (arg is Comp comp)
            {
                if ((comp.InputType != StackType.F && !comp.IsLifted) || comp.Kind.IsEqualityOrInequality())
                {
                    context.Step("push negation into comparison", inst);
                    comp.Kind = comp.Kind.Negate();
                    comp.AddILRange(inst.ILRange);
                    inst.ReplaceWith(comp);
                }
                comp.AcceptVisitor(this);
            }
            else if (arg.MatchLogicAnd(out lhs, out rhs))
            {
                // logic.not(if (lhs) rhs else ldc.i4 0)
                // ==> if (logic.not(lhs)) ldc.i4 1 else logic.not(rhs)
                context.Step("push negation into logic.and", inst);
                IfInstruction ifInst = (IfInstruction)arg;
                var           ldc0   = ifInst.FalseInst;
                Debug.Assert(ldc0.MatchLdcI4(0));
                ifInst.Condition = Comp.LogicNot(lhs, inst.ILRange);
                ifInst.TrueInst  = new LdcI4(1)
                {
                    ILRange = ldc0.ILRange
                };
                ifInst.FalseInst = Comp.LogicNot(rhs, inst.ILRange);
                inst.ReplaceWith(ifInst);
                ifInst.AcceptVisitor(this);
            }
            else if (arg.MatchLogicOr(out lhs, out rhs))
            {
                // logic.not(if (lhs) ldc.i4 1 else rhs)
                // ==> if (logic.not(lhs)) logic.not(rhs) else ldc.i4 0)
                context.Step("push negation into logic.or", inst);
                IfInstruction ifInst = (IfInstruction)arg;
                var           ldc1   = ifInst.TrueInst;
                Debug.Assert(ldc1.MatchLdcI4(1));
                ifInst.Condition = Comp.LogicNot(lhs, inst.ILRange);
                ifInst.TrueInst  = Comp.LogicNot(rhs, inst.ILRange);
                ifInst.FalseInst = new LdcI4(0)
                {
                    ILRange = ldc1.ILRange
                };
                inst.ReplaceWith(ifInst);
                ifInst.AcceptVisitor(this);
            }
            else
            {
                arg.AcceptVisitor(this);
            }
        }
Exemple #2
0
        protected internal override void VisitLogicNot(LogicNot inst)
        {
            ILInstruction arg, lhs, rhs;

            if (inst.Argument.MatchLogicNot(out arg))
            {
                context.Step("logic.not(logic.not(arg)) => arg", inst);
                Debug.Assert(arg.ResultType == StackType.I4);
                arg.AddILRange(inst.ILRange);
                arg.AddILRange(inst.Argument.ILRange);
                inst.ReplaceWith(arg);
                arg.AcceptVisitor(this);
            }
            else if (inst.Argument is Comp comp)
            {
                if ((comp.InputType != StackType.F && !comp.IsLifted) || comp.Kind.IsEqualityOrInequality())
                {
                    context.Step("push negation into comparison", inst);
                    comp.Kind = comp.Kind.Negate();
                    comp.AddILRange(inst.ILRange);
                    inst.ReplaceWith(comp);
                }
                comp.AcceptVisitor(this);
            }
            else if (inst.Argument.MatchLogicAnd(out lhs, out rhs))
            {
                // logic.not(if (lhs) rhs else ldc.i4 0)
                // ==> if (logic.not(lhs)) ldc.i4 1 else logic.not(rhs)
                context.Step("push negation into logic.and", inst);
                IfInstruction ifInst = (IfInstruction)inst.Argument;
                var           ldc0   = ifInst.FalseInst;
                Debug.Assert(ldc0.MatchLdcI4(0));
                ifInst.Condition = new LogicNot(lhs)
                {
                    ILRange = inst.ILRange
                };
                ifInst.TrueInst = new LdcI4(1)
                {
                    ILRange = ldc0.ILRange
                };
                ifInst.FalseInst = new LogicNot(rhs)
                {
                    ILRange = inst.ILRange
                };
                inst.ReplaceWith(ifInst);
                ifInst.AcceptVisitor(this);
            }
            else if (inst.Argument.MatchLogicOr(out lhs, out rhs))
            {
                // logic.not(if (lhs) ldc.i4 1 else rhs)
                // ==> if (logic.not(lhs)) logic.not(rhs) else ldc.i4 0)
                context.Step("push negation into logic.or", inst);
                IfInstruction ifInst = (IfInstruction)inst.Argument;
                var           ldc1   = ifInst.TrueInst;
                Debug.Assert(ldc1.MatchLdcI4(1));
                ifInst.Condition = new LogicNot(lhs)
                {
                    ILRange = inst.ILRange
                };
                ifInst.TrueInst = new LogicNot(rhs)
                {
                    ILRange = inst.ILRange
                };
                ifInst.FalseInst = new LdcI4(0)
                {
                    ILRange = ldc1.ILRange
                };
                inst.ReplaceWith(ifInst);
                ifInst.AcceptVisitor(this);
            }
            else
            {
                inst.Argument.AcceptVisitor(this);
            }
        }