public void SrtReg685()
        {
            var m   = new SsaProcedureBuilder(nameof(SrtReg685));
            var i_1 = m.Reg32("i_1");
            var i_2 = m.Reg32("i_2");
            var i_3 = m.Reg32("i_3");

            m.Assign(i_1, m.Int32(0));

            m.Label("m1");
            m.Phi(i_2, i_1, i_3);
            m.SideEffect(m.Fn("foo", i_2));
            m.SideEffect(m.Fn("foo", m.IAdd(i_2, 1)));
            m.Assign(i_3, m.IAdd(i_2, 2));
            m.BranchIf(m.Eq(i_3, 10), "m1");

            m.Label("m2");
            m.Return();

            var dom = m.Procedure.CreateBlockDominatorGraph();
            var lif = new LinearInductionVariableFinder(m.Procedure, m.Ssa.Identifiers, dom);

            lif.Find();
            Assert.AreEqual("(0 0x00000002 0x0000000C)", lif.InductionVariables[0].ToString());

            var ctx = lif.Contexts[lif.InductionVariables[0]];

            var str = new StrengthReduction(m.Ssa, lif.InductionVariables[0], ctx);

            str.ClassifyUses();
            Assert.AreEqual(2, str.IncrementedUses.Count);
            str.ModifyUses();
        }
Beispiel #2
0
        public void SsamCallBypass()
        {
            var sp   = m.Architecture.StackRegister;
            var sp_1 = m.Reg("sp_1", sp);
            var sp_5 = m.Reg("sp_5", sp);
            var a    = m.Reg32("a");
            var fp   = m.Reg32("fp");

            m.Assign(sp_1, fp);
            var uses    = new Identifier[] { a, sp_1 };
            var defines = new Identifier[] { sp_5 };
            var stmCall = m.Call(a, 4, uses, defines);

            RunSsaMutator(ssam =>
            {
                var call = (CallInstruction)stmCall.Instruction;
                ssam.AdjustRegisterAfterCall(stmCall, call, sp, 0);
            });

            var sExp = @"
sp_1 = fp
call a (retsize: 4;)
	uses: a,sp_1
sp_5 = sp_1
";

            AssertProcedureCode(sExp);
        }
Beispiel #3
0
        public void Urb_Remove_many_blocks()
        {
            var m = new SsaProcedureBuilder(name: nameof(Urb_Remove_many_blocks));

            var r1_1 = m.Reg32("r1_1");
            var r1_2 = m.Reg32("r1_2");
            var r1_3 = m.Reg32("r1_3");
            var r1_4 = m.Reg32("r1_4");
            var r2   = m.Reg32("r2");

            m.AddDefToEntryBlock(r2);
            m.BranchIf(Constant.False(), "m2");

            m.Label("m1");
            m.Assign(r1_1, 1);
            m.Goto("m4");

            m.Label("m2");  // dead code
            m.BranchIf(m.Eq0(r2), "m3");

            m.Label("m2a");
            m.Assign(r1_2, 2);
            m.Goto("m4");

            m.Label("m3");
            m.Assign(r1_3, 3);
            // end of dead code.

            m.Label("m4");
            m.Phi(r1_4, (r1_1, "m1"), (r1_2, "m2a"), (r1_3, "m3"));
            m.Return(r1_4);

            var sExp =
                #region
                @"// Urb_Remove_many_blocks
// Return size: 0
define Urb_Remove_many_blocks
Urb_Remove_many_blocks_entry:
	def r2
	// succ:  l1
l1:
	// succ:  m1
m1:
	r1_1 = 1<32>
	// succ:  m4
m4:
	r1_4 = r1_1
	return r1_4
	// succ:  Urb_Remove_many_blocks_exit
Urb_Remove_many_blocks_exit:
";

            #endregion

            RunTest(sExp, m);
        }
Beispiel #4
0
        public void DeadDpbApplication()
        {
            var dead = m.Reg32("dead");

            m.Assign(dead, m.Dpb(m.Word32(0), m.Fn("foo", Constant.Word32(1)), 0));

            EliminateDeadCode();

            var sExp =
                @"
foo(1<32>)
";

            AssertProcedureCode(sExp);
        }
Beispiel #5
0
        public void Icrw_TypeReferenceToFunc()
        {
            var a  = m.Reg32("a");
            var b  = m.Reg32("b");
            var fn = m.Reg32("fn");

            fn.DataType = RefFnPtr32("FnPtr", a, b);
            var uses    = new Identifier[] { b };
            var defines = new Identifier[] { a };
            var callStm = m.Call(fn, 4, uses, defines);

            RunIndirectCallRewriter();

            Assert.AreEqual("a = fn(b)", callStm.Instruction.ToString());
        }
Beispiel #6
0
        public void CoaDoNotCoalesceInvalidConstant()
        {
            var a = m.Reg32("a");
            var b = m.Reg32("b");

            m.Assign(a, Constant.Invalid);
            m.Assign(b, m.IAdd(a, 4));

            RunCoalescer();

            var expected =
                @"
a = <invalid>
b = a + 0x00000004
";

            AssertProcedureCode(expected);
        }
