public void AssumeEqual(ISymValue v1, ISymValue v2) { WorkList wl = new WorkList(); SymbolicValue v1rep = Find(v1); SymbolicValue v2rep = Find(v2); PushEquality(wl, v1rep, v2rep); if (!wl.IsEmpty()) { // TODO: there's an opportunity for optimizing the number // of necessary updates that we need to record, since the induced // updates of the equality may end up as duplicates. AddEqualityUpdate(v1rep, v2rep); } DrainEqualityWorkList(wl); }
private void DrainEqualityWorkList(WorkList wl) { while (!wl.IsEmpty()) { EqPair eqpair = (EqPair)wl.Pull(); SymbolicValue v1rep = Find(eqpair.v1); SymbolicValue v2rep = Find(eqpair.v2); if (v1rep == v2rep) { continue; } // always map new to older var if (v1rep.UniqueId < v2rep.UniqueId) { SymbolicValue temp = v1rep; v1rep = v2rep; v2rep = temp; } // perform congruence closure here: foreach (IUniqueKey f in this.Functions(v1rep)) { SymbolicValue target = this.LookupWithoutManifesting(v2rep, f); if (target == null) { this[v2rep, f] = this[v1rep, f]; } else { PushEquality(wl, this[v1rep, f], target); } } MathematicalLattice.Element av1 = this[v1rep]; MathematicalLattice.Element av2 = this[v2rep]; // merge term map of v1 into v2 foreach (IUniqueKey eterm in this.eqTermMap.Keys2(v1rep)) { this.eqTermMap = this.eqTermMap.Add(v2rep, eterm, null); } this.forwMap = this.forwMap.Add(v1rep, v2rep); this[v2rep] = this.elementLattice.Meet(av1, av2); } }
public void Dump(TextWriter tw) { HashSet seen = new HashSet(); WorkList wl = new WorkList(); Console.WriteLine("LastSymbolId:{0}", this.idCounter); foreach (IUniqueKey function in this.termMap.Keys2(this.constRoot)) { SymbolicValue target = this[this.constRoot, function]; tw.WriteLine("{0} = {1}", Function2String(function), target); wl.Add(target); } while (!wl.IsEmpty()) { SymbolicValue v = (SymbolicValue)wl.Pull(); if (!seen.Add(v)) { continue; } foreach (IUniqueKey function in this.termMap.Keys2(v)) { SymbolicValue target = this[v, function]; tw.WriteLine("{0}({2}) = {1}", Function2String(function), target, v); wl.Add(target); } } tw.WriteLine("**Abstract value map"); foreach (SymbolicValue v in seen) { AbstractValue aval = this[v]; if (!this.elementLattice.IsTop(aval)) { tw.WriteLine("{0} -> {1}", v, aval); } } }
private void DrainEqualityWorkList(WorkList <EqualityPair <TFunc, TADomain> > workList) { while (!workList.IsEmpty()) { EqualityPair <TFunc, TADomain> equalityPair = workList.Pull(); SymValue sv1 = Find(equalityPair.Sv1); SymValue sv2 = Find(equalityPair.Sv2); if (sv1 != sv2) { if (sv1.UniqueId < sv2.UniqueId) { SymValue tmp = sv1; sv1 = sv2; sv2 = tmp; } foreach (TFunc function in Functions(sv1)) { SymValue v2 = LookupWithoutManifesting(sv2, function); if (v2 == null) { this [sv2, function] = this [sv1, function]; } else { TryPushEquality(workList, this [sv1, function], v2); } } TADomain thisValue = this [sv1]; TADomain thatValue = this [sv2]; foreach (var elem in EqualTermsMap[sv1].AsEnumerable()) { EqualTermsMap = EqualTermsMap.Add(sv2, EqualTermsMap [sv2].Cons(elem)); } this.forw_map = this.forw_map.Add(sv1, sv2); this [sv2] = thisValue.Meet(thatValue); } } }
/// <summary> /// Must follow field edges of value types backwards as well /// </summary> public Variable GetLocalMappingToLoc(ISymValue loc) { WorkList refparams = new WorkList(); WorkList fields = new WorkList(); fields.Add(loc); while (! fields.IsEmpty()) { ISymValue sv = (ISymValue)fields.Pull(); foreach (EGraphTerm eterm in egraph.EqTerms(sv)) { if ( !(eterm.Function is StackVariable)) { Variable v = eterm.Function as Variable; if (v != null) { return v; } Field f = eterm.Function as Field; if (f != null && f.DeclaringType.IsValueType) { if (eterm.Args.Length>0) { fields.Add(eterm.Args[0]); } } if (eterm.Function == ValueOf && eterm.Args.Length>0) { // could be that we are looking at a ref parameter refparams.Add(eterm.Args[0]); } } } } while (! refparams.IsEmpty()) { ISymValue sv = (ISymValue)refparams.Pull(); foreach (EGraphTerm eterm in egraph.EqTerms(sv)) { if ( !(eterm.Function is StackVariable)) { Variable v = eterm.Function as Variable; if (v != null && (v.Type is Reference || v.Type is Pointer)) { return v; } } } } return null; }
private static bool InternalLessEqual(SymGraph <TFunc, TADomain> thisG, SymGraph <TFunc, TADomain> thatG, out IImmutableMap <SymValue, Sequence <SymValue> > forward, out IImmutableMap <SymValue, SymValue> backward) { int updateSize; SymGraph <TFunc, TADomain> commonTail = ComputeCommonTail(thisG, thatG, out updateSize); if (thisG.IsImmutable) { thisG = thisG.Clone(); } var workList = new WorkList <EqualityPair <TFunc, TADomain> > (); workList.Add(new EqualityPair <TFunc, TADomain> (thisG.const_root, thatG.const_root)); IImmutableSet <SymValue> backwardManifested = ImmutableSet <SymValue> .Empty(SymValue.GetUniqueKey); IImmutableMap <SymValue, SymValue> backwardMap = ImmutableIntKeyMap <SymValue, SymValue> .Empty(SymValue.GetUniqueKey); IImmutableMap <SymValue, Sequence <SymValue> > forwardMap = ImmutableIntKeyMap <SymValue, Sequence <SymValue> > .Empty(SymValue.GetUniqueKey); IImmutableMap <SymValue, int> triggers = ImmutableIntKeyMap <SymValue, int> .Empty(SymValue.GetUniqueKey); while (!workList.IsEmpty()) { EqualityPair <TFunc, TADomain> equalityPair = workList.Pull(); SymValue sv1 = equalityPair.Sv1; SymValue sv2 = equalityPair.Sv2; SymValue s; if (VisitedBefore(sv2, backwardManifested, backwardMap, out s)) { if (s != null && s == sv1) { continue; } if (DebugOptions.Debug) { Console.WriteLine("---LessEqual fails due to pre-existing relation: {0} <- {1}", s, sv2); } forward = null; backward = null; return(false); } TADomain val1 = sv1 == null?thisG.UnderlyingTopValue.ForManifestedField() : thisG [sv1]; TADomain val2 = thatG [sv2]; if (!val1.LessEqual(val2)) { if (DebugOptions.Debug) { Console.WriteLine("---LessEqual fails due to abstract values: !({0} <= {1})", val1, val2); } forward = null; backward = null; return(false); } if (sv1 != null) { backwardMap = backwardMap.Add(sv2, sv1); forwardMap = forwardMap.Add(sv1, forwardMap [sv1].Cons(sv2)); } else { backwardManifested = backwardManifested.Add(sv2); } if (thisG.HasAllBottomFields(sv1)) { continue; } if (thatG.HasAllBottomFields(sv2)) { if (DebugOptions.Debug) { Console.WriteLine("---LessEqual fails due to bottom field difference"); } forward = null; backward = null; return(false); } foreach (TFunc function in thatG.Functions(sv2)) { SymValue v1 = thisG [function, sv1]; SymValue v2 = thatG [function, sv2]; if (DebugOptions.Debug) { Console.WriteLine(" {0}-{1}->{2} <=? {3}-{4}->{5}", sv1, function, v1, sv2, function, v2); } workList.Add(new EqualityPair <TFunc, TADomain> (v1, v2)); } foreach (var e in thatG.MultiEdges(sv2)) { foreach (SymValue sv in thatG.MultiEdgeMap[sv2, e].AsEnumerable()) { if (!UpdateTrigger(sv, e, ref triggers)) { continue; } SymGraphTerm <TFunc> term = thatG.EqualMultiTermsMap [sv]; var args = new SymValue[term.Args.Length]; for (int i = 0; i < args.Length; i++) { args [i] = backwardMap [term.Args [i]]; } SymValue v1 = thisG.LookupWithoutManifesting(args, e.Function); if (v1 == null) { if (DebugOptions.Debug) { Console.WriteLine("---LessEqual fails due to missing multi term {0}({1})", e.Function, string.Join(", ", term.Args.Select(it => it.ToString()))); } forward = null; backward = null; return(false); } workList.Add(new EqualityPair <TFunc, TADomain> (v1, sv)); } } } forward = forwardMap; backward = CompleteWithCommon(backwardMap, thisG, commonTail.IdGenerator); return(true); }
public void Dump(TextWriter tw) { var set = new HashSet <SymValue> (); var workList = new WorkList <SymValue> (); IImmutableMap <SymValue, int> triggers = ImmutableIntKeyMap <SymValue, int> .Empty(SymValue.GetUniqueKey); tw.WriteLine("EGraphId: {0}", this.egraph_id); tw.WriteLine("LastSymbolId: {0}", LastSymbolId); foreach (TFunc function in TermMap.Keys2(this.const_root)) { SymValue sv = this [this.const_root, function]; tw.WriteLine("{0} = {1}", function, sv); workList.Add(sv); } while (!workList.IsEmpty()) { SymValue sv = workList.Pull(); if (!set.Add(sv)) { continue; } foreach (TFunc function in TermMap.Keys2(sv)) { SymValue target = this [sv, function]; tw.WriteLine("{0}({2}) = {1})", function, target, sv); workList.Add(target); } foreach (var edge in MultiEdgeMap.Keys2(sv)) { foreach (SymValue target in MultiEdgeMap[sv, edge].AsEnumerable()) { if (!UpdateTrigger(target, edge, ref triggers)) { continue; } SymGraphTerm <TFunc> term = EqualMultiTermsMap [target]; if (term.Args != null) { tw.WriteLine("{0}({1}) = {2}", term.Function, term.Args.ToString(", "), target); workList.Add(target); } } } } tw.WriteLine("**Abstract value map"); foreach (SymValue sv in set) { TADomain abstractValue = this [sv]; if (!abstractValue.IsTop) { tw.WriteLine("{0} -> {1}", sv, abstractValue); } } }
private void DrainEqualityWorkList(WorkList wl) { while ( ! wl.IsEmpty() ) { EqPair eqpair = (EqPair)wl.Pull(); SymbolicValue v1rep = Find(eqpair.v1); SymbolicValue v2rep = Find(eqpair.v2); if (v1rep == v2rep) continue; // always map new to older var if (v1rep.UniqueId < v2rep.UniqueId) { SymbolicValue temp = v1rep; v1rep = v2rep; v2rep = temp; } // perform congruence closure here: foreach(IUniqueKey f in this.Functions(v1rep)) { SymbolicValue target = this.LookupWithoutManifesting(v2rep, f); if (target == null) { this[v2rep, f] = this[v1rep,f]; } else { PushEquality(wl, this[v1rep,f], target); } } MathematicalLattice.Element av1 = this[v1rep]; MathematicalLattice.Element av2 = this[v2rep]; // merge term map of v1 into v2 foreach(IUniqueKey eterm in this.eqTermMap.Keys2(v1rep)) { this.eqTermMap = this.eqTermMap.Add(v2rep, eterm, null); } this.forwMap = this.forwMap.Add(v1rep, v2rep); this[v2rep] = this.elementLattice.Meet(av1,av2); } }
public void Dump(TextWriter tw) { HashSet seen = new HashSet(); WorkList wl = new WorkList(); Console.WriteLine("LastSymbolId:{0}", this.idCounter); foreach(IUniqueKey function in this.termMap.Keys2(this.constRoot)) { SymbolicValue target = this[this.constRoot, function]; tw.WriteLine("{0} = {1}", Function2String(function), target); wl.Add(target); } while ( ! wl.IsEmpty() ) { SymbolicValue v = (SymbolicValue)wl.Pull(); if ( ! seen.Add(v)) continue; foreach(IUniqueKey function in this.termMap.Keys2(v)) { SymbolicValue target = this[v, function]; tw.WriteLine("{0}({2}) = {1}", Function2String(function), target, v); wl.Add(target); } } tw.WriteLine("**Abstract value map"); foreach (SymbolicValue v in seen) { AbstractValue aval = this[v]; if (!this.elementLattice.IsTop(aval)) { tw.WriteLine("{0} -> {1}", v, aval); } } }