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(); }
public void Spbp_LinearProcedure() { var m = new SsaProcedureBuilder(nameof(Spbp_LinearProcedure)); var fp = m.Ssa.Identifiers.Add(m.Frame.FramePointer, null, null, false).Identifier; Given_StackPointer(m); var sp_1 = m.Reg("sp_1", m.Architecture.StackRegister); var sp_2 = m.Reg("sp_2", m.Architecture.StackRegister); var sp_3 = m.Reg("sp_3", m.Architecture.StackRegister); m.AddDefToEntryBlock(fp); m.Assign(sp_1, m.ISub(fp, m.Int32(4))); // Indirect call = hell node var ci = m.Call(m.Mem32(m.Word32(0x2)), 4, new[] { sp_1 }, new[] { sp_2 }); m.Assign(sp_3, m.IAdd(sp_2, m.Int32(4))); m.Return(); m.AddUseToExitBlock(sp_3); RunTest(m.Ssa); var sExp = #region Expected @"Spbp_LinearProcedure_entry: def fp l1: sp_1 = fp - 4 call Mem4[0x00000002:word32] (retsize: 4;) uses: sp:sp_1 sp_2 = fp - 4 sp_3 = fp return Spbp_LinearProcedure_exit: use sp_3 "; #endregion AssertStringsEqual(sExp, m.Ssa); }
public void Spbp_TwoExits() { var m = new SsaProcedureBuilder(nameof(Spbp_TwoExits)); Given_FramePointer(m); Given_StackPointer(m); var sp_1 = m.Reg("sp_1", m.Architecture.StackRegister); var sp_2 = m.Reg("sp_2", m.Architecture.StackRegister); var sp_3 = m.Reg("sp_3", m.Architecture.StackRegister); var sp_4 = m.Reg("sp_4", m.Architecture.StackRegister); var sp_5 = m.Reg("sp_5", m.Architecture.StackRegister); var sp_6 = m.Reg("sp_6", m.Architecture.StackRegister); m.AddDefToEntryBlock(fp); m.Assign(sp_1, m.ISub(fp, m.Int32(4))); m.BranchIf(m.Eq0(m.Mem32(m.Word32(0x1))), "m_eq0"); m.Label("m_ne0"); // Indirect call = hell node m.Call(m.Mem32(m.Word32(0x4)), 4, new[] { sp_1 }, new[] { sp_2 }); m.Assign(sp_3, m.IAdd(sp_2, m.Int32(4))); m.Return(); m.Label("m_eq0"); // Indirect call = hell node m.Call(m.Mem32(m.Word32(0x8)), 4, new[] { sp_1 }, new[] { sp_4 }); m.Assign(sp_5, m.IAdd(sp_4, m.Int32(4))); m.Return(); m.AddPhiToExitBlock(sp_6, (sp_3, "m_ne0"), (sp_5, "m_eq0")); m.AddUseToExitBlock(sp_6); RunTest(m.Ssa); var sExp = #region Expected @"Spbp_TwoExits_entry: def fp l1: sp_1 = fp - 4 branch Mem7[0x00000001:word32] == 0x00000000 m_eq0 goto m_ne0 m_eq0: call Mem9[0x00000008:word32] (retsize: 4;) uses: sp:sp_1 sp_4 = fp - 4 sp_5 = fp return m_ne0: call Mem8[0x00000004:word32] (retsize: 4;) uses: sp:sp_1 sp_2 = fp - 4 sp_3 = fp return Spbp_TwoExits_exit: sp_6 = PHI((sp_3, m_ne0), (sp_5, m_eq0)) use sp_6 "; #endregion AssertStringsEqual(sExp, m.Ssa); }