Beispiel #7
0
        public void Urb_Remove_false()
        {
            var m = new SsaProcedureBuilder(name: nameof(Urb_Remove_false));

            var r1_1 = m.Reg32("r1_1");
            var r1_2 = m.Reg32("r1_2");
            var r1_3 = m.Reg32("r1_3");

            m.BranchIf(Constant.False(), "m2");

            m.Label("m1");
            m.Assign(r1_1, 1);
            m.Goto("m3");

            m.Label("m2");  // dead code
            m.Assign(r1_2, 2);

            m.Label("m3");
            m.Phi(r1_3, (r1_1, "m1"), (r1_2, "m2"));
            m.Return(r1_3);

            var sExp =
                #region
                @"// Urb_Remove_false
// Return size: 0
define Urb_Remove_false
Urb_Remove_false_entry:
	// succ:  l1
l1:
	// succ:  m1
m1:
	r1_1 = 1<32>
	// succ:  m3
m3:
	r1_3 = r1_1
	return r1_3
	// succ:  Urb_Remove_false_exit
Urb_Remove_false_exit:
";

            #endregion

            RunTest(sExp, m);
        }
        public void FPUG_NoFpuUses()
        {
            var top_1   = m.Reg("FakeTop_1", Top);
            var top_2   = m.Reg("FakeTop_2", Top);
            var f       = m.Reg32("f");
            var uses    = new Identifier[] { top_1 };
            var defines = new Identifier[] { top_2 };

            m.Call(f, 4, uses, defines);

            RunFpuStackReturnGuesser();

            var expected =
                @"
call f (retsize: 4;)
	uses: Top:FakeTop_1
FakeTop_2 = FakeTop_1
";

            AssertProcedureCode(expected);
        }
Beispiel #9
0
        public void CoaCallUses()
        {
            var r2 = m.Reg32("r2");
            var r3 = m.Reg32("r3");
            var r4 = m.Reg32("r4");

            m.Assign(r4, m.Fn(r2));
            var uses    = new Identifier[] { r2, r3, r4 };
            var defines = new Identifier[] { };

            m.Call(r3, 4, uses, defines);

            RunCoalescer();

            var expected =
                @"
r4 = r2()
call r3 (retsize: 4;)
	uses: r2,r3,r4
";

            AssertProcedureCode(expected);
        }
Beispiel #10
0
        public void Icrw_TrashedIdentifier()
        {
            var fn    = m.Reg32("fn");
            var ret   = m.Reg32("ret");
            var trash = m.Reg32("trash");

            fn.DataType = FnPtr32(ret);
            var uses    = new Identifier[] { };
            var defines = new Identifier[] { ret, trash };

            m.Call(fn, 4, uses, defines);

            RunIndirectCallRewriter();

            var expected =
                @"
ret = fn()
trash = <invalid>
";

            AssertProcedureCode(expected);
        }
Beispiel #11
0
        public void VpLoop()
        {
            var b = new ProgramBuilder();

            b.Add("main", m =>
            {
                var r  = m.Reg32("r0", 0);
                var zf = m.Flags("Z");
                m.Label("l0000");
                m.MStore(r, m.Word32(0));
                m.Assign(r, m.ISub(r, 4));
                m.Assign(zf, m.Cond(r));
                m.BranchIf(m.Test(ConditionCode.NE, zf), "l0000");

                m.Label("l0001");
                m.Assign(r, 42);

                m.Label("l0002");
                m.MStore(r, m.Word32(12));
                m.Assign(r, m.ISub(r, 4));
                m.BranchIf(m.Eq0(r), "l0002");

                m.Return();
            });
            RunFileTest(b.BuildProgram(), "Analysis/VpLoop.txt");
        }
        public void UfuserMipsLittleEndianUnalignedWordLoad()
        {
            var r4 = m.Reg32("r4");
            var r8 = m.Reg32("r8");

            __lwl(r8, m.Mem32(m.IAdd(r4, 0x2B)));
            __lwr(r8, m.Mem32(m.IAdd(r4, 0x28)));
            var ssa  = RunTest(m);
            var sExp =
                #region Expected
                @"r8:r8
    def:  def r8
    uses: r8_3 = r8
r4:r4
    def:  def r4
    uses: r8_5 = Mem3[r4 + 0x00000028:word32]
Mem2:Global memory
    def:  def Mem2
r8_3: orig: r8
    def:  r8_3 = r8
Mem3:Global memory
    def:  def Mem3
    uses: r8_5 = Mem3[r4 + 0x00000028:word32]
r8_5: orig: r8
    def:  r8_5 = Mem3[r4 + 0x00000028:word32]
// SsaProcedureBuilder
// Return size: 0
void SsaProcedureBuilder()
SsaProcedureBuilder_entry:
	def r8
	def r4
	def Mem2
	def Mem3
	// succ:  l1
l1:
	r8_5 = Mem3[r4 + 0x00000028:word32]
SsaProcedureBuilder_exit:
";

            #endregion
            AssertStringsEqual(sExp, ssa);
        }