Beispiel #1
0
        private IEnumerable <APC> ComputeSubroutinePreContinuation(APC point)
        {
            Edge <CFGBlock, EdgeTag>             edge = point.SubroutineContext.Head;
            LispList <Edge <CFGBlock, EdgeTag> > tail = point.SubroutineContext.Tail;

            bool isHandlerEdge;
            LispList <Pair <EdgeTag, Subroutine> > diffs = EdgeSubroutinesOuterToInner(edge.From, edge.To, out isHandlerEdge, tail);

            while (diffs.Head.Value != this)
            {
                diffs = diffs.Tail;
            }

            if (diffs.Tail == null)
            {
                if (isHandlerEdge)
                {
                    for (int i = 0; i < edge.From.Count; i++)
                    {
                        yield return(new APC(edge.From, i, tail));
                    }
                }
                else
                {
                    yield return(APC.ForEnd(edge.From, tail));
                }
            }
            else
            {
                Pair <EdgeTag, Subroutine> first = diffs.Tail.Head;
                Subroutine nextSubroutine        = first.Value;
                yield return(APC.ForEnd(nextSubroutine.Exit, point.SubroutineContext.Cons(new Edge <CFGBlock, EdgeTag> (edge.From, edge.To, first.Key))));
            }
        }
Beispiel #2
0
        public override IEnumerable <APC> Predecessors(APC pc)
        {
            if (pc.Index > 0)
            {
                yield return(new APC(pc.Block, pc.Index - 1, pc.SubroutineContext));
            }

            else if (IsSubroutineStart(pc.Block))
            {
                if (!pc.SubroutineContext.IsEmpty())
                {
                    foreach (APC apc in ComputeSubroutinePreContinuation(pc))
                    {
                        yield return(apc);
                    }
                }
            }
            else
            {
                foreach (CFGBlock block in pc.Block.Subroutine.PredecessorBlocks(pc.Block))
                {
                    LispList <Pair <EdgeTag, Subroutine> > diffs = EdgeSubroutinesOuterToInner(block, pc.Block, pc.SubroutineContext);
                    if (diffs.IsEmpty())
                    {
                        yield return(APC.ForEnd(block, pc.SubroutineContext));
                    }
                    else
                    {
                        Subroutine sub  = diffs.Head.Value;
                        var        edge = new Edge <CFGBlock, EdgeTag> (block, pc.Block, diffs.Head.Key);
                        yield return(APC.ForEnd(sub.Exit, pc.SubroutineContext.Cons(edge)));
                    }
                }
            }
        }
Beispiel #3
0
        private APC ComputeSubroutinePreContinuation(APC point, out bool hasSinglePredecessor)
        {
            Edge <CFGBlock, EdgeTag> head = point.SubroutineContext.Head;
            bool isExceptionHandlerEdge;
            LispList <Edge <CFGBlock, EdgeTag> >   tail  = point.SubroutineContext.Tail;
            LispList <Pair <EdgeTag, Subroutine> > flist = EdgeSubroutinesOuterToInner(head.From, head.To, out isExceptionHandlerEdge, tail);

            while (flist.Head.Value != this)
            {
                flist = flist.Tail;
            }
            if (flist.Tail.IsEmpty())
            {
                if (isExceptionHandlerEdge && head.From.Count > 1)
                {
                    hasSinglePredecessor = false;
                    return(APC.Dummy);
                }

                hasSinglePredecessor = true;
                return(APC.ForEnd(head.From, tail));
            }
            Pair <EdgeTag, Subroutine> first = flist.Tail.Head;
            Subroutine sub = first.Value;

            hasSinglePredecessor = true;

            return(APC.ForEnd(sub.Exit, point.SubroutineContext.Cons(new Edge <CFGBlock, EdgeTag> (head.From, head.To, first.Key))));
        }
Beispiel #4
0
        public override bool HasSinglePredecessor(APC point, out APC ifFound)
        {
            if (point.Index > 0)
            {
                ifFound = new APC(point.Block, point.Index - 1, point.SubroutineContext);
                return(true);
            }

            if (IsSubroutineStart(point.Block))
            {
                if (point.SubroutineContext == null)
                {
                    ifFound = APC.Dummy;
                    return(false);
                }

                bool hasSinglePredecessor;
                ifFound = ComputeSubroutinePreContinuation(point, out hasSinglePredecessor);
                return(hasSinglePredecessor);
            }


            CFGBlock onlyOne = null;

            foreach (CFGBlock predecessor in point.Block.Subroutine.PredecessorBlocks(point.Block))
            {
                if (onlyOne != null)
                {
                    ifFound = APC.Dummy;
                    return(false);
                }
                onlyOne = predecessor;
            }
            if (onlyOne == null)
            {
                ifFound = APC.Dummy;
                return(false);
            }

            LispList <Pair <EdgeTag, Subroutine> > list = EdgeSubroutinesOuterToInner(onlyOne, point.Block, point.SubroutineContext);

            if (list.IsEmpty())
            {
                ifFound = APC.ForEnd(onlyOne, point.SubroutineContext);
                return(true);
            }

            var        edge = new Edge <CFGBlock, EdgeTag> (onlyOne, point.Block, list.Head.Key);
            Subroutine sub  = list.Head.Value;

            ifFound = APC.ForEnd(sub.Exit, point.SubroutineContext.Cons(edge));
            return(true);
        }
Beispiel #5
0
        public int GlobalStackDepth(APC pc)
        {
            int num = LocalStackDepth(pc);

            if (pc.SubroutineContext == null || !pc.Block.Subroutine.HasContextDependentStackDepth)
            {
                return(num);
            }

            CFGBlock block = pc.SubroutineContext.Head.From;

            return(num + GlobalStackDepth(APC.ForEnd(block, pc.SubroutineContext.Tail)));
        }