Example #1
0
        //
        //  proc ResolveFinalNodeRefs()
        //      foreach graphnode in graphnodeList
        //          def firstproc = graphnode.firstproc
        //          // Auto-generate the updateNodeRefs for this graphnode given the 
        //          // list stored in the first procedure found in the assignment expression
        //          foreach noderef in firstProc.updatedProperties	
        //              def n = graphnode.firstProcRefIndex
        //              def autogenRef = updateNodeRef[n]
        //              autogenRef.append(noderef)
        //              graphnode.pushUpdateRef(autogenRef)
        //          end
        //      end
        //  end
        //
        private void ResolveFinalNodeRefs()
        {
            foreach (ProtoCore.AssociativeGraph.GraphNode graphNode in codeBlock.instrStream.dependencyGraph.GraphList)
            {
                ProtoCore.DSASM.ProcedureNode firstProc = graphNode.firstProc;
                if (null == firstProc || firstProc.IsAutoGenerated)
                {
                    continue;
                }

                // TODO: The following implementation is wrong.
                // Suppose for function call: x = foo().bar(); which converted
                // to x = %dot(foo(), bar(), ...); the following checking skips
                // it because %dot() is an internal function. -Yu Ke

                // Do this only for non auto-generated function calls 
                //if any local var is depend on global var
                if (core.Options.localDependsOnGlobalSet)
                {
                    if (!firstProc.Name.ToCharArray()[0].Equals('_') && !firstProc.Name.ToCharArray()[0].Equals('%'))
                    {
                        //for each node
                        foreach (ProtoCore.AssociativeGraph.GraphNode gNode in codeBlock.instrStream.dependencyGraph.GraphList)
                        {
                            if (gNode.updateNodeRefList != null && gNode.updateNodeRefList.Count != 0)
                            {
                                if (gNode.procIndex == firstProc.ID && !gNode.updateNodeRefList[0].nodeList[0].symbol.name.ToCharArray()[0].Equals('%'))
                                {
                                    foreach (ProtoCore.AssociativeGraph.GraphNode dNode in gNode.dependentList)
                                    {
                                        if (dNode.procIndex == ProtoCore.DSASM.Constants.kGlobalScope)
                                        {
                                            if (!dNode.updateNodeRefList[0].nodeList[0].symbol.name.ToCharArray()[0].Equals('%'))
                                            {
                                                graphNode.PushDependent(dNode);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                if (firstProc.ClassID == Constants.kGlobalScope)
                {
                    graphNode.updateNodeRefList.AddRange(firstProc.UpdatedGlobalVariables);
                }
                else
                {
                    // For each property modified
                    foreach (ProtoCore.AssociativeGraph.UpdateNodeRef updateRef in firstProc.UpdatedProperties)
                    {
                        int index = graphNode.firstProcRefIndex;

                        // Is it a global function
                        if (ProtoCore.DSASM.Constants.kInvalidIndex != index)
                        {
                            if (core.Options.GenerateSSA)
                            {
                                foreach (ProtoCore.AssociativeGraph.GraphNode dependent in graphNode.dependentList)
                                {
                                    // Do this only if first proc is a member function...
                                    ProtoCore.AssociativeGraph.UpdateNodeRef autogenRef = new ProtoCore.AssociativeGraph.UpdateNodeRef(dependent.updateNodeRefList[0]);
                                    autogenRef = autogenRef.GetUntilFirstProc();

                                    // ... and the first symbol is an instance of a user-defined type
                                    int last = autogenRef.nodeList.Count - 1;
                                    Validity.Assert(autogenRef.nodeList[last].nodeType != ProtoCore.AssociativeGraph.UpdateNodeType.kMethod && null != autogenRef.nodeList[last].symbol);
                                    if (autogenRef.nodeList[last].symbol.datatype.UID >= (int)PrimitiveType.kMaxPrimitives)
                                    {
                                        autogenRef.PushUpdateNodeRef(updateRef);
                                        graphNode.updateNodeRefList.Add(autogenRef);

                                        if (graphNode.lastGraphNode != null)
                                        {
                                            graphNode.lastGraphNode.updateNodeRefList.Add(autogenRef);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                // Do this only if first proc is a member function...
                                ProtoCore.AssociativeGraph.UpdateNodeRef autogenRef = new ProtoCore.AssociativeGraph.UpdateNodeRef(graphNode.dependentList[0].updateNodeRefList[0]);
                                autogenRef = autogenRef.GetUntilFirstProc();

                                // ... and the first symbol is an instance of a user-defined type
                                int last = autogenRef.nodeList.Count - 1;
                                Validity.Assert(autogenRef.nodeList[last].nodeType != ProtoCore.AssociativeGraph.UpdateNodeType.kMethod && null != autogenRef.nodeList[last].symbol);
                                if (autogenRef.nodeList[last].symbol.datatype.UID >= (int)PrimitiveType.kMaxPrimitives)
                                {
                                    autogenRef.PushUpdateNodeRef(updateRef);
                                    graphNode.updateNodeRefList.Add(autogenRef);
                                }
                            }
                        }
                    }
                }

                if (graphNode.updatedArguments.Count > 0)
                {
                    // For each argument modified
                    int n = 0;

                    // Create the current modified argument
                    foreach (KeyValuePair<string, List<ProtoCore.AssociativeGraph.UpdateNodeRef>> argNameModifiedStatementsPair in firstProc.UpdatedArgumentProperties)
                    {
                        // For every single arguments' modified statements
                        foreach (ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef in argNameModifiedStatementsPair.Value)
                        {
                            if (core.Options.GenerateSSA)
                            {
                                //
                                // We just trigger update from whichever statement is dependent on the first pointer associatied with this SSA stmt
                                // Given:
                                //      p = C.C();
                                //      a = p.x;
                                //      i = f(p);
                                //
                                //      %t0 = C.C()
                                //      p = %t0
                                //      %t1 = p
                                //      %t2 = %t1.x
                                //      a = %t2
                                //      %t3 = p
                                //      %t4 = f(%t3)    -> Assume that function 'f' modifies the property 'x' of its argument
                                //                      -> The graph node of this stmt has 2 updatenoderefs 
                                //                      ->  there are %t4 and p ('p' because it is the first pointer of %t3
                                //      i = %t4
                                //
                                
                                // Get the modified property name 
                                string argname = graphNode.updatedArguments[n].nodeList[0].symbol.name;
                                if (ProtoCore.Utils.CoreUtils.IsSSATemp(argname) && ssaTempToFirstPointerMap.ContainsKey(argname))
                                {
                                    // The property is an SSA temp, Get the SSA first pointer associated with this temp
                                    argname = ssaTempToFirstPointerMap[argname];
                                }

                                bool isAccessible = false;
                                SymbolNode symbol = null;
                                bool isAllocated = VerifyAllocation(argname, globalClassIndex, globalProcIndex, out symbol, out isAccessible);
                                if (isAllocated)
                                {
                                    ProtoCore.AssociativeGraph.UpdateNode updateNode = new UpdateNode();
                                    updateNode.symbol = symbol;
                                    updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol;

                                    ProtoCore.AssociativeGraph.UpdateNodeRef argNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
                                    argNodeRef.PushUpdateNode(updateNode);
                                    graphNode.updateNodeRefList.Add(argNodeRef);
                                }
                                
                            }
                            else
                            {
                                ProtoCore.AssociativeGraph.UpdateNodeRef argNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
                                argNodeRef.PushUpdateNodeRef(graphNode.updatedArguments[n]);
                                argNodeRef.PushUpdateNodeRef(nodeRef);
                                graphNode.updateNodeRefList.Add(argNodeRef);
                            }
                        }
                        ++n;
                    }
                }
            }
        }
Example #2
0
        //
        //  proc ResolveFinalNodeRefs()
        //      foreach graphnode in graphnodeList
        //          def firstproc = graphnode.firstproc
        //          // Auto-generate the updateNodeRefs for this graphnode given the
        //          // list stored in the first procedure found in the assignment expression
        //          foreach noderef in firstProc.updatedProperties
        //              def n = graphnode.firstProcRefIndex
        //              def autogenRef = updateNodeRef[n]
        //              autogenRef.append(noderef)
        //              graphnode.pushUpdateRef(autogenRef)
        //          end
        //      end
        //  end
        //
        private void ResolveFinalNodeRefs()
        {
            foreach (ProtoCore.AssociativeGraph.GraphNode graphNode in codeBlock.instrStream.dependencyGraph.GraphList)
            {
                ProtoCore.DSASM.ProcedureNode firstProc = graphNode.firstProc;
                if (null == firstProc || firstProc.isAutoGenerated)
                {
                    continue;
                }

                // TODO: The following implementation is wrong.
                // Suppose for function call: x = foo().bar(); which converted
                // to x = %dot(foo(), bar(), ...); the following checking skips
                // it because %dot() is an internal function. -Yu Ke

                // Do this only for non auto-generated function calls
                //if any local var is depend on global var
                if (compileStateTracker.Options.localDependsOnGlobalSet)
                {
                    if (!firstProc.name.ToCharArray()[0].Equals('_') && !firstProc.name.ToCharArray()[0].Equals('%'))
                    {
                        //for each node
                        foreach (ProtoCore.AssociativeGraph.GraphNode gNode in codeBlock.instrStream.dependencyGraph.GraphList)
                        {
                            if (gNode.updateNodeRefList != null && gNode.updateNodeRefList.Count != 0)
                            {
                                if (gNode.procIndex == firstProc.procId && !gNode.updateNodeRefList[0].nodeList[0].symbol.name.ToCharArray()[0].Equals('%'))
                                {
                                    foreach (ProtoCore.AssociativeGraph.GraphNode dNode in gNode.dependentList)
                                    {
                                        if (dNode.procIndex == ProtoCore.DSASM.Constants.kGlobalScope)
                                        {
                                            if (!dNode.updateNodeRefList[0].nodeList[0].symbol.name.ToCharArray()[0].Equals('%'))
                                            {
                                                graphNode.PushDependent(dNode);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                // For each property modified
                foreach (ProtoCore.AssociativeGraph.UpdateNodeRef updateRef in firstProc.updatedProperties)
                {
                    int index = graphNode.firstProcRefIndex;

                    // Is it a global function
                    if (ProtoCore.DSASM.Constants.kGlobalScope == firstProc.classScope)
                    {
                        graphNode.updateNodeRefList.AddRange(firstProc.updatedGlobals);
                    }
                    else if (ProtoCore.DSASM.Constants.kInvalidIndex != index && ProtoCore.DSASM.Constants.kGlobalScope != firstProc.classScope)
                    {
                        foreach (ProtoCore.AssociativeGraph.GraphNode dependent in graphNode.dependentList)
                        {
                            // Do this only if first proc is a member function...
                            ProtoCore.AssociativeGraph.UpdateNodeRef autogenRef = new ProtoCore.AssociativeGraph.UpdateNodeRef(dependent.updateNodeRefList[0]);
                            autogenRef = autogenRef.GetUntilFirstProc();

                            // ... and the first symbol is an instance of a user-defined type
                            int last = autogenRef.nodeList.Count - 1;
                            Validity.Assert(autogenRef.nodeList[last].nodeType != ProtoCore.AssociativeGraph.UpdateNodeType.kMethod && null != autogenRef.nodeList[last].symbol);
                            if (autogenRef.nodeList[last].symbol.datatype.UID >= (int)PrimitiveType.kMaxPrimitives)
                            {
                                autogenRef.PushUpdateNodeRef(updateRef);
                                graphNode.updateNodeRefList.Add(autogenRef);
                            }
                        }
                    }
                }

                if (graphNode.updatedArguments.Count > 0)
                {
                    // For each argument modified
                    int n = 0;

                    // Create the current modified argument
                    foreach (KeyValuePair<string, List<ProtoCore.AssociativeGraph.UpdateNodeRef>> argNameModifiedStatementsPair in firstProc.updatedArgumentProperties)
                    {
                        // For every single arguments' modified statements
                        foreach (ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef in argNameModifiedStatementsPair.Value)
                        {
                            ProtoCore.AssociativeGraph.UpdateNodeRef argNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
                            argNodeRef.PushUpdateNodeRef(graphNode.updatedArguments[n]);
                            argNodeRef.PushUpdateNodeRef(nodeRef);
                            graphNode.updateNodeRefList.Add(argNodeRef);
                        }
                        ++n;
                    }
                }
            }
        }