/// <summary> /// Builds a strongly connected component corresponding to: /// a1 = 0 /// a2 = phi(a1, a3) /// while (a2 != 10) /// { /// a3 = a2 + 4 /// } /// </summary> private List<SsaIdentifier> BuildScc() { var m = new ProcedureBuilder("test"); Identifier a = new Identifier("a", PrimitiveType.Word32, null); m.Label("b1"); m.Assign(a, Constant.Word32(0)); m.Label("b2"); m.Assign(a, m.IAdd(a, 4)); m.BranchIf(m.Ne(a, 10), "b2"); m.Label("b3"); m.Return(); this.dom = m.Procedure.CreateBlockDominatorGraph(); var ssa = new SsaTransform( new ProgramDataFlow(), m.Procedure, null, dom, new HashSet<RegisterStorage>()); /* proc = new Procedure("test", new Frame(PrimitiveType.Word32)); Block b1 = proc.AddBlock("b1"); Block b2 = proc.AddBlock("b2"); Identifier a2 = new Identifier("a2", PrimitiveType.Word32, null); Identifier a3 = new Identifier("a3", PrimitiveType.Word32, null); PhiFunction phi = new PhiFunction(a1.DataType, new Expression [] { a1, a3 }); Statement stm_a1 = new Statement(0, new Assignment(a1, Constant.Word32(0)), null); Statement stm_a2 = new Statement(0, new PhiAssignment(a2, new PhiFunction(a1.DataType, a1, a3 )), null); Statement stm_ex = new Statement(0, new Branch(new BinaryExpression(Operator.Ne, PrimitiveType.Bool, a2, Constant.Word32(10)), b2), null); Statement stm_a3 = new Statement(0, new Assignment(a3, new BinaryExpression(Operator.IAdd, a3.DataType, a2, Constant.Word32(4))), null); b1.Statements.Add(stm_a1); b2.Statements.Add(stm_a2); b2.Statements.Add(stm_a3); SsaIdentifier sid_a1 = new SsaIdentifier(a1, a1, stm_a1, ((Assignment)stm_a1.Instruction).Src, false); SsaIdentifier sid_a2 = new SsaIdentifier(a2, a2, stm_a2, ((PhiAssignment) stm_a2.Instruction).Src, false); SsaIdentifier sid_a3 = new SsaIdentifier(a3, a3, stm_a3, ((Assignment) stm_a3.Instruction).Src, false); sid_a1.Uses.Add(stm_a2); ssaIds = new SsaIdentifierCollection(); ssaIds.Add(a1, sid_a1); ssaIds.Add(a2, sid_a2); ssaIds.Add(a3, sid_a3); */ ssaIds = ssa.SsaState.Identifiers; List<SsaIdentifier> list = new List<SsaIdentifier> { ssaIds.Where(i => i.Identifier.Name == "a_0").Single(), ssaIds.Where(i => i.Identifier.Name == "a_1").Single(), ssaIds.Where(i => i.Identifier.Name == "a_2").Single(), }; return list; }
public void Pdg_PostDominateIfElse() { ProcedureBuilder m = new ProcedureBuilder(); m.BranchIf(m.Local32("a"), "then"); m.Assign(m.Local32("b"), m.Int32(0)); m.Jump("join"); m.Label("then"); m.Assign(m.Local32("c"), m.Int32(0)); m.Label("join"); m.Return(); FindPostDominators(m); }
private Procedure BuildSimpleLoop() { ProcedureBuilder m = new ProcedureBuilder(); Identifier p = m.Local32("p"); m.Assign(p, 0); m.Label("loop"); m.BranchIf(m.Eq(p, 0x4000), "done"); m.Store(m.IAdd(p, 0x3000), m.Int32(0)); m.Assign(p, m.IAdd(p, 4)); m.Goto("loop"); m.Label("done"); m.Return(); return m.Procedure; }
public void WriteProcedure_Max() { var m = new ProcedureBuilder("proc"); var r1 = m.Register("r1"); var r2 = m.Register("r2"); var r3 = m.Register("r3"); m.BranchIf(m.Gt(r1, r2), "greaterthan"); m.Assign(r3,r2); m.Assign(r2, r1); m.Assign(r1, r3); m.Label("greaterthan"); m.Return(r1); hcf.Write(m.Procedure); var sExp = @"void proc()<br /> {<br /> proc_entry:<br /> <span class=""kw"">goto</span> l1<br /> greaterthan:<br /> <span class=""kw"">return</span> r1<br /> l1:<br /> <span class=""kw"">branch</span> r1 > r2 greaterthan<br /> l2:<br /> r3 = r2<br /> r2 = r1<br /> r1 = r3<br /> <span class=""kw"">goto</span> greaterthan<br /> proc_exit:<br /> }<br /> "; Debug.Write(sb.ToString()); Assert.AreEqual(sExp, sb.ToString()); }
/// <summary> /// Mutually recursive functions that jump into each other's bodies. /// </summary> /// <returns></returns> public static Program BuildProgram() { var prog = new ProgramBuilder(); var m = new ProcedureBuilder("even"); var r1 = m.Register(1); m.BranchIf(m.Eq0(r1), "done"); m.Assign(r1, m.ISub(r1, 1)); m.Call("odd", 4); m.Assign(r1, m.Not(r1)); m.Return(); m.Label("done"); m.Assign(r1, true); m.Return(); prog.Add(m); m = new ProcedureBuilder("odd"); r1 = m.Register(1); m.BranchIf(m.Eq(r1, 1), "done"); m.Assign(r1, m.ISub(r1, 1)); m.Call("event", 4); m.Assign(r1, m.Not(r1)); m.Return(); m.Label("done"); m.Assign(r1, true); m.Return(); prog.Add(m); return prog.BuildProgram(); }
public void OutpReplaceSimple() { var m = new ProcedureBuilder(); m.Label("block"); var foo = new Identifier("foo", PrimitiveType.Word32, null); var pfoo = new Identifier("pfoo", PrimitiveType.Pointer32, null); m.Assign(foo, 3); var sid = new SsaIdentifier(foo, foo, m.Block.Statements.Last, null, false); var ssaIds = new SsaIdentifierCollection { { foo, sid } }; var opt = new OutParameterTransformer(null, ssaIds); opt.ReplaceDefinitionsWithOutParameter(foo, pfoo); Assert.AreEqual("*pfoo = 0x00000003", m.Block.Statements[0].ToString()); }
public void OutpReplaceManyUses() { ProcedureBuilder m = new ProcedureBuilder(); Identifier foo = new Identifier("foo", PrimitiveType.Word32, null); Identifier bar = new Identifier("bar", PrimitiveType.Word32, null); Identifier pfoo = new Identifier("pfoo", PrimitiveType.Pointer32, null); Block block = m.Label("block"); m.Assign(foo, 1); Statement stmFoo = m.Block.Statements.Last; m.Assign(bar, foo); Statement stmBar = m.Block.Statements.Last; SsaIdentifier ssaFoo = new SsaIdentifier(foo, foo, stmFoo, ((Assignment) stmFoo.Instruction).Src, false); ssaFoo.Uses.Add(stmBar); SsaIdentifier ssaBar = new SsaIdentifier(bar, bar, stmBar, ((Assignment) stmBar.Instruction).Src, false); SsaIdentifierCollection ssaIds = new SsaIdentifierCollection(); ssaIds.Add(foo, ssaFoo); ssaIds.Add(bar, ssaBar); OutParameterTransformer opt = new OutParameterTransformer(m.Procedure, ssaIds); opt.ReplaceDefinitionsWithOutParameter(foo, pfoo); Assert.AreEqual(3, block.Statements.Count); Assert.AreEqual("foo = 0x00000001", block.Statements[0].Instruction.ToString()); Assert.AreEqual("*pfoo = foo", block.Statements[1].Instruction.ToString()); Assert.AreEqual("bar = foo", block.Statements[2].Instruction.ToString()); }
public void OutpReplacePhi() { var m = new ProcedureBuilder(); var foo = new Identifier("foo", PrimitiveType.Word32, null); var foo1 = new Identifier("foo1", PrimitiveType.Word32, null); var foo2 = new Identifier("foo2", PrimitiveType.Word32, null); var foo3 = new Identifier("foo3", PrimitiveType.Word32, null); var pfoo = new Identifier("pfoo", PrimitiveType.Pointer32, null); Block block1 = m.Label("block1"); m.Assign(foo1, Constant.Word32(1)); Statement stmFoo1 = m.Block.Statements.Last; Block block2 = m.Label("block2"); m.Assign(foo2, Constant.Word32(2)); Statement stmFoo2 = m.Block.Statements.Last; Block block3 = m.Label("block3"); Statement stmFoo3 = m.Phi(foo3, foo1, foo2); SsaIdentifierCollection ssaIds = new SsaIdentifierCollection(); ssaIds.Add(foo1, new SsaIdentifier(foo1, foo, stmFoo1, null, false)); ssaIds.Add(foo2, new SsaIdentifier(foo2, foo, stmFoo2, null, false)); ssaIds.Add(foo3, new SsaIdentifier(foo3, foo, stmFoo3, null, false)); OutParameterTransformer opt = new OutParameterTransformer(null, ssaIds); opt.ReplaceDefinitionsWithOutParameter(foo3, pfoo); Assert.AreEqual("*pfoo = 0x00000001", stmFoo1.Instruction.ToString()); Assert.AreEqual("*pfoo = 0x00000002", stmFoo2.Instruction.ToString()); Assert.AreEqual("foo3 = PHI(foo1, foo2)", stmFoo3.Instruction.ToString()); }
public void Pdg_PostdominateLoop() { ProcedureBuilder m = new ProcedureBuilder(); m.Jump("test"); m.Label("test"); m.BranchIf(m.LocalBool("f"), "done"); m.Label("body"); m.Store(m.Int32(30), m.Int32(0)); m.Jump("test"); m.Label("done"); m.Return(); FindPostDominators(m); string sExp = "body (4): idom test (3)" + nl + "done (5): idom ProcedureBuilder_exit (6)" + nl + "l1 (2): idom test (3)" + nl + "ProcedureBuilder_entry (1): idom l1 (2)" + nl + "ProcedureBuilder_exit (6): idom " + nl + "test (3): idom done (5)" + nl; Console.WriteLine(sw.ToString()); Assert.AreEqual(sExp, sw.ToString()); }
public void Pdg_InfiniteLoop() { ProcedureBuilder m = new ProcedureBuilder(); m.Label("Infinity"); m.BranchIf(m.Eq(m.LoadW(m.Word16(0x1234)), 0), "hop"); m.SideEffect(m.Fn("foo")); m.Label("hop"); m.BranchIf(m.Eq(m.LoadW(m.Word16(0x5123)), 1), "Infinity"); m.SideEffect(m.Fn("bar")); m.Jump("Infinity"); m.Return(); FindPostDominators(m); string sExp = "hop (4): idom ProcedureBuilder_exit (6)" + nl + "Infinity (2): idom hop (4)" + nl + "l1 (3): idom hop (4)" + nl + "l2 (5): idom ProcedureBuilder_exit (6)" + nl + "ProcedureBuilder_entry (1): idom Infinity (2)" + nl + "ProcedureBuilder_exit (6): idom " + nl; Assert.AreEqual(sExp, sw.ToString()); }
public void Pdg_LoopWithIfElse() { var m = new ProcedureBuilder(); var c = m.Declare(PrimitiveType.Word32, "c"); var f = m.Declare(PrimitiveType.Bool, "f"); m.Label("loopHead"); m.BranchIf(m.Eq(c, 0), "done"); m.BranchIf(f, "then"); m.Label("else"); m.SideEffect(m.Fn("CallElse")); m.Jump("loopHead"); m.Label("then"); m.SideEffect(m.Fn("CallThen")); m.Jump("loopHead"); m.Label("done"); m.Return(); FindPostDominators(m); string sExp = "done (6): idom ProcedureBuilder_exit (7)" + nl + "else (4): idom loopHead (2)" + nl + "l1 (3): idom loopHead (2)" + nl + "loopHead (2): idom done (6)" + nl + "ProcedureBuilder_entry (1): idom loopHead (2)" + nl + "ProcedureBuilder_exit (7): idom " + nl + "then (5): idom loopHead (2)" + nl; Assert.AreEqual(sExp, sw.ToString()); }