public Tuple <DependencyPTGDomain, TimeSpan> AnalyzeMoveNextMethod() { AnalysisStats.extraAnalysisOverHead = new Stopwatch(); var sw = new Stopwatch(); sw.Start(); // 0) Analyze static fields. // DIEGODIEGO: Should I also Include the points-to graph??? var staticConstructor = processToAnalyze.ProcessorClass.Methods.SingleOrDefault(m => m.Name.Value == ".cctor"); if (staticConstructor != null) { var cfgcCtor = staticConstructor.DoAnalysisPhases(host, sourceLocationProvider); var rangeAnalysisCctor = new RangeAnalysis(cfgcCtor, staticConstructor); rangeAnalysisCctor.Analyze(); } // The following steps generates a PTG for the MoveNext method that takes into account the context of invocation // This is the Producer entry method and the call to GetEnumerator which then is used in the Movenext method // 1) Analyze the entry method that creates, populates and return the clousure var cfgEntry = processToAnalyze.EntryMethod.DoAnalysisPhases(host, sourceLocationProvider); var pointsToEntry = new SimplePointsToAnalysis(cfgEntry, processToAnalyze.EntryMethod); var entryResult = pointsToEntry.Analyze(); var ptgOfEntry = entryResult[cfgEntry.Exit.Id].Output; // 2) Call the GetEnumerator that may create a new clousure and polulate it var myGetEnumResult = new LocalVariable("$_temp_it", processToAnalyze.EntryMethod) { Type = processToAnalyze.GetIteratorMethod.Type }; ptgOfEntry.Add(myGetEnumResult); var ptgAfterEnum = this.interprocManager.PTAInterProcAnalysis(ptgOfEntry, new List <IVariable> { pointsToEntry.ReturnVariable }, myGetEnumResult, processToAnalyze.GetIteratorMethod); // These are the nodes that we want to protect/analyze var protectedNodes = ptgOfEntry.Nodes.OfType <ParameterNode>() .Where(n => IsScopeType(n.Type)).Select(n => new ProtectedRowNode(n, ProtectedRowNode.GetKind(n.Type))); // Create tables representing the input and output tables this.inputTable = new TraceableTable(protectedNodes.Single(pn => pn.RowKind == ProtectedRowKind.Input)); this.outputTable = new TraceableTable(protectedNodes.Single(pn => pn.RowKind == ProtectedRowKind.Output)); // 3) I bing the current PTG with the parameters of MoveNext method on the clousure // Well... Inlining is broken we we added the Exceptional control graph. Let's avoid it //var cfg = this.moveNextMethod.DoAnalysisPhases(host, this.GetMethodsToInline()); var cfg = this.interprocManager.GetCFG(processToAnalyze.MoveNextMethod); cfg.PropagateExpressions(this.equalities); // In general, the variable to bind is going to be pointsToEntry.ReturnVariable which is aliased with "$_temp_it" (myGetEnumResult) SimplePointsToGraph calleePTG = InterproceduralManager.PTABindCallerCallee(ptgAfterEnum, new List <IVariable> { myGetEnumResult }, processToAnalyze.MoveNextMethod); this.pointsToAnalyzer = new SimplePointsToAnalysis(cfg, processToAnalyze.MoveNextMethod, calleePTG); // Now I analyze the Movenext method with the proper initialization var result = this.AnalyzeScopeMethod(cfg, pointsToAnalyzer, protectedNodes); sw.Stop(); //return Tuple.Create(result, sw.Elapsed - AnalysisStats.extraAnalysisOverHead.Elapsed); return(Tuple.Create(result, sw.Elapsed)); }
public DependencyPTGDomain AnalyzeMoveNextMethod() { // 1) Analyze the entry method that creates, populates and return the clousure var cfgEntry = entryMethod.DoAnalysisPhases(host); var pointsToEntry = new IteratorPointsToAnalysis(cfgEntry, this.entryMethod); // , this.specialFields); var entryResult = pointsToEntry.Analyze(); var ptgOfEntry = entryResult[cfgEntry.Exit.Id].Output; // 2) Call the GetEnumerator that may create a new clousure and polulate it var myGetEnumResult = new LocalVariable("$_temp_it") { Type = getEnumMethod.ReturnType }; ptgOfEntry.Add(myGetEnumResult); var ptgAfterEnum = this.interprocManager.PTAInterProcAnalysis(ptgOfEntry, new List <IVariable> { pointsToEntry.ReturnVariable }, myGetEnumResult, this.getEnumMethod); // These are the nodes that we want to protect/analyze var protectedNodes = ptgOfEntry.Nodes.OfType <ParameterNode>() .Where(n => IsScopeType(n.Type)).Select(n => new ProtectedRowNode(n, ProtectedRowNode.GetKind(n.Type))); // I no longer need this. //var specialFields = cfgEntry.ForwardOrder[1].Instructions.OfType<StoreInstruction>() // .Where(st => st.Result is InstanceFieldAccess).Select(st => new KeyValuePair<string,IVariable>((st.Result as InstanceFieldAccess).FieldName,st.Operand) ); //this.specialFields = specialFields.ToDictionary(item => item.Key, item => item.Value); // 3) I bing the current PTG with the parameters of MoveNext method on the clousure // Well... Inlining is broken we we added the Exceptional control graph. Let's avoid it //var cfg = this.moveNextMethod.DoAnalysisPhases(host, this.GetMethodsToInline()); var cfg = this.interprocManager.GetCFG(this.moveNextMethod); PropagateExpressions(cfg, this.equalities); // In general, the variable to bind is going to be pointsToEntry.ReturnVariable which is aliased with "$_temp_it" (myGetEnumResult) SimplePointsToGraph calleePTG = InterproceduralManager.PTABindCallerCallee(ptgAfterEnum, new List <IVariable> { myGetEnumResult }, this.moveNextMethod); this.pointsToAnalyzer = new IteratorPointsToAnalysis(cfg, this.moveNextMethod, calleePTG); //this.pta= this.interprocManager.PTABindAndRunInterProcAnalysis(ptgAfterEnum, new List<IVariable> { myGetEnumResult }, this.moveNextMethod, cfg); //var pointsTo = new IteratorPointsToAnalysis(cfg, this.moveNextMethod, this.specialFields); //this.ptAnalysisResult = pointsTo.Analyze(); // var pointsTo = new IteratorPointsToAnalysis(cfg, this.moveNextMethod, this.specialFields, ptgOfEntry); // Now I analyze the Movenext method with the proper initialization var result = this.AnalyzeScopeMethod(cfg, pointsToAnalyzer, protectedNodes); return(result); }