Ejemplo n.º 1
0
 public void LiveOutAtBlock(Block b, SsaIdentifier v)
 {
     Set(records[b].LiveOut, v);
     if (!visited.Contains(b))
     {
         visited.Add(b);
         var s = (b.Statements.Count > 0) ? b.Statements[^ 1] : null;
Ejemplo n.º 2
0
 /// <summary>
 /// Computes the closure 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">The SSA identifier whose use-closure we're calculating</param>
 /// <param name="uses">Uses we've seen so far.</param>
 /// <param name="aliases">Aliases of sid we've seen so far.</param>
 public HashSet <Statement> ClosureOfUsingStatements(
     SsaIdentifier sid,
     HashSet <Statement> uses,
     HashSet <Identifier> aliases)
 {
     foreach (var use in sid.Uses)
     {
         if (uses.Contains(use))
         {
             continue;
         }
         uses.Add(use);
         if (IsCopyWithOptionalCast(sid.Identifier, use))
         {
             // Bypass copies (C_4 = C_3) and casts
             // (C_4 = SLICE(SZC_3, bool, 0)
             var ass      = (Assignment)use.Instruction;
             var sidAlias = ssaIds[ass.Dst];
             aliases.Add(sidAlias.Identifier);
             ClosureOfUsingStatements(sidAlias, uses, aliases);
         }
         if (use.Instruction is PhiAssignment phiAss)
         {
             // Bypass PHI nodes.
             var sidPhi = ssaIds[phiAss.Dst];
             aliases.Add(sidPhi.Identifier);
             ClosureOfUsingStatements(sidPhi, uses, aliases);
         }
     }
     return(uses);
 }
Ejemplo n.º 3
0
 private void Set(List <SsaIdentifier> s, SsaIdentifier v)
 {
     if (!s.Contains(v))
     {
         s.Add(v);
     }
 }
Ejemplo n.º 4
0
        public LinearInductionVariable CreateInductionVariable()
        {
            if (ctx.PhiStatement == null)
            {
                return(null);
            }
            if (ctx.PhiIdentifier == null)
            {
                return(null);
            }
            if (ctx.DeltaValue == null)
            {
                return(null);
            }

            SsaIdentifier sidPhi = ssaIds[ctx.PhiIdentifier];

            if (ctx.TestStatement == null && ctx.InitialValue == null)
            {
                return(new LinearInductionVariable(null, ctx.DeltaValue, null, false));
            }
            if (ctx.InitialValue != null)
            {
                if (IsIdUsedOnlyBy(ctx.PhiIdentifier, ctx.TestStatement, ctx.DeltaStatement))
                {
                    // The only use inside the loop is the increment, so we never see the initial value.
                    ctx.InitialValue = Operator.IAdd.ApplyConstants(ctx.InitialValue, ctx.DeltaValue);
                }
            }

            ctx.TestValue = AdjustTestValue(ctx.TestValue);

            return(ctx.CreateInductionVariable());
        }
Ejemplo n.º 5
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);
         }
         if (use.Instruction is PhiAssignment phiAss)
         {
             var sidPhi = ssaIds[phiAss.Dst];
             aliases.Add(sidPhi);
             ClosureOfUsingStatements(sidPhi, expr, uses, aliases);
         }
     }
     return(uses);
 }
Ejemplo n.º 6
0
        public void Transform()
        {
            foreach (var s in ssaIds.ToList())
            {
                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.º 7
0
 private static void GeneratePhiFunction(SsaIdentifier phi, PhiArgument[] args)
 {
     ((PhiAssignment)phi.DefStatement !.Instruction).Src =
         new PhiFunction(
             phi.Identifier.DataType,
             args);
 }
Ejemplo n.º 8
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);
        }
 private void ProcessAdjacentStores(SsaIdentifier sid, StoreOffset[] storeOffset)
 {
     for (int i = 0; i < storeOffset.Length; ++i)
     {
         if (storeOffset[i] == null)
         {
             continue;
         }
         var cast1  = GetCastRhs(storeOffset[i].Store);
         var slice1 = GetSliceRhs(storeOffset[i].Store);
         if (cast1 != null || slice1 != null)
         {
             for (int j = i + 1; j < storeOffset.Length; ++j)
             {
                 var cast2  = GetCastRhs(storeOffset[j].Store);
                 var slice2 = GetSliceRhs(storeOffset[j].Store);
                 if (cast1 != null && slice2 != null)
                 {
                     ReplaceStores(sid, storeOffset[i], storeOffset[j]);
                     storeOffset[i] = null !;
                     storeOffset[j] = null !;
                 }
                 else if (slice1 != null && cast2 != null)
                 {
                     throw new NotImplementedException();
                 }
             }
         }
     }
 }
Ejemplo n.º 10
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);
 }
Ejemplo n.º 11
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.º 12
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.º 13
0
        public void Transform()
        {
            foreach (var s in ssaIds.ToList())
            {
                sidGrf = s;
                if (!IsLocallyDefinedFlagGroup(sidGrf))
                {
                    continue;
                }
                if (sidGrf.DefStatement.Instruction is AliasAssignment)
                {
                    continue;
                }
                var uses = new HashSet <Statement>();
                this.aliases = new HashSet <Identifier>();
                ClosureOfUsingStatements(sidGrf, uses, aliases);
                trace.Inform("Tracing {0}", sidGrf.DefStatement.Instruction);

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

                    trace.Inform("   used {0}", useStm.Instruction);
                    useStm.Instruction.Accept(this);
                    trace.Inform("    now {0}", useStm.Instruction);
                }
            }
        }
Ejemplo n.º 14
0
 private Identifier Reg8(string name)
 {
     var mr = new RegisterStorage(name, ssaIds.Count, 0, 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;
 }
Ejemplo n.º 15
0
        public void ReplaceAssigment(SsaIdentifier sid, Assignment ass)
        {
            var stm = sid.DefStatement !;

            ssa.RemoveUses(stm);
            sid.DefStatement !.Instruction = ass;
            ssa.AddUses(stm);
        }
Ejemplo n.º 16
0
 private void LiveOutAtBlock(Block n, SsaIdentifier sid)
 {
     if (!visitedBlocks.ContainsKey(n))
     {
         visitedBlocks[n] = n;
         LiveOutAtStatement(n, n.Statements.Count - 1, sid);
     }
 }
Ejemplo n.º 17
0
 /// <summary>
 /// Ensure that identifier is alive. Simplify phi function until
 /// identifier is not in the list of removed phi identifiers
 /// </summary>
 /// <param name="sid">SSA identifier of phi function</param>
 /// <returns>
 /// Returns original SSA identifier or result of phi function
 /// simplification
 /// </returns>
 private SsaIdentifier EnsureLiveIdentifier(SsaIdentifier sid)
 {
     while (this.outer.sidsToRemove.Contains(sid))
     {
         sid = SamePhiArgument(sid);
     }
     return(sid);
 }
Ejemplo n.º 18
0
        private bool IsLocallyDefinedFlagGroup(SsaIdentifier sid)
        {
            var stg = sid.OriginalIdentifier.Storage;

            return((stg is FlagGroupStorage ||
                    stg is FlagRegister) &&
                   sid.DefStatement != null);
        }
Ejemplo n.º 19
0
        public override void VisitIdentifier(Identifier id)
        {
            SsaIdentifier sid = ssa.Identifiers[id];

            if (sid.DefStatement != null)
            {
                liveIds.Add(sid);
            }
        }
Ejemplo n.º 20
0
 public IEnumerable <SsaIdentifier> GetSuccessors(SsaIdentifier sid)
 {
     this.operands = new List <SsaIdentifier>();
     if (sid.DefStatement != null)
     {
         sid.DefStatement.Instruction.Accept(this);
     }
     return(operands);
 }
Ejemplo n.º 21
0
 private SsaIdentifier AddPhiOperands(Identifier id, SsaIdentifier phi)
 {
     // Determine operands from predecessors.
     ((PhiAssignment)phi.DefStatement.Instruction).Src =
         new PhiFunction(
             id.DataType,
             phi.DefStatement.Block.Pred.Select(p => ReadVariable(id, p).Identifier).ToArray());
     return(TryRemoveTrivial(phi));
 }
Ejemplo n.º 22
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.º 23
0
            private void UsePhiArguments(SsaIdentifier phi)
            {
                var phiFunc = ((PhiAssignment)phi.DefStatement.Instruction).Src;

                foreach (var de in phiFunc.Arguments)
                {
                    var id = (Identifier)de.Value;
                    ssaIds[id].Uses.Add(phi.DefStatement);
                }
            }
Ejemplo n.º 24
0
        public override Expression VisitTestCondition(TestCondition tc)
        {
            SsaIdentifier sid = ssaIds[(Identifier)tc.Expression];

            sid.Uses.Remove(useStm !);
            Expression c = UseGrfConditionally(sid, tc.ConditionCode);

            Use(c, useStm !);
            return(c);
        }
Ejemplo n.º 25
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.º 26
0
        private void DefineUninitializedIdentifier(
            Statement stm,
            SsaIdentifier sid)
        {
            var value  = Constant.Invalid;
            var ass    = new Assignment(sid.Identifier, value);
            var newStm = InsertStatementAfter(ass, stm);

            sid.DefExpression = value;
            sid.DefStatement  = newStm;
        }
Ejemplo n.º 27
0
            private Identifier Use(Identifier idOld)
            {
                SsaIdentifier sid;

                if (!ssa.Identifiers.TryGetValue(idOld, out sid))
                {
                    sid = new SsaIdentifier(idOld, idOld, stmCur, null, false);
                    ssa.Identifiers.Add(idOld, sid);
                }
                ssa.Identifiers[idOld].Uses.Add(stmCur);
                return(idOld);
            }
Ejemplo n.º 28
0
        public override void VisitIdentifier(Identifier id)
        {
            SsaIdentifier sid = ssaIds[id];

            for (int i = 0; i < sid.Uses.Count; ++i)
            {
                if (sid.Uses[i] == def)
                {
                    sid.Uses[i] = use;
                }
            }
        }
Ejemplo n.º 29
0
        public Identifier InsertAssignmentNewId(Identifier idOld, Block b, int i)
        {
            var stm = new Statement(
                (b.Address ?? b.Procedure.EntryAddress).ToLinear(),
                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.º 30
0
        private Expression ReplaceMkSequence(MkSequence seq, Statement stmCur, SsaIdentifier sidHead, SsaIdentifier sidTail)
        {
            var idSeq = ssa.Procedure.Frame.EnsureSequence(
                seq.DataType,
                sidHead.OriginalIdentifier.Storage,
                sidTail.OriginalIdentifier.Storage);
            SsaIdentifier sidSeq = EnsureSequenceArgument(idSeq);

            sidSeq.Uses.Add(stmCur);
            RemoveUse(sidHead);
            RemoveUse(sidTail);
            return(sidSeq.Identifier);
        }
Ejemplo n.º 31
0
        public bool IsIdUsedOnlyBy(Identifier id, Statement?stm1, Statement?stm2)
        {
            SsaIdentifier sid = ssa.Identifiers[id];

            foreach (Statement u in sid.Uses)
            {
                if (u != stm1 && u != stm2)
                {
                    return(false);
                }
            }
            return(true);
        }
Ejemplo n.º 32
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);
         }
     }
 }
Ejemplo n.º 33
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.º 34
0
		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());
		}
Ejemplo n.º 35
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.º 36
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.º 37
0
        public void Add(SsaIdentifier sid)
		{
            if (Members.Contains(sid))		// should be a set!
                return;

			Members.Add(sid);
			if (this.Identifier == null)
			{
				this.Identifier = sid.Identifier;
			}
			else
			{
				if (string.Compare(sid.Identifier.Name, this.Identifier.Name) < 0)
				{
					this.Identifier = sid.Identifier;
				}

				if (iv == null)
				{
					iv = sid.InductionVariable;
				}
				else if (sid.InductionVariable == null)
				{
					sid.InductionVariable = iv;
				}
				else 
				{
					iv = LinearInductionVariable.Merge(sid.InductionVariable, iv);
					if (iv == null)
					{
						// Warning(string.Format("{0} and {1} are conflicting induction variables: {2} {3}", 
					}
					sid.InductionVariable = iv;
				}
			}
			Definitions.Add(sid.DefStatement);
			foreach (Statement u in sid.Uses)
				Uses.Add(u);
		}
Ejemplo n.º 38
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.º 39
0
 public override void VisitIdentifier(Identifier id)
 {
     sid = ssaIds[id];
     stm = sid.DefStatement;
 }
Ejemplo n.º 40
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);
		}
Ejemplo n.º 41
0
		private void LiveOutAtBlock(Block n, SsaIdentifier sid)
		{
			if (!visitedBlocks.ContainsKey(n))
			{
				visitedBlocks[n] = n;
				LiveOutAtStatement(n, n.Statements.Count-1, sid);
			}
		}
Ejemplo n.º 42
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);
			}
		}
Ejemplo n.º 43
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.º 44
0
		private void Set(List<SsaIdentifier> s, SsaIdentifier v)
		{
			if (!s.Contains(v))
				s.Add(v);
		}
Ejemplo n.º 45
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());
		}
Ejemplo n.º 46
0
		public void RenameDominatedIdentifiers(SsaIdentifier sidOld, SsaIdentifier sidNew)
		{
			DominatedUseRenamer dur = new DominatedUseRenamer(doms);
			dur.Transform(sidOld, sidNew);
		}
Ejemplo n.º 47
0
        private bool IsLocallyDefinedFlagGroup(SsaIdentifier sid)
        {
            return sid.OriginalIdentifier.Storage is FlagGroupStorage && sid.DefStatement != null;
		}
Ejemplo n.º 48
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.º 49
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.º 50
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.º 51
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.º 52
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;
			}
Ejemplo n.º 53
0
		public bool IsDefinedAtStatement(SsaIdentifier v, Statement stm)
		{
			return (v.DefStatement == stm);
		}
Ejemplo n.º 54
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);
			}
		}
Ejemplo n.º 55
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);
			}
		}
Ejemplo n.º 56
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;
 }
Ejemplo n.º 57
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);
					}
				}
			}
Ejemplo n.º 58
0
        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());
        }
Ejemplo n.º 59
0
        private bool IsLocallyDefinedFlagGroup(SsaIdentifier sid)
        {
            var stg = sid.OriginalIdentifier.Storage;
            return (stg is FlagGroupStorage ||
                    stg is FlagRegister)
                && sid.DefStatement != null;
		}