Пример #1
0
        private static Graph <MoverProc> ConstructMoverProcedureCallGraph(CivlTypeChecker civlTypeChecker)
        {
            var moverProcedureCallGraph = new Graph <MoverProc>();

            foreach (var impl in civlTypeChecker.program.Implementations.Where(impl =>
                                                                               civlTypeChecker.procToYieldingProc.ContainsKey(impl.Proc)))
            {
                MoverProc callerProc = civlTypeChecker.procToYieldingProc[impl.Proc] as MoverProc;
                if (callerProc == null)
                {
                    continue;
                }

                foreach (var callCmd in impl.Blocks.SelectMany(b => b.Cmds).OfType <CallCmd>())
                {
                    if (civlTypeChecker.procToYieldingProc.ContainsKey(callCmd.Proc))
                    {
                        MoverProc calleeProc = civlTypeChecker.procToYieldingProc[callCmd.Proc] as MoverProc;
                        if (calleeProc == null)
                        {
                            continue;
                        }

                        Debug.Assert(callerProc.upperLayer == calleeProc.upperLayer);
                        moverProcedureCallGraph.AddEdge(callerProc, calleeProc);
                    }
                }
            }

            return(moverProcedureCallGraph);
        }
Пример #2
0
            private bool IsRecursiveMoverProcedureCall(CallCmd call)
            {
                MoverProc source = null;

                if (civlTypeChecker.procToYieldingProc.ContainsKey(call.Proc))
                {
                    source = civlTypeChecker.procToYieldingProc[call.Proc] as MoverProc;
                }
                if (source == null)
                {
                    return(false);
                }

                MoverProc target = (MoverProc)yieldingProc;

                HashSet <MoverProc> frontier = new HashSet <MoverProc> {
                    source
                };
                HashSet <MoverProc> visited = new HashSet <MoverProc>();

                while (frontier.Count > 0)
                {
                    var curr = frontier.First();
                    frontier.Remove(curr);
                    visited.Add(curr);

                    if (curr == target)
                    {
                        return(true);
                    }
                    frontier.UnionWith(moverProcedureCallGraph.Successors(curr).Except(visited));
                }

                return(false);
            }
Пример #3
0
        public void TypeCheck()
        {
            // Mover procedures can only call other mover procedures on the same layer.
            // Thus, the constructed call graph naturally forms disconnected components w.r.t. layers and we
            // can keep a single graph instead of one for each layer;
            foreach (var impl in civlTypeChecker.program.Implementations.Where(impl =>
                                                                               civlTypeChecker.procToYieldingProc.ContainsKey(impl.Proc)))
            {
                MoverProc callerProc = civlTypeChecker.procToYieldingProc[impl.Proc] as MoverProc;
                if (callerProc == null)
                {
                    continue;
                }

                foreach (var callCmd in impl.Blocks.SelectMany(b => b.Cmds).OfType <CallCmd>())
                {
                    if (civlTypeChecker.procToYieldingProc.ContainsKey(callCmd.Proc))
                    {
                        MoverProc calleeProc = civlTypeChecker.procToYieldingProc[callCmd.Proc] as MoverProc;
                        if (calleeProc == null)
                        {
                            continue;
                        }

                        Debug.Assert(callerProc.upperLayer == calleeProc.upperLayer);
                        moverProcedureCallGraph.AddEdge(callerProc, calleeProc);
                    }
                }
            }

            foreach (var impl in civlTypeChecker.program.Implementations.Where(impl =>
                                                                               civlTypeChecker.procToYieldingProc.ContainsKey(impl.Proc)))
            {
                var yieldingProc = civlTypeChecker.procToYieldingProc[impl.Proc];

                impl.PruneUnreachableBlocks();
                Graph <Block> implGraph = Program.GraphFromImpl(impl);
                implGraph.ComputeLoops();

                foreach (int layerNum in civlTypeChecker.allRefinementLayers.Where(l => l <= yieldingProc.upperLayer))
                {
                    PerLayerYieldSufficiencyTypeChecker perLayerSufficiencyTypeChecker =
                        new PerLayerYieldSufficiencyTypeChecker(this, yieldingProc, impl, layerNum, implGraph);
                    perLayerSufficiencyTypeChecker.TypeCheckLayer();
                }
            }

            // To allow garbage collection
            moverProcedureCallGraph = null;
        }