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