Ejemplo n.º 1
0
		public Identifier InsertAssignmentNewId(Identifier idOld, Block b, int i)
		{
			Statement stm = new Statement(0, null, b);
            SsaIdentifier sidNew = ssaIds.Add((Identifier)ssaIds[idOld].OriginalIdentifier, stm, idOld, false);
			stm.Instruction = new Assignment(sidNew.Identifier, idOld);
			b.Statements.Insert(i, stm);
			return sidNew.Identifier;
		}
Ejemplo n.º 2
0
		/// <summary>
		/// Creates a phi statement with slots for each predecessor block, then
		/// inserts the phi statement as the first statement of the block.
		/// </summary>
		/// <param name="b">Block into which the phi statement is inserted</param>
		/// <param name="v">Destination variable for the phi assignment</param>
		/// <returns>The inserted phi Assignment</returns>
		private Instruction InsertPhiStatement(Block b, Identifier v)
		{
			var stm = new Statement(
                0,
				new PhiAssignment(v, b.Pred.Count),
				b);
			b.Statements.Insert(0, stm);
			return stm.Instruction;
		}
Ejemplo n.º 3
0
 public void Test2()
 {
     BinaryExpression b = m.IAdd(id, m.UMul(id, 5));
     Assignment ass = new Assignment(x, b);
     Statement stm = new Statement(0, ass, null);
     Add_mul_id_c_id_Rule rule = new Add_mul_id_c_id_Rule(new SsaEvaluationContext(ssaIds));
     Assert.IsTrue(rule.Match(b));
     ass.Src = rule.Transform();
     Assert.AreEqual("x = id *u 0x00000006", ass.ToString());
 }
Ejemplo n.º 4
0
		public void Test1()
		{
			BinaryExpression b = m.Shl(m.SMul(id, 3), 2);
			Assignment ass = new Assignment(x, b);
			Statement stm = new Statement(0, ass, null);
			ssaIds[id].Uses.Add(stm);
			ssaIds[id].Uses.Add(stm);

			var rule = new Shl_mul_e_Rule(null);
			Assert.IsTrue(rule.Match(b));
			ass.Src = rule.Transform();
			Assert.AreEqual("x = id *s 12", ass.ToString());
		}
Ejemplo n.º 5
0
		public SsaIdentifier(Identifier id, Identifier eOrig, Statement stmDef, Expression exprDef, bool isSideEffect)
		{
			if (id == null)
				throw new ArgumentNullException("id");
			if (eOrig == null)
				throw new ArgumentNullException("eOrig");
			this.Identifier = id;
			this.OriginalIdentifier = eOrig;
			this.DefStatement = stmDef;
            this.DefExpression = exprDef;
            this.IsSideEffect = isSideEffect;
			this.Uses = new List<Statement>();
		}
Ejemplo n.º 6
0
		public bool AreConstrained(Statement def, Statement use)
		{
			SideEffectFlags defFlags = FindSideEffect(def.Instruction);
			int iUse = use.Block.Statements.IndexOf(use);
			for (int i = def.Block.Statements.IndexOf(def) + 1; i < def.Block.Statements.Count; ++i)
			{
				if (i == iUse)
					return false;

				if (Conflict(defFlags, FindSideEffect(def.Block.Statements[i].Instruction)))
					return true;
			}
			return true;
		}
Ejemplo n.º 7
0
 private void SetDefStatement(Statement stm, SsaIdentifier sid)
 {
     List<SsaIdentifier> sids;
     if (defsByStatement.TryGetValue(sid.DefStatement, out sids))
     {
         sids.Remove(sid);
     }
     if (!defsByStatement.TryGetValue(stm, out sids))
     {
         sids = new List<SsaIdentifier>();
         defsByStatement.Add(stm, sids);
     }
     sids.Add(sid);
 }
