Пример #1
0
 private void CategorizeIdentifier(SsaIdentifier sid)
 {
     if (sid.DefStatement.Instruction is DefInstruction &&
         sid.DefStatement.Block == proc.EntryBlock)
     {
         // Reaching definition was a DefInstruction;
         flow.Preserved.Add(sid.OriginalIdentifier.Storage);
         return;
     }
     Assignment ass;
     if (sid.DefStatement.Instruction.As<Assignment>(out ass))
     {
         if ((ass.Src == sid.OriginalIdentifier) 
             ||
            (sid.OriginalIdentifier.Storage == arch.StackRegister &&
             ass.Src == proc.Frame.FramePointer))
         {
             flow.Preserved.Add(sid.OriginalIdentifier.Storage);
             return;
         }
         Constant c;
         if (ass.Src.As<Constant>(out c))
         {
             flow.Constants.Add(sid.OriginalIdentifier.Storage, c);
             // Fall through to Trashed below --v
         }
     }
     flow.Trashed.Add(sid.OriginalIdentifier.Storage);
 }
Пример #2
0
 private Identifier Reg8(string name)
 {
     var mr = new RegisterStorage(name, ssaIds.Count, PrimitiveType.Byte);
     Identifier id = new Identifier(mr.Name, mr.DataType, mr);
     SsaIdentifier sid = new SsaIdentifier(id, id, null, null, false);
     ssaIds.Add(id, sid);
     return sid.Identifier;
 }
Пример #3
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);
 }
		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());
		}
Пример #5
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);
				}
			}
		}
Пример #6
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);
				}
			}
		}
Пример #7
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));
                }
            }
        }
Пример #8
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);
		}
Пример #9
0
		public void LiveInAtStatement(Block b, int i, SsaIdentifier v)
		{
			// v is live-in at s.

			while (i > 0)
			{
				--i;
				Statement s = b.Statements[i];
				if (IsDefinedAtStatement(v, s))
					return;
			}
		
			// v is live-in at the header of this block!
			Set(records[b].LiveIn, v);
			foreach (Block p in b.Pred)
			{
				LiveOutAtBlock(p, v);
			}
		}
Пример #10
0
		public void LiveOutAtBlock(Block b, SsaIdentifier v)
		{
			Set(records[b].LiveOut, v);
			if (!visited.Contains(b))
			{
				visited.Add(b);
				Statement s = b.Statements.Last;
				if (!IsDefinedAtStatement(v, s))
					LiveInAtStatement(b, b.Statements.Count - 1, v);
			}
		}
Пример #11
0
		public bool IsDefinedAtStatement(SsaIdentifier v, Statement stm)
		{
			return (v.DefStatement == stm);
		}
Пример #12
0
		public void RenameDominatedIdentifiers(SsaIdentifier sidOld, SsaIdentifier sidNew)
		{
			DominatedUseRenamer dur = new DominatedUseRenamer(doms);
			dur.Transform(sidOld, sidNew);
		}
		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());
		}
Пример #14
0
		private void LiveInAtStatement(Block block, int iStm, SsaIdentifier sid)
		{
			if (iStm <= 0)
			{
				foreach (Block p in block.Pred)
				{
					LiveOutAtBlock(p, sid);
				}
			}
			else
			{
				LiveOutAtStatement(block, --iStm, sid);
			}
		}
Пример #15
0
		public override void VisitIdentifier(Identifier id)
		{
			sid = ssaIds[id];
			stm = sid.DefStatement;
		}
Пример #16
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;
		}
Пример #17
0
 /// <summary>
 /// Computes the close of a web of using statements. The <paramref name="uses"/> hash set 
 /// will contain all non-trivial uses of the expression.
 /// </summary>
 /// <param name="sid"></param>
 /// <param name="expr"></param>
 /// <param name="uses"></param>
 public HashSet<Statement> ClosureOfUsingStatements(
     SsaIdentifier sid,
     Expression expr,
     HashSet<Statement> uses,
     HashSet<SsaIdentifier> aliases)
 {
     foreach (var use in sid.Uses)
     {
         if (uses.Contains(use))
             continue;
         uses.Add(use);
         if (IsCopyWithOptionalCast(sid.Identifier, use))
         {
             var ass = (Assignment)use.Instruction;
             var sidAlias = ssaIds[ass.Dst];
             aliases.Add(sidAlias);
             ClosureOfUsingStatements(sidAlias, expr, uses, aliases);
         }
     }
     return uses;
 }
Пример #18
0
		public Expression UseGrfConditionally(SsaIdentifier sid, ConditionCode cc)
		{
			GrfDefinitionFinder gf = new GrfDefinitionFinder(ssaIds);
			gf.FindDefiningExpression(sid);
			
			Expression e = gf.DefiningExpression;
			if (e == null)
			{
				return sid.Identifier;
			}
			BinaryExpression binDef = e as BinaryExpression;
			if (binDef != null)
			{
				if (gf.IsNegated)
					e = new UnaryExpression(Operator.Not, PrimitiveType.Bool, e);
				return e;
			}
			ConditionOf cof = e as ConditionOf;
			if (cof != null)
			{
				binDef = cof.Expression as BinaryExpression;
				if (binDef == null)
                    binDef = CmpExpressionToZero(cof.Expression);
				return ComparisonFromConditionCode(cc, binDef, gf.IsNegated);
			}
			Application app = e as Application;
			if (app != null)
			{
				return sid.Identifier;
			}
			PhiFunction phi = e as PhiFunction;
			if (phi != null)
			{
				return sid.Identifier;
			}
			throw new NotImplementedException("NYI: e: " + e.ToString());
		}
Пример #19
0
        private bool IsLocallyDefinedFlagGroup(SsaIdentifier sid)
        {
            return sid.OriginalIdentifier.Storage is FlagGroupStorage && sid.DefStatement != null;
		}
Пример #20
0
		private void Set(List<SsaIdentifier> s, SsaIdentifier v)
		{
			if (!s.Contains(v))
				s.Add(v);
		}
Пример #21
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);
		}
Пример #22
0
		private void LiveOutAtBlock(Block n, SsaIdentifier sid)
		{
			if (!visitedBlocks.ContainsKey(n))
			{
				visitedBlocks[n] = n;
				LiveOutAtStatement(n, n.Statements.Count-1, sid);
			}
		}
Пример #23
0
			public Node(SsaIdentifier info)
			{
				this.info = info;
				if (info.DefStatement != null)
				{
					Assignment ass = info.DefStatement.Instruction as Assignment;
					if (ass != null)
					{
						this.lvalue = ass.Dst;
						return;
					}
					PhiAssignment phi = info.DefStatement.Instruction as PhiAssignment;
					if (phi != null)
					{
						this.lvalue = phi.Dst;
						return;
					}
				}
				this.lvalue = info.Identifier;
			}
Пример #24
0
		public void LiveOutAtStatement(Block block, int iStm, SsaIdentifier sid)
		{
            Dictionary<SsaIdentifier, SsaIdentifier> W = iStm >= 0 
				? VariablesDefinedByStatement(block.Statements[iStm])
				: new Dictionary<SsaIdentifier,SsaIdentifier>();

			foreach (SsaIdentifier w in W.Values)
			{
				if (w != sid)
					interference.Add(w.Identifier, sid.Identifier);

			}
			if (!W.ContainsKey(sid))
				LiveInAtStatement(block, iStm, sid);
		}
Пример #25
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;
		}
Пример #26
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();
     }
 }
Пример #27
0
			public void Transform(SsaIdentifier sidOld, SsaIdentifier sidNew)
			{
				this.sidOld = sidOld;
				this.sidNew = sidNew;

				foreach (Statement stm in sidOld.Uses)
				{
					stmCur = stm;
					if (domGraph.DominatesStrictly(sidOld.DefStatement, stm))
					{
						stm.Instruction = stm.Instruction.Accept(this);
					}
				}
			}