/// <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, dom);

            /*
            
            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;
		}
Пример #2
0
        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&nbsp;proc()<br />
{<br />
proc_entry:<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class=""kw"">goto</span>&nbsp;l1<br />
greaterthan:<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class=""kw"">return</span>&nbsp;r1<br />
l1:<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class=""kw"">branch</span>&nbsp;r1&nbsp;&gt;&nbsp;r2&nbsp;greaterthan<br />
l2:<br />
&nbsp;&nbsp;&nbsp;&nbsp;r3&nbsp;=&nbsp;r2<br />
&nbsp;&nbsp;&nbsp;&nbsp;r2&nbsp;=&nbsp;r1<br />
&nbsp;&nbsp;&nbsp;&nbsp;r1&nbsp;=&nbsp;r3<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class=""kw"">goto</span>&nbsp;greaterthan<br />
proc_exit:<br />
}<br />
";
            Debug.Write(sb.ToString());
            Assert.AreEqual(sExp, sb.ToString());
        }
Пример #3
0
        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.Jump("loop");

            m.Label("done");
            m.Return();
            return m.Procedure;
        }
		public void OutpReplaceSimple()
		{
            var m = new ProcedureBuilder();
            var block = 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 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 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());
		}