Ejemplo n.º 8
0
		/// <summary>
		/// Rewrites CALL instructions to function applications.
		/// </summary>
		/// <remarks>
		/// Converts an opcode:
		/// <code>
		///   call procExpr 
		/// </code>
		/// to one of:
		/// <code>
		///	 ax = procExpr(bindings);
		///  procEexpr(bindings);
		/// </code>
		/// </remarks>
		/// <param name="proc">Procedure in which the CALL instruction exists</param>
		/// <param name="stm">The particular statement of the call instruction</param>
		/// <param name="call">The actuall CALL instruction.</param>
		/// <returns>True if the conversion was possible, false if the procedure didn't have
		/// a signature yet.</returns>
		public bool RewriteCall(Procedure proc, Statement stm, CallInstruction call)
		{
            var callee = call.Callee as ProcedureConstant;
            if (callee == null)
                return false;          //$REVIEW: what happens with indirect calls?
			var procCallee = callee.Procedure;
			var sigCallee = GetProcedureSignature(procCallee);
			var fn = new ProcedureConstant(Program.Platform.PointerType, procCallee);
            if (sigCallee == null || !sigCallee.ParametersValid)
                return false;

            var ab = new ApplicationBuilder(Program.Architecture, proc.Frame, call.CallSite, fn, sigCallee, true);
			stm.Instruction = ab.CreateInstruction();
            return true;
		}
Ejemplo n.º 9
0
        public void Test1()
        {
            BinaryExpression b = m.IAdd(m.SMul(id, 4), id);
            Assignment ass = new Assignment(x, b);
            Statement stm = new Statement(0, ass, null);
            ssaIds[id].Uses.Add(stm);
            ssaIds[id].Uses.Add(stm);

            ctx.Statement = stm;
            Add_mul_id_c_id_Rule rule = new Add_mul_id_c_id_Rule(ctx);
            Assert.IsTrue(rule.Match(b));
            Assert.AreEqual(2, ssaIds[id].Uses.Count);
            ass.Src = rule.Transform();
            Assert.AreEqual("x = id *s 0x00000005", ass.ToString());
            Assert.AreEqual(1, ssaIds[id].Uses.Count);
        }
Ejemplo n.º 10
0
		public void Creation()
		{
			CallGraph g = new CallGraph();
			Procedure p1 = new Procedure("p1000", null);
			Procedure p2 = new Procedure("p2000", null);
			Procedure p3 = new Procedure("p3000", null);
			Procedure p4 = new Procedure("p4000", null);

            var pc1 = new ProcedureConstant(PrimitiveType.Pointer32, p1);
            var pc2 = new ProcedureConstant(PrimitiveType.Pointer32, p2);
            var pc3 = new ProcedureConstant(PrimitiveType.Pointer32, p3);
            var pc4 = new ProcedureConstant(PrimitiveType.Pointer32, p4);

            Statement s11 = new Statement(0, CreateCall(pc2), p1.EntryBlock);
            Statement s12 = new Statement(0, CreateCall(pc2), p1.EntryBlock);
            Statement s13 = new Statement(0, CreateCall(pc3), p1.EntryBlock);
			p1.EntryBlock.Statements.Add(s11);
			p1.EntryBlock.Statements.Add(s12);
			p1.EntryBlock.Statements.Add(s13);

            Statement s21 = new Statement(0, CreateCall(pc3), p2.EntryBlock);
            Statement s22 = new Statement(0, CreateCall(pc4), p2.EntryBlock);
			p2.EntryBlock.Statements.Add(s21);
			p2.EntryBlock.Statements.Add(s22);

            Statement s31 = new Statement(0, CreateCall(pc4), p3.EntryBlock);
			p3.EntryBlock.Statements.Add(s31);

            Statement s41 = new Statement(0, CreateCall(pc4), p4.EntryBlock);

			g.AddEntryPoint(p1);
			g.AddEdge(s11, p2);
			g.AddEdge(s12, p2);
			g.AddEdge(s13, p3);

			g.AddEdge(s21, p3);
			g.AddEdge(s22, p4);

			g.AddEdge(s31, p4);

			g.AddEdge(s41, p4);		// recursion!

            //$TODO: need Count
//			Assert.IsTrue(g.Callees(p1).Count == 3);
//			Assert.IsTrue(g.CallerStatements(p4).Count == 3);
		}
Ejemplo n.º 11
0
		/// <summary>
		/// Chases a chain statements to locate the expression that
		/// defines the value of a condition code.
		/// </summary>
		/// <param name="sid"></param>
		/// <returns></returns>
		public void FindDefiningExpression(SsaIdentifier sid)
		{
			this.sid = sid;
			negated = false;
			stm = sid.DefStatement;
			if (stm != null)
			{
				Statement stmOld = null;
				defExpr = null;
				while (stm != null && defExpr == null)
				{
					stmOld = stm;
					stm = null;
					stmOld.Instruction.Accept(this);
				}
			}
		}
Ejemplo n.º 12
0
        /// <summary>
        /// Inserts the instr d of the identifier v at statement S.
        /// </summary>
        /// <param name="d"></param>
        /// <param name="v"></param>
        /// <param name="S"></param>
        public void Insert(Instruction d, Identifier v, Statement S)
        {
            // Insert new phi-functions.
            foreach (var dfFode in DomGraph.DominatorFrontier(S.Block))
            {
                // If there is no phi-function for v
                //    create new phi-function for v. (which is an insert, so call self recursively)
                // All input operands of the new phi-finctions are initually assumed to be
                // uses of r.

                // Update uses sets for all uses dominated by S, or the new phi statements.
                // This is done by walking down the dominator tree from each def and find uses
                // that along wit the def match property 1.

                // Update each use that is a parameter of a newly created phi-function, according
                // to property 2.
            }
        }
Ejemplo n.º 13
0
		public void ReplaceDefinitionsWithOutParameter(Identifier id, Identifier idOut)
		{
			this.idOut = idOut;
			wl = new WorkList<Identifier>();
			wl.Add(id);
			var visited = new HashSet<Statement>();

			while (wl.GetWorkItem(out id))
			{
				ssa = ssaIds[id];
				stmDef = ssa.DefStatement;
				if (stmDef != null && !visited.Contains(stmDef))
				{
					visited.Add(stmDef);
					iStmDef = stmDef.Block.Statements.IndexOf(stmDef);
					stmDef.Instruction = stmDef.Instruction.Accept(this);
				}
			}
		}
Ejemplo n.º 14
0
        public void Transform()
        {
            foreach (var s in ssaIds)
            {
                sidGrf = s;
                if (!IsLocallyDefinedFlagGroup(sidGrf))
                    continue;

                var uses = new HashSet<Statement>();
                aliases = new HashSet<SsaIdentifier>();
                ClosureOfUsingStatements(sidGrf, sidGrf.DefExpression, uses, aliases);

                if (trace.TraceInfo) Debug.WriteLine(string.Format("Tracing {0}", sidGrf.DefStatement.Instruction));

                foreach (var u in uses)
                {
                    useStm = u;

                    if (trace.TraceInfo) Debug.WriteLine(string.Format("   used {0}", useStm.Instruction));
                    useStm.Instruction.Accept(this);
                    if (trace.TraceInfo) Debug.WriteLine(string.Format("    now {0}", useStm.Instruction));
                }
            }
        }
Ejemplo n.º 15
0
		/// <summary>
		/// Tries to move the assigment as far down the block as is possible.
		/// </summary>
		/// <param name="ass"></param>
		/// <param name="block"></param>
		/// <param name="i"></param>
		/// <returns>true if a change was made</returns>
		public bool TryMoveAssignment(Statement stmDef, SsaIdentifier sidDef, Expression defExpr, Block block, int initialPosition)
		{
			SideEffectFlags flagsDef = sef.FindSideEffect(stmDef.Instruction);
			for (int i = initialPosition + 1; i < block.Statements.Count; ++i)
			{
				Statement stm = block.Statements[i];
				if (sidDef.Uses.Contains(stm))
				{
					if (CanCoalesce(sidDef, stmDef, stm))
					{
						Coalesced = true;
						return CoalesceStatements(sidDef, defExpr, stmDef, stm);
					}
					else
					{
						return MoveAssignment(initialPosition, i, block);
					}
				}
				if (stm.Instruction.IsControlFlow)
				{
					return MoveAssignment(initialPosition, i, block);
				}

				SideEffectFlags flagsStm = sef.FindSideEffect(stm.Instruction);
				if (sef.Conflict(flagsDef, flagsStm))
				{
					return MoveAssignment(initialPosition, i, block);
				}
			}
			return MoveAssignment(initialPosition, block.Statements.Count, block);
		}
Ejemplo n.º 16
0
		private Block PrecedingPhiBlock(Identifier u, Statement stm)
		{
			PhiAssignment phi = stm.Instruction as PhiAssignment;
			if (phi == null)
				return null;
			for (int i = 0; i < phi.Src.Arguments.Length; ++i)
			{
				if (u == phi.Src.Arguments[i])
					return stm.Block.Pred[i];
			}
			return null;
		}
Ejemplo n.º 17
0
		private Dictionary<SsaIdentifier,SsaIdentifier> VariablesDefinedByStatement(Statement stm)
		{
			Dictionary<SsaIdentifier,SsaIdentifier> W = new Dictionary<SsaIdentifier,SsaIdentifier>();
			foreach (SsaIdentifier sid in ssa)
			{
				if (sid.DefStatement == stm)
					W[sid] = sid;
			}
			return W;
		}
Ejemplo n.º 18
0
		public PhiFunction GetPhiFunction(Statement stm)
		{
			PhiAssignment ass = stm.Instruction as PhiAssignment;
			if (ass == null)
				return null;
			return ass.Src;
		}
Ejemplo n.º 19
0
		// Returns true if v is also live in before executing s.

		public bool LiveOutAtStatement(Statement s, SsaIdentifier v)
		{
			// v is live-out at s.

			List<Identifier> ids = this.IdentifiersDefinedAtStatement(s);
			if (ids != null)
			{
				foreach (Identifier id in ids)
				{
					if (id != v.Identifier)
						interference.Add(id, v.Identifier);
				}
			}
			return (v.DefStatement != s);
		}
Ejemplo n.º 20
0
		public bool IsLiveOut(Identifier id, Statement stm)
		{
			bool live = records[stm.Block].LiveOut.Contains(ssaIds[id]);
			for (int i = stm.Block.Statements.Count - 1; i >= 0; --i)
			{
				Statement s = stm.Block.Statements[i];
				if (s == stm)
					return live;

				if (ssaIds[id].DefStatement == s)
					return false;

				if (!(s.Instruction is PhiAssignment) && ssaIds[id].Uses.Contains(s))
					live = true;
			}
			return live;
		}
Ejemplo n.º 21
0
		public bool IsFirstStatementInBlock(Statement stm, Block block)
		{
			return block.Statements.IndexOf(stm) == 0;
		}
Ejemplo n.º 22
0
		public bool IsDefinedAtStatement(SsaIdentifier v, Statement stm)
		{
			return (v.DefStatement == stm);
		}
Ejemplo n.º 23
0
		public List<Identifier> IdentifiersDefinedAtStatement(Statement stm)
		{
			if (stm == null) return null;
			return defined[stm];
		}
Ejemplo n.º 24
0
        /// <summary>
        /// Returns true if the identifer <paramref name="sid"/>, which is defined in <paramref name="def"/>, can safely
        /// be coalesced into <paramref name="use"/>.
        /// </summary>
        /// <param name="sid">identifier common to <paramref name="def"/> and <paramref name="use"/>.</param>
        /// <param name="def">Statement that defines <paramref name="sid"/>. </param>
        /// <param name="use">Statement that uses <paramref name="sid"/>. </param>
        /// <returns></returns>
		public bool CanCoalesce(SsaIdentifier sid, Statement def, Statement use)
		{
			if (sid.Uses.Count != 1)
				return false;
			System.Diagnostics.Debug.Assert(sid.Uses[0] == use);
			if (use.Instruction is PhiAssignment)
				return false;
			if (use.Instruction is UseInstruction)
				return false;

            //$PERFORMANCE: this loop might be slow and should be improved if possible.
            List<SsaIdentifier> sids;
            if (defsByStatement.TryGetValue(def, out sids))
            {
                foreach (SsaIdentifier sidOther in sids)
                {
                    if (sidOther != sid && sidOther.IsSideEffect)
                    {
                        if (sidOther.Uses.Contains(use))
                            return false;
                    }
                }
            }
			return true;
		}
Ejemplo n.º 25
0
 public UsedIdentifierAdjuster(Statement def, SsaIdentifierCollection ssaIds, Statement use)
 {
     this.def = def;
     this.use = use;
     this.ssaIds = ssaIds;
 }
Ejemplo n.º 26
0
		/// <summary>
		/// Coalesces the single use and the single definition of an identifier.
		/// </summary>
		/// <param name="sid"></param>
		/// <param name="defExpr"></param>
		/// <param name="def"></param>
		/// <param name="use"></param>
		/// <returns></returns>
		public bool CoalesceStatements(SsaIdentifier sid, Expression defExpr, Statement def, Statement use)
		{
            PreCoalesceDump(sid, def, use);
			def.Instruction.Accept(new UsedIdentifierAdjuster(def, ssa.Identifiers, use));
            use.Instruction.Accept(new IdentifierReplacer(ssa, use, sid.Identifier, defExpr));

			List<SsaIdentifier> sids;
			if (defsByStatement.TryGetValue(def, out sids))
			{
				foreach (SsaIdentifier s in sids)
				{
					if (s != sid)
					{
						s.DefStatement = use;
						SetDefStatement(use, s);
					}
				}
			}
			ssa.DeleteStatement(def);
			PostCoalesceDump(use);
			return true;
		}
Ejemplo n.º 27
0
 private static void PreCoalesceDump(SsaIdentifier sid, Statement def, Statement use)
 {
     if (trace.TraceInfo)
     {
         Debug.WriteLineIf(trace.TraceInfo, "Coalescing on " + sid.Identifier.ToString());
         Debug.Indent();
         Debug.WriteLineIf(trace.TraceInfo, def.Instruction.ToString());
         Debug.WriteLineIf(trace.TraceInfo, use.Instruction.ToString());
         Debug.Unindent();
     }
 }
Ejemplo n.º 28
0
 private static void PostCoalesceDump(Statement use)
 {
     if (trace.TraceInfo)
     {
         Debug.WriteLineIf(trace.TraceInfo, "  ; coalesced to");
         Debug.Indent();
         Debug.WriteLineIf(trace.TraceInfo, use.Instruction.ToString());
         Debug.Unindent();
     }
 }
Ejemplo n.º 29
0
        public Statement BranchIf(Expression expr, string label)
        {
            Block b = EnsureBlock(null);
            branchBlock = BlockOf(label);
            TerminateBlock();

            Statement stm = new Statement(0, new Branch(expr, branchBlock), b);
            b.Statements.Add(stm);
            return stm;
        }
Ejemplo n.º 30
0
 public IdentifierReplacer(SsaState ssaIds, Statement use, Identifier idOld, Expression exprNew)
 {
     this.ssaIds = ssaIds;
     this.use = use;
     this.idOld = idOld;
     this.exprNew = exprNew;
 }