/// <summary> /// Merges two instances based on the stronger of both variabilities and the set union of their reaching definitions /// </summary> /// <param name="a">first instance</param> /// <param name="b">second instance</param> /// <returns>instance representing the merged information of both instances</returns> public static VariabilityInfo MergeDefs(VariabilityInfo a, VariabilityInfo b) { Contract.Requires(a.Definitions != null); Contract.Requires(b.Definitions != null); return(new VariabilityInfo( VariabilityOperations.Stronger(a.Variability, b.Variability), a.Definitions.Union(b.Definitions).Distinct().ToArray())); }
private AbstractStackState <VariabilityInfo> HandleBinBranch(ILInstruction ili, AbstractStackState <VariabilityInfo> pre) { VariabilityInfo a = pre[0]; VariabilityInfo b = pre[1]; var next = pre.Pop().Pop(); if (VariabilityOperations.Stronger(a.Variability, b.Variability) == EVariability.Constant) { next = next.UniqueSuccessor(); } else { next = next.AmbiguousSuccessor(); } return(next); }
private AbstractStackState <VariabilityInfo> HandleCall(ILInstruction ili, AbstractStackState <VariabilityInfo> pre, bool isCalli) { MethodBase callee = (MethodBase)ili.Operand; bool hasThis = callee.CallingConvention.HasFlag(CallingConventions.HasThis); EVariability callVar = EVariability.Constant; ParameterInfo[] args = callee.GetParameters(); MethodFacts myFacts = FactUniverse.Instance.GetFacts(Method); MethodFacts calleeFacts = FactUniverse.Instance.GetFacts(callee); AbstractStackState <VariabilityInfo> next = pre; if (hasThis) { callVar = VariabilityOperations.Stronger(callVar, pre[0].Variability); next = pre.Pop(); } for (int i = 0; i < args.Length; i++) { callVar = VariabilityOperations.Stronger(callVar, next[0].Variability); next = next.Pop(); } if (!calleeFacts.IsSideEffectFree) { callVar = EVariability.ExternVariable; } if (calleeFacts.IsStaticEvaluation) { callVar = EVariability.Constant; } if (isCalli) { next = pre.Pop(); } VariabilityInfo callVarI = VariabilityInfo.CreateBySingleDef(callVar, ili.Index); next = UpdateStackState(ili, callVarI, next); Type returnType; if (callee.IsFunction(out returnType)) { next = next.Push(callVarI); } return(next.UniqueSuccessor()); }
/// <summary> /// Merges two instances under assumption of a single reaching definition /// </summary> /// <param name="a">first instance</param> /// <param name="b">second instance</param> /// <param name="def">the one and only reaching definition</param> /// <returns>merged instance, based on the stronger of both variabilities</returns> public static VariabilityInfo MergeByNewDef(VariabilityInfo a, VariabilityInfo b, int def) { return(CreateBySingleDef( VariabilityOperations.Stronger(a.Variability, b.Variability), def)); }