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)))); } }
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))); } } } }
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)))); }
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); }
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))); }