Exemplo n.º 1
0
        public List <Interval> BuildIntervals(DirectedGraph <StructureNode> graph, StructureNode entry)
        {
            if (graph == null)
            {
                throw new ArgumentNullException("graph");
            }
            if (entry == null)
            {
                throw new ArgumentNullException("entry");
            }

            var intervalsInGraph = new List <Interval>();          // The sequence of intervals in this graph
            var headers          = new WorkList <StructureNode>(); // The sequence of interval header nodes
            var beenInH          = new HashSet <StructureNode>();  // The set of nodes that have been in the above sequence at some stage

            headers.Add(entry);
            beenInH.Add(entry);

            StructureNode header;

            while (headers.GetWorkItem(out header))
            {
                Interval newInt = new Interval(intervalID++, header);

                // Process each succesive node in the interval until no more nodes can be added to the interval.
                for (int i = 0; i < newInt.Nodes.Count; i++)
                {
                    StructureNode curNode = newInt.Nodes[i];

                    foreach (StructureNode succ in graph.Successors(curNode))
                    {
                        // Only further consider the current child if it isn't already in the interval
                        if (!newInt.Nodes.Contains(succ))
                        {
                            // If the current child has all its parents
                            // inside the interval, then add it to the interval. Remove it from the header
                            // sequence if it is on it.
                            if (IsSubSetOf(graph.Predecessors(succ), newInt))
                            {
                                newInt.AddNode(succ);
                                headers.Remove(succ);
                            }

                            // Otherwise, add it to the header sequence if it hasn't already been in it.
                            else if (!beenInH.Contains(succ))
                            {
                                headers.Add(succ);
                                beenInH.Add(succ);
                            }
                        }
                    }
                }

                // Add the new interval to the sequence of intervals
                intervalsInGraph.Add(newInt);
            }
            return(intervalsInGraph);
        }
Exemplo n.º 2
0
        public void BuildIntervals(DerivedGraph derGraph)
        {
            if (derGraph == null)
                throw new ArgumentNullException("derGraph");
            if (derGraph.Entry == null)
                throw new ArgumentException("cfg graph must be non-null.", "derGraph");

            var intSeq = derGraph.Intervals;	// The sequence of intervals in this graph
            var headerSeq = new WorkList<StructureNode>();	// The sequence of interval header nodes
            var beenInH = new List<StructureNode>();	// The set of nodes that have been in the above sequence at some stage

            headerSeq.Add(derGraph.Entry);

            beenInH.Add(derGraph.Entry);

            StructureNode header;
            while (headerSeq.GetWorkItem(out header))
            {
                var newInt = new Interval(intervalID++, header);

                // Process each succesive node in the interval until no more nodes can be added to the interval.
                for (int i = 0; i < newInt.Nodes.Count; i++)
                {
                    var curNode = newInt.Nodes[i];

                    // Process each child of the current node
                    for (int j = 0; j < curNode.OutEdges.Count; j++)
                    {
                        var succ = curNode.OutEdges[j];

                        // Only further consider the current child if it isn't already in the interval
                        if (!newInt.Nodes.Contains(succ))
                        {
                            // If the current child has all its parents
                            // inside the interval, then add it to the interval. Remove it from the header
                            // sequence if it is on it.
                            if (IsSubSetOf(succ.InEdges, newInt))
                            {
                                newInt.AddNode(succ);
                                headerSeq.Remove(succ);
                            }

                            // Otherwise, add it to the header sequence if it hasn't already been in it.
                            else if (!beenInH.Contains(succ))
                            {
                                headerSeq.Add(succ);
                                beenInH.Add(succ);
                            }
                        }
                    }
                }

                // Add the new interval to the sequence of intervals
                intSeq.Add(newInt);
            }
        }
Exemplo n.º 3
0
 public void WlAdd()
 {
     WorkList<int> w = new WorkList<int>();
     w.Add(3);
     Assert.IsFalse(w.IsEmpty);
     int x;
     Assert.IsTrue(w.GetWorkItem(out x));
     Assert.AreEqual(3, x);
     Assert.IsTrue(w.IsEmpty);
 }
Exemplo n.º 4
0
        public void WlAdd()
        {
            WorkList <int> w = new WorkList <int>();

            w.Add(3);
            Assert.IsFalse(w.IsEmpty);
            int x;

            Assert.IsTrue(w.GetWorkItem(out x));
            Assert.AreEqual(3, x);
            Assert.IsTrue(w.IsEmpty);
        }
Exemplo n.º 5
0
 public void WlRemove()
 {
     WorkList<int> w = new WorkList<int>();
     w.Add(3);
     w.Add(2);
     Assert.IsFalse(w.IsEmpty);
     w.Remove(3);
     Assert.IsFalse(w.IsEmpty);
     w.Remove(2);
     Assert.IsTrue(w.IsEmpty);
     int x;
     Assert.IsFalse(w.GetWorkItem(out x));
 }
Exemplo n.º 6
0
        private HashSet <Statement> PlacePhiFunctions()
        {
            HashSet <Statement> phiStatements = new HashSet <Statement>();
            var defVars = LocateAllDefinedVariables(AOrig);

            MarkTemporariesDeadIn(AOrig);

            // For each defined variable in block n, collect the places where it is defined

            foreach (var a in defVars)
            {
                // Create a worklist W of all the blocks that define a.

                var W = new WorkList <Block>();
                foreach (Block b in SsaState.DomGraph.ReversePostOrder.Keys)
                {
                    byte bits;
                    AOrig[SsaState.RpoNumber(b)].TryGetValue(a, out bits);
                    if ((bits & BitDefined) != 0)
                    {
                        W.Add(b);
                    }
                }
                Block n;
                while (W.GetWorkItem(out n))
                {
                    foreach (Block y in SsaState.DomGraph.DominatorFrontier(n))
                    {
                        // Only add phi functions if there is no
                        // phi already and variable is not deadIn.

                        var  dict = AOrig[SsaState.RpoNumber(y)];
                        byte bits;
                        dict.TryGetValue(a, out bits);
                        if ((bits & (BitHasPhi | BitDeadIn)) == 0)
                        {
                            bits   |= BitHasPhi;
                            dict[a] = bits;
                            var stm = InsertPhiStatement(y, a);
                            phiStatements.Add(stm);
                            if ((bits & BitDefined) == 0)
                            {
                                W.Add(y);
                            }
                        }
                    }
                }
            }
            return(phiStatements);
        }
Exemplo n.º 7
0
        public void WlRemove()
        {
            WorkList <int> w = new WorkList <int>();

            w.Add(3);
            w.Add(2);
            Assert.IsFalse(w.IsEmpty);
            w.Remove(3);
            Assert.IsFalse(w.IsEmpty);
            w.Remove(2);
            Assert.IsTrue(w.IsEmpty);
            int x;

            Assert.IsFalse(w.GetWorkItem(out x));
        }
Exemplo n.º 8
0
 public DataType BuildOverlappedStructure(List<StructureField> fields)
 {
     List<StructureType> types = new List<StructureType>();
     int commonOffset = CommonOffset(fields);
     StructureField field;
     WorkList<StructureField> worklist = new WorkList<StructureField>(fields);
     while (worklist.GetWorkItem(out field))
     {
         StructureType s = FindStructureToFitIn(field, commonOffset, types);
         if (s == null)
         {
             s = new StructureType();
             types.Add(s);
         }
         s.Fields.Add(new StructureField(field.Offset - commonOffset, field.DataType));
     }
     return Normalize(types);
 }
Exemplo n.º 9
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);
                }
            }
        }
Exemplo n.º 10
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);
				}
			}
		}
Exemplo n.º 11
0
        public DataType BuildOverlappedStructure(List <StructureField> fields)
        {
            List <StructureType> types             = new List <StructureType>();
            int                       commonOffset = CommonOffset(fields);
            StructureField            field;
            WorkList <StructureField> worklist = new WorkList <StructureField>(fields);

            while (worklist.GetWorkItem(out field))
            {
                StructureType s = FindStructureToFitIn(field, commonOffset, types);
                if (s == null)
                {
                    s = new StructureType();
                    types.Add(s);
                }
                s.Fields.Add(new StructureField(field.Offset - commonOffset, field.DataType));
            }
            return(Normalize(types));
        }
Exemplo n.º 12
0
        /// <summary>
        /// As far as possible, try fusing consecutive linear blocks in the
        /// cluster.
        /// </summary>
        /// <param name="cluster"></param>
        public void FuseLinearBlocks(Cluster cluster)
        {
            var      wl = new WorkList <RtlBlock>(cluster.Blocks);
            RtlBlock block;

            while (wl.GetWorkItem(out block))
            {
                if (sr.ICFG.Successors(block).Count != 1)
                {
                    continue;
                }
                var succ = sr.ICFG.Successors(block).First();
                if (sr.ICFG.Predecessors(succ).Count != 1)
                {
                    continue;
                }
                Debug.Assert(sr.ICFG.Predecessors(succ).First() == block, "Inconsistent graph");
                if (!(block.Instructions.Last().Instructions.Last() is RtlAssignment))
                {
                    continue;
                }

                // Move all instructions into predecessor.
                block.Instructions.AddRange(succ.Instructions);
                sr.ICFG.RemoveEdge(block, succ);
                var succSuccs = sr.ICFG.Successors(succ).ToList();
                foreach (var ss in succSuccs)
                {
                    sr.ICFG.RemoveEdge(succ, ss);
                    sr.ICFG.AddEdge(block, ss);
                }
                cluster.Blocks.Remove(succ);
                // May be more blocks.
                wl.Add(block);
            }
        }
Exemplo n.º 13
0
        private State [] BuildDfaTable(Node n)
        {
            List <State> dStates = new List <State>();

            // Create the default, error state.

            State err = new State(new BitArray(n.FirstPos.Length), charClasses);

            AddState(dStates, err);

            // Create the initial state.

            State s0 = new State(n.FirstPos, charClasses);

            AddState(dStates, s0);

            // Start the worklist.

            WorkList <State> worklist = new WorkList <State>();

            worklist.Add(s0);
            State t;

            while (worklist.GetWorkItem(out t))
            {
                Debug.WriteLine(t.ToString());
                for (int a = 0; a != charClasses; ++a)
                {
                    // Create U, a state consisting of the positions in
                    // FollowPos(p) where p is any position in t that has
                    // an 'a'.

                    State u = new State(new BitArray(positions.Count), charClasses);
                    for (int p = 0; p != t.Positions.Length; ++p)
                    {
                        if (!t.Positions[p])
                        {
                            continue;
                        }
                        ByteNode pp = (ByteNode)positions[p];
                        if (pp.Any || alphabet[pp.startByte] == a)
                        {
                            u.Positions.Or(pp.FollowPos);
                        }
                        t.Accepts |= pp.Accepts;
                    }

                    if (IsEmptySet(u.Positions))
                    {
                        u = null;
                    }
                    else
                    {
                        State uu = FindState(dStates, u.Positions);
                        if (uu == null)
                        {
                            AddState(dStates, u);
                            worklist.Add(u);
                        }
                        else
                        {
                            u = uu;
                        }
                    }
                    t.NextState[a] = u;
                }
                Debug.WriteLine("t complete: " + t);
            }
            return(dStates.ToArray());
        }
Exemplo n.º 14
0
        private void PlacePhiFunctions()
        {
            var defVars = LocateAllDefinedVariables(AOrig);
            MarkTemporariesDeadIn(AOrig);

            // For each defined variable in block n, collect the places where it is defined

            foreach (var a in defVars)
            {
                // Create a worklist W of all the blocks that define a.

                var W = new WorkList<Block>();
                foreach (Block b in SsaState.DomGraph.ReversePostOrder.Keys)
                {
                    byte bits;
                    AOrig[SsaState.RpoNumber(b)].TryGetValue(a, out bits);
                    if ((bits & BitDefined) != 0)
                        W.Add(b);
                }
                Block n;
                while (W.GetWorkItem(out n))
                {
                    foreach (Block y in SsaState.DomGraph.DominatorFrontier(n))
                    {
                        // Only add phi functions if there is no
                        // phi already and variable is not deadIn.

                        var dict = AOrig[SsaState.RpoNumber(y)];
                        byte bits;
                        dict.TryGetValue(a, out bits);
                        if ((bits & (BitHasPhi | BitDeadIn)) == 0)
                        {
                            bits |= BitHasPhi;
                            dict[a] = bits;
                            InsertPhiStatement(y, a);
                            if ((bits & BitDefined) == 0)
                            {
                                W.Add(y);
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 15
0
        private void Eliminate()
        {
            liveIds = new WorkList <SsaIdentifier>();
            HashSet <Statement> marks = new HashSet <Statement>();

            // Initially, just mark those statements that contain critical statements.
            // These are calls to other functions, functions (which have side effects) and use statements.
            // Critical instructions must never be considered dead.

            foreach (var stm in proc.Statements)
            {
                if (critical.IsCritical(stm.Instruction))
                {
                    if (trace.TraceInfo)
                    {
                        Debug.WriteLineIf(trace.TraceInfo, string.Format("Critical: {0}", stm.Instruction));
                    }
                    marks.Add(stm);
                    stm.Instruction.Accept(this);               // mark all used identifiers as live.
                }
            }

            // Each identifier is live, so its defining statement is also live.

            SsaIdentifier sid;

            while (liveIds.GetWorkItem(out sid))
            {
                Statement def = sid.DefStatement;
                if (def != null)
                {
                    if (!marks.Contains(def))
                    {
                        if (trace.TraceInfo)
                        {
                            Debug.WriteLine(string.Format("Marked: {0}", def.Instruction));
                        }
                        marks.Add(def);
                        sid.DefStatement.Instruction.Accept(this);
                    }
                }
            }

            // We have now marked all the useful instructions in the code. Any non-marked
            // instruction is now useless and should be deleted.

            foreach (Block b in proc.ControlGraph.Blocks)
            {
                for (int iStm = 0; iStm < b.Statements.Count; ++iStm)
                {
                    Statement stm = b.Statements[iStm];
                    if (!marks.Contains(stm))
                    {
                        if (trace.TraceInfo)
                        {
                            Debug.WriteLineIf(trace.TraceInfo, string.Format("Deleting: {0}", stm.Instruction));
                        }
                        ssa.DeleteStatement(stm);
                        --iStm;
                    }
                }
            }

            AdjustApplicationsWithDeadReturnValues();
        }
Exemplo n.º 16
0
        public List<Interval> BuildIntervals(DirectedGraph<StructureNode> graph, StructureNode entry)
        {
            if (graph == null)
                throw new ArgumentNullException("graph");
            if (entry == null)
                throw new ArgumentNullException("entry");

            var intervalsInGraph = new List<Interval>();	// The sequence of intervals in this graph
            var headers = new WorkList<StructureNode>();	// The sequence of interval header nodes
            var beenInH = new HashSet<StructureNode>();	    // The set of nodes that have been in the above sequence at some stage

            headers.Add(entry);
            beenInH.Add(entry);

            StructureNode header;
            while (headers.GetWorkItem(out header))
            {
                Interval newInt = new Interval(intervalID++, header);

                // Process each succesive node in the interval until no more nodes can be added to the interval.
                for (int i = 0; i < newInt.Nodes.Count; i++)
                {
                    StructureNode curNode = newInt.Nodes[i];

                    foreach (StructureNode succ in graph.Successors(curNode))
                    {
                        // Only further consider the current child if it isn't already in the interval
                        if (!newInt.Nodes.Contains(succ))
                        {
                            // If the current child has all its parents
                            // inside the interval, then add it to the interval. Remove it from the header
                            // sequence if it is on it.
                            if (IsSubSetOf(graph.Predecessors(succ), newInt))
                            {
                                newInt.AddNode(succ);
                                headers.Remove(succ);
                            }

                            // Otherwise, add it to the header sequence if it hasn't already been in it.
                            else if (!beenInH.Contains(succ))
                            {
                                headers.Add(succ);
                                beenInH.Add(succ);
                            }
                        }
                    }
                }

                // Add the new interval to the sequence of intervals
                intervalsInGraph.Add(newInt);
            }
            return intervalsInGraph;
        }
Exemplo n.º 17
0
		private State [] BuildDfaTable(Node n)
		{
			List<State> dStates = new List<State>();

			// Create the default, error state.

			State err = new State(new BitArray(n.FirstPos.Length), charClasses);
			AddState(dStates, err);

			// Create the initial state.

			State s0 = new State(n.FirstPos, charClasses);
			AddState(dStates, s0);

			// Start the worklist.

            WorkList<State> worklist = new WorkList<State>();
			worklist.Add(s0);
            State t;
			while (worklist.GetWorkItem(out t))
			{
				Debug.WriteLine(t.ToString());
				for (int a = 0; a != charClasses; ++a)
				{
					// Create U, a state consisting of the positions in 
					// FollowPos(p) where p is any position in t that has 
					// an 'a'.

					State u = new State(new BitArray(positions.Count), charClasses);
					for (int p = 0; p != t.Positions.Length; ++p)
					{
						if (!t.Positions[p])
							continue;
						ByteNode pp = (ByteNode) positions[p];
						if (pp.Any || alphabet[pp.startByte] == a)
						{
							u.Positions.Or(pp.FollowPos);
						}
						t.Accepts |= pp.Accepts;
					}

					if (IsEmptySet(u.Positions))
					{
						u = null;
					}
					else
					{
						State uu = FindState(dStates, u.Positions);
						if (uu == null)
						{
							AddState(dStates, u);
							worklist.Add(u);
						}
						else
						{
							u = uu;
						}
					}
					t.NextState[a] = u;
				}
				Debug.WriteLine("t complete: " + t);
			}
            return dStates.ToArray(); 
		}
Exemplo n.º 18
0
		private void Eliminate()
		{
			liveIds = new WorkList<SsaIdentifier>();
			HashSet<Statement> marks = new HashSet<Statement>();

			// Initially, just mark those statements that contain critical statements.
			// These are calls to other functions, functions (which have side effects) and use statements.
			// Critical instructions must never be considered dead.

            foreach (var stm in proc.Statements)
            {
                if (critical.IsCritical(stm.Instruction))
                {
                    if (trace.TraceInfo) Debug.WriteLineIf(trace.TraceInfo, string.Format("Critical: {0}", stm.Instruction));
                    marks.Add(stm);
                    stm.Instruction.Accept(this);		// mark all used identifiers as live.
                }
            }
			
			// Each identifier is live, so its defining statement is also live.

            SsaIdentifier sid;
			while (liveIds.GetWorkItem(out sid))
			{
				Statement def = sid.DefStatement;
				if (def != null)
				{
					if (!marks.Contains(def))
					{
						if (trace.TraceInfo) Debug.WriteLine(string.Format("Marked: {0}", def.Instruction));
                        marks.Add(def);
						sid.DefStatement.Instruction.Accept(this);
					}
				}
			}

			// We have now marked all the useful instructions in the code. Any non-marked
			// instruction is now useless and should be deleted.

			foreach (Block b in proc.ControlGraph.Blocks)
			{
				for (int iStm = 0; iStm < b.Statements.Count; ++iStm)
				{
					Statement stm = b.Statements[iStm];
					if (!marks.Contains(stm))
					{
						if (trace.TraceInfo) Debug.WriteLineIf(trace.TraceInfo, string.Format("Deleting: {0}", stm.Instruction));
						ssa.DeleteStatement(stm);
						--iStm;
					}
				}
			}

			AdjustApplicationsWithDeadReturnValues();
		}
Exemplo n.º 19
0
        public void BuildIntervals(DerivedGraph derGraph)
        {
            if (derGraph == null)
            {
                throw new ArgumentNullException("derGraph");
            }
            if (derGraph.Entry == null)
            {
                throw new ArgumentException("cfg graph must be non-null.", "derGraph");
            }

            var intSeq    = derGraph.Intervals;             // The sequence of intervals in this graph
            var headerSeq = new WorkList <StructureNode>(); // The sequence of interval header nodes
            var beenInH   = new List <StructureNode>();     // The set of nodes that have been in the above sequence at some stage

            headerSeq.Add(derGraph.Entry);

            beenInH.Add(derGraph.Entry);

            StructureNode header;

            while (headerSeq.GetWorkItem(out header))
            {
                var newInt = new Interval(intervalID++, header);

                // Process each succesive node in the interval until no more nodes can be added to the interval.
                for (int i = 0; i < newInt.Nodes.Count; i++)
                {
                    var curNode = newInt.Nodes[i];

                    // Process each child of the current node
                    for (int j = 0; j < curNode.OutEdges.Count; j++)
                    {
                        var succ = curNode.OutEdges[j];

                        // Only further consider the current child if it isn't already in the interval
                        if (!newInt.Nodes.Contains(succ))
                        {
                            // If the current child has all its parents
                            // inside the interval, then add it to the interval. Remove it from the header
                            // sequence if it is on it.
                            if (IsSubSetOf(succ.InEdges, newInt))
                            {
                                newInt.AddNode(succ);
                                headerSeq.Remove(succ);
                            }

                            // Otherwise, add it to the header sequence if it hasn't already been in it.
                            else if (!beenInH.Contains(succ))
                            {
                                headerSeq.Add(succ);
                                beenInH.Add(succ);
                            }
                        }
                    }
                }

                // Add the new interval to the sequence of intervals
                intSeq.Add(newInt);
            }
        }