Exemplo n.º 1
0
        private static Dictionary <int, HashSet <VarVersionPair> > GetAllVarVersions(VarVersionPair
                                                                                     leftvar, Exprent exprent, SSAUConstructorSparseEx ssau)
        {
            Dictionary <int, HashSet <VarVersionPair> > map = new Dictionary <int, HashSet <VarVersionPair
                                                                                            > >();
            SFormsFastMapDirect mapLiveVars = ssau.GetLiveVarVersionsMap(leftvar);
            List <Exprent>      lst         = exprent.GetAllExprents(true);

            lst.Add(exprent);
            foreach (Exprent expr in lst)
            {
                if (expr.type == Exprent.Exprent_Var)
                {
                    int varindex = ((VarExprent)expr).GetIndex();
                    if (leftvar.var != varindex)
                    {
                        if (mapLiveVars.ContainsKey(varindex))
                        {
                            HashSet <VarVersionPair> verset = new HashSet <VarVersionPair>();
                            foreach (int vers in mapLiveVars.Get(varindex))
                            {
                                verset.Add(new VarVersionPair(varindex, vers));
                            }
                            Sharpen.Collections.Put(map, varindex, verset);
                        }
                        else
                        {
                            throw new Exception("inkonsistent live map!");
                        }
                    }
                    else
                    {
                        Sharpen.Collections.Put(map, varindex, null);
                    }
                }
                else if (expr.type == Exprent.Exprent_Field)
                {
                    if (ssau.GetMapFieldVars().ContainsKey(expr.id))
                    {
                        int?varindex = ssau.GetMapFieldVars().GetOrNullable(expr.id);
                        if (mapLiveVars.ContainsKey(varindex.Value))
                        {
                            HashSet <VarVersionPair> verset = new HashSet <VarVersionPair>();
                            foreach (int vers in mapLiveVars.Get(varindex.Value))
                            {
                                verset.Add(new VarVersionPair(varindex.Value, vers));
                            }
                            Sharpen.Collections.Put(map, varindex.Value, verset);
                        }
                    }
                }
            }
            return(map);
        }
Exemplo n.º 2
0
        private static bool IsVersionToBeReplaced(VarVersionPair usedvar, Dictionary <int
                                                                                      , HashSet <VarVersionPair> > mapVars, SSAUConstructorSparseEx ssau, VarVersionPair
                                                  leftpaar)
        {
            VarVersionsGraph    ssuversions = ssau.GetSsuversions();
            SFormsFastMapDirect mapLiveVars = ssau.GetLiveVarVersionsMap(usedvar);

            if (mapLiveVars == null)
            {
                // dummy version, predecessor of a phi node
                return(false);
            }
            // compare protected ranges
            if (!InterpreterUtil.EqualObjects(ssau.GetMapVersionFirstRange().GetOrNullable(leftpaar
                                                                                           ), ssau.GetMapVersionFirstRange().GetOrNullable(usedvar)))
            {
                return(false);
            }
            foreach (KeyValuePair <int, HashSet <VarVersionPair> > ent in mapVars)
            {
                FastSparseSetFactory <int> .FastSparseSet <int> liveverset = mapLiveVars.Get(ent.Key);
                if (liveverset == null)
                {
                    return(false);
                }
                HashSet <VarVersionNode> domset = new HashSet <VarVersionNode>();
                foreach (VarVersionPair verpaar in ent.Value)
                {
                    domset.Add(ssuversions.nodes.GetWithKey(verpaar));
                }
                bool isdom = false;
                foreach (int livever in liveverset)
                {
                    VarVersionNode node = ssuversions.nodes.GetWithKey(new VarVersionPair(ent.Key, livever
                                                                                          ));
                    if (ssuversions.IsDominatorSet(node, domset))
                    {
                        isdom = true;
                        break;
                    }
                }
                if (!isdom)
                {
                    return(false);
                }
            }
            return(true);
        }
Exemplo n.º 3
0
        private static void ReplaceSingleVar(Exprent parent, VarExprent var, Exprent dest
                                             , SSAUConstructorSparseEx ssau)
        {
            parent.ReplaceExprent(var, dest);
            // live sets
            SFormsFastMapDirect      livemap = ssau.GetLiveVarVersionsMap(new VarVersionPair(var));
            HashSet <VarVersionPair> setVars = GetAllVersions(dest);

            foreach (VarVersionPair varpaar in setVars)
            {
                VarVersionNode node      = ssau.GetSsuversions().nodes.GetWithKey(varpaar);
                var            toRemove  = new List <KeyValuePair <int, FastSparseSetFactory <int> .FastSparseSet <int> > >();
                var            entryList = node.live.EntryList();
                for (var index = 0; index < entryList.Count; index++)
                {
                    var itent = entryList[index];
                    KeyValuePair <int, FastSparseSetFactory <int> .FastSparseSet <int> > ent =
                        entryList.ElementAtOrDefault(index + 1);
                    if (ent.Value == null)
                    {
                        break;
                    }

                    int key = ent.Key;
                    if (!livemap.ContainsKey(key))
                    {
                        toRemove.Add(itent);
                    }
                    else
                    {
                        FastSparseSetFactory <int> .FastSparseSet <int> set = ent.Value;
                        set.Complement(livemap.Get(key));
                        if (set.IsEmpty())
                        {
                            toRemove.Add(itent);
                        }
                    }
                }

                foreach (var keyValuePair in toRemove)
                {
                    node.live.PutInternal(keyValuePair.Key, keyValuePair.Value, true);
                    // entryList.RemoveAll(c => c.Key == keyValuePair.Key);
                }
            }
        }
Exemplo n.º 4
0
 private static bool MapsEqual(SFormsFastMapDirect map1, SFormsFastMapDirect map2)
 {
     if (map1 == null)
     {
         return(map2 == null);
     }
     else if (map2 == null)
     {
         return(false);
     }
     if (map1.Size() != map2.Size())
     {
         return(false);
     }
     foreach (KeyValuePair <int, FastSparseSetFactory <int> .FastSparseSet <int> > ent2 in map2.
              EntryList())
     {
         if (!InterpreterUtil.EqualObjects(map1.Get(ent2.Key), ent2.Value))
         {
             return(false);
         }
     }
     return(true);
 }
Exemplo n.º 5
0
        private SFormsFastMapDirect GetFilteredOutMap(string nodeid, string predid, DirectGraph
                                                      dgraph, string destid)
        {
            SFormsFastMapDirect mapNew = new SFormsFastMapDirect();
            bool isFinallyExit         = dgraph.mapShortRangeFinallyPaths.ContainsKey(predid);

            if (nodeid.Equals(dgraph.mapNegIfBranch.GetOrNull(predid)))
            {
                if (outNegVarVersions.ContainsKey(predid))
                {
                    mapNew = outNegVarVersions.GetOrNull(predid).GetCopy();
                }
            }
            else if (outVarVersions.ContainsKey(predid))
            {
                mapNew = outVarVersions.GetOrNull(predid).GetCopy();
            }
            if (isFinallyExit)
            {
                SFormsFastMapDirect mapNewTemp    = mapNew.GetCopy();
                SFormsFastMapDirect mapTrueSource = new SFormsFastMapDirect();
                string exceptionDest = dgraph.mapFinallyMonitorExceptionPathExits.GetOrNull(predid
                                                                                            );
                bool isExceptionMonitorExit = (exceptionDest != null && !nodeid.Equals(exceptionDest
                                                                                       ));
                HashSet <string> setLongPathWrapper = new HashSet <string>();
                foreach (List <FlattenStatementsHelper.FinallyPathWrapper> lstwrapper in dgraph.mapLongRangeFinallyPaths
                         .Values)
                {
                    foreach (FlattenStatementsHelper.FinallyPathWrapper finwraplong in lstwrapper)
                    {
                        setLongPathWrapper.Add(finwraplong.destination + "##" + finwraplong.source);
                    }
                }
                foreach (FlattenStatementsHelper.FinallyPathWrapper finwrap in dgraph.mapShortRangeFinallyPaths
                         .GetOrNull(predid))
                {
                    SFormsFastMapDirect map;
                    bool recFinally = dgraph.mapShortRangeFinallyPaths.ContainsKey(finwrap.source);
                    if (recFinally)
                    {
                        // recursion
                        map = GetFilteredOutMap(finwrap.entry, finwrap.source, dgraph, destid);
                    }
                    else if (finwrap.entry.Equals(dgraph.mapNegIfBranch.GetOrNull(finwrap.source)))
                    {
                        map = outNegVarVersions.GetOrNull(finwrap.source);
                    }
                    else
                    {
                        map = outVarVersions.GetOrNull(finwrap.source);
                    }
                    // false path?
                    bool isFalsePath;
                    if (recFinally)
                    {
                        isFalsePath = !finwrap.destination.Equals(nodeid);
                    }
                    else
                    {
                        isFalsePath = !setLongPathWrapper.Contains(destid + "##" + finwrap.source);
                    }
                    if (isFalsePath)
                    {
                        mapNewTemp.Complement(map);
                    }
                    else if (mapTrueSource.IsEmpty())
                    {
                        if (map != null)
                        {
                            mapTrueSource = map.GetCopy();
                        }
                    }
                    else
                    {
                        MergeMaps(mapTrueSource, map);
                    }
                }
                if (isExceptionMonitorExit)
                {
                    mapNew = mapTrueSource;
                }
                else
                {
                    mapNewTemp.Union(mapTrueSource);
                    mapNew.Intersection(mapNewTemp);
                    if (!mapTrueSource.IsEmpty() && !mapNew.IsEmpty())
                    {
                        // FIXME: what for??
                        // replace phi versions with corresponding phantom ones
                        Dictionary <VarVersionPair, VarVersionPair> mapPhantom = phantomexitnodes.GetOrNull
                                                                                     (predid);
                        if (mapPhantom == null)
                        {
                            mapPhantom = new Dictionary <VarVersionPair, VarVersionPair>();
                        }
                        SFormsFastMapDirect mapExitVar = mapNew.GetCopy();
                        mapExitVar.Complement(mapTrueSource);
                        foreach (KeyValuePair <int, FastSparseSetFactory <int> .FastSparseSet <int> > ent in mapExitVar
                                 .EntryList())
                        {
                            foreach (int version in ent.Value)
                            {
                                int            varindex = ent.Key;
                                VarVersionPair exitvar  = new VarVersionPair(varindex, version);
                                FastSparseSetFactory <int> .FastSparseSet <int> newSet = mapNew.Get(varindex);
                                // remove the actual exit version
                                newSet.Remove(version);
                                // get or create phantom version
                                VarVersionPair phantomvar = mapPhantom.GetOrNull(exitvar);
                                if (phantomvar == null)
                                {
                                    int newversion = GetNextFreeVersion(exitvar.var, null);
                                    phantomvar = new VarVersionPair(exitvar.var, newversion);
                                    VarVersionNode exitnode    = ssuversions.nodes.GetWithKey(exitvar);
                                    VarVersionNode phantomnode = ssuversions.CreateNode(phantomvar);
                                    phantomnode.flags |= VarVersionNode.Flag_Phantom_Finexit;
                                    VarVersionEdge edge = new VarVersionEdge(VarVersionEdge.Edge_Phantom, exitnode, phantomnode
                                                                             );
                                    exitnode.AddSuccessor(edge);
                                    phantomnode.AddPredecessor(edge);
                                    Sharpen.Collections.Put(mapPhantom, exitvar, phantomvar);
                                }
                                // add phantom version
                                newSet.Add(phantomvar.version);
                            }
                        }
                        if (!(mapPhantom.Count == 0))
                        {
                            Sharpen.Collections.Put(phantomexitnodes, predid, mapPhantom);
                        }
                    }
                }
            }
            return(mapNew);
        }
Exemplo n.º 6
0
        private void ProcessExprent(Exprent expr, SFormsFastMapDirect[] varmaparr, Statement
                                    stat, bool calcLiveVars)
        {
            if (expr == null)
            {
                return;
            }
            VarExprent varassign = null;
            bool       finished  = false;

            switch (expr.type)
            {
            case Exprent.Exprent_Assignment:
            {
                AssignmentExprent assexpr = (AssignmentExprent)expr;
                if (assexpr.GetCondType() == AssignmentExprent.Condition_None)
                {
                    Exprent dest = assexpr.GetLeft();
                    if (dest.type == Exprent.Exprent_Var)
                    {
                        varassign = (VarExprent)dest;
                    }
                }
                break;
            }

            case Exprent.Exprent_Function:
            {
                FunctionExprent func = (FunctionExprent)expr;
                switch (func.GetFuncType())
                {
                case FunctionExprent.Function_Iif:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr, stat, calcLiveVars);
                    SFormsFastMapDirect varmapFalse;
                    if (varmaparr[1] == null)
                    {
                        varmapFalse = new SFormsFastMapDirect(varmaparr[0]);
                    }
                    else
                    {
                        varmapFalse  = varmaparr[1];
                        varmaparr[1] = null;
                    }
                    ProcessExprent(func.GetLstOperands()[1], varmaparr, stat, calcLiveVars);
                    SFormsFastMapDirect[] varmaparrNeg = new SFormsFastMapDirect[] { varmapFalse, null };
                    ProcessExprent(func.GetLstOperands()[2], varmaparrNeg, stat, calcLiveVars);
                    MergeMaps(varmaparr[0], varmaparrNeg[0]);
                    varmaparr[1] = null;
                    finished     = true;
                    break;
                }

                case FunctionExprent.Function_Cadd:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr, stat, calcLiveVars);
                    SFormsFastMapDirect[] varmaparrAnd = new SFormsFastMapDirect[] { new SFormsFastMapDirect
                                                                                         (varmaparr[0]), null };
                    ProcessExprent(func.GetLstOperands()[1], varmaparrAnd, stat, calcLiveVars);
                    // false map
                    varmaparr[1] = MergeMaps(varmaparr[varmaparr[1] == null ? 0 : 1], varmaparrAnd[varmaparrAnd
                                                                                                   [1] == null ? 0 : 1]);
                    // true map
                    varmaparr[0] = varmaparrAnd[0];
                    finished     = true;
                    break;
                }

                case FunctionExprent.Function_Cor:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr, stat, calcLiveVars);
                    SFormsFastMapDirect[] varmaparrOr = new SFormsFastMapDirect[] { new SFormsFastMapDirect
                                                                                        (varmaparr[varmaparr[1] == null ? 0 : 1]), null };
                    ProcessExprent(func.GetLstOperands()[1], varmaparrOr, stat, calcLiveVars);
                    // false map
                    varmaparr[1] = varmaparrOr[varmaparrOr[1] == null ? 0 : 1];
                    // true map
                    varmaparr[0] = MergeMaps(varmaparr[0], varmaparrOr[0]);
                    finished     = true;
                    break;
                }
                }
                break;
            }
            }
            if (!finished)
            {
                List <Exprent> lst = expr.GetAllExprents();
                lst.Remove(varassign);
                foreach (Exprent ex in lst)
                {
                    ProcessExprent(ex, varmaparr, stat, calcLiveVars);
                }
            }
            SFormsFastMapDirect varmap = varmaparr[0];

            // field access
            if (expr.type == Exprent.Exprent_Field)
            {
                int?index;
                if (mapFieldVars.ContainsKey(expr.id))
                {
                    index = mapFieldVars.GetOrNullable(expr.id);
                }
                else
                {
                    index = fieldvarcounter--;
                    Sharpen.Collections.Put(mapFieldVars, expr.id, index);
                    // ssu graph
                    ssuversions.CreateNode(new VarVersionPair(index, 1));
                }
                SetCurrentVar(varmap, index, 1);
            }
            else if (expr.type == Exprent.Exprent_Invocation || (expr.type == Exprent.Exprent_Assignment &&
                                                                 ((AssignmentExprent)expr).GetLeft().type == Exprent.Exprent_Field) || (expr.
                                                                                                                                        type == Exprent.Exprent_New && ((NewExprent)expr).GetNewType().type == ICodeConstants
                                                                                                                                        .Type_Object) || expr.type == Exprent.Exprent_Function)
            {
                bool ismmpp = true;
                if (expr.type == Exprent.Exprent_Function)
                {
                    ismmpp = false;
                    FunctionExprent fexpr = (FunctionExprent)expr;
                    if (fexpr.GetFuncType() >= FunctionExprent.Function_Imm && fexpr.GetFuncType() <=
                        FunctionExprent.Function_Ppi)
                    {
                        if (fexpr.GetLstOperands()[0].type == Exprent.Exprent_Field)
                        {
                            ismmpp = true;
                        }
                    }
                }
                if (ismmpp)
                {
                    varmap.RemoveAllFields();
                }
            }
            if (varassign != null)
            {
                int varindex = varassign.GetIndex();
                if (varassign.GetVersion() == 0)
                {
                    // get next version
                    int nextver = GetNextFreeVersion(varindex, stat);
                    // set version
                    varassign.SetVersion(nextver);
                    // ssu graph
                    ssuversions.CreateNode(new VarVersionPair(varindex, nextver));
                    SetCurrentVar(varmap, varindex, nextver);
                }
                else
                {
                    if (calcLiveVars)
                    {
                        VarMapToGraph(new VarVersionPair(varindex, varassign.GetVersion()), varmap);
                    }
                    SetCurrentVar(varmap, varindex, varassign.GetVersion());
                }
            }
            else if (expr.type == Exprent.Exprent_Function)
            {
                // MM or PP function
                FunctionExprent func_1 = (FunctionExprent)expr;
                switch (func_1.GetFuncType())
                {
                case FunctionExprent.Function_Imm:
                case FunctionExprent.Function_Mmi:
                case FunctionExprent.Function_Ipp:
                case FunctionExprent.Function_Ppi:
                {
                    if (func_1.GetLstOperands()[0].type == Exprent.Exprent_Var)
                    {
                        VarExprent     var      = (VarExprent)func_1.GetLstOperands()[0];
                        int            varindex = var.GetIndex();
                        VarVersionPair varpaar  = new VarVersionPair(varindex, var.GetVersion());
                        // ssu graph
                        VarVersionPair phantomver = phantomppnodes.GetOrNull(varpaar);
                        if (phantomver == null)
                        {
                            // get next version
                            int nextver = GetNextFreeVersion(varindex, null);
                            phantomver = new VarVersionPair(varindex, nextver);
                            //ssuversions.createOrGetNode(phantomver);
                            ssuversions.CreateNode(phantomver);
                            VarVersionNode vernode = ssuversions.nodes.GetWithKey(varpaar);
                            FastSparseSetFactory <int> .FastSparseSet <int> vers = factory.SpawnEmptySet();
                            if (vernode.preds.Count == 1)
                            {
                                vers.Add(new Sharpen.EnumeratorAdapter <VarVersionEdge>(vernode.preds.GetEnumerator()).Next().source.version);
                            }
                            else
                            {
                                foreach (VarVersionEdge edge in vernode.preds)
                                {
                                    vers.Add(new Sharpen.EnumeratorAdapter <VarVersionEdge>(edge.source.preds.GetEnumerator()).Next().source.version);
                                }
                            }
                            vers.Add(nextver);
                            CreateOrUpdatePhiNode(varpaar, vers, stat);
                            Sharpen.Collections.Put(phantomppnodes, varpaar, phantomver);
                        }
                        if (calcLiveVars)
                        {
                            VarMapToGraph(varpaar, varmap);
                        }
                        SetCurrentVar(varmap, varindex, var.GetVersion());
                    }
                    break;
                }
                }
            }
            else if (expr.type == Exprent.Exprent_Var)
            {
                VarExprent vardest      = (VarExprent)expr;
                int        varindex     = vardest.GetIndex();
                int        current_vers = vardest.GetVersion();
                FastSparseSetFactory <int> .FastSparseSet <int> vers = varmap.Get(varindex);
                int cardinality = vers.GetCardinality();
                if (cardinality == 1)
                {
                    // size == 1
                    if (current_vers != 0)
                    {
                        if (calcLiveVars)
                        {
                            VarMapToGraph(new VarVersionPair(varindex, current_vers), varmap);
                        }
                        SetCurrentVar(varmap, varindex, current_vers);
                    }
                    else
                    {
                        // split last version
                        int usever = GetNextFreeVersion(varindex, stat);
                        // set version
                        vardest.SetVersion(usever);
                        SetCurrentVar(varmap, varindex, usever);
                        // ssu graph
                        int            lastver = new Sharpen.EnumeratorAdapter <int>(vers.GetEnumerator()).Next();
                        VarVersionNode prenode = ssuversions.nodes.GetWithKey(new VarVersionPair(varindex
                                                                                                 , lastver));
                        VarVersionNode usenode = ssuversions.CreateNode(new VarVersionPair(varindex, usever
                                                                                           ));
                        VarVersionEdge edge = new VarVersionEdge(VarVersionEdge.Edge_General, prenode, usenode
                                                                 );
                        prenode.AddSuccessor(edge);
                        usenode.AddPredecessor(edge);
                    }
                }
                else if (cardinality == 2)
                {
                    // size > 1
                    if (current_vers != 0)
                    {
                        if (calcLiveVars)
                        {
                            VarMapToGraph(new VarVersionPair(varindex, current_vers), varmap);
                        }
                        SetCurrentVar(varmap, varindex, current_vers);
                    }
                    else
                    {
                        // split version
                        int usever = GetNextFreeVersion(varindex, stat);
                        // set version
                        vardest.SetVersion(usever);
                        // ssu node
                        ssuversions.CreateNode(new VarVersionPair(varindex, usever));
                        SetCurrentVar(varmap, varindex, usever);
                        current_vers = usever;
                    }
                    CreateOrUpdatePhiNode(new VarVersionPair(varindex, current_vers), vers, stat);
                }
            }
        }
        private void ProcessExprent(Exprent expr, SFormsFastMapDirect[] varmaparr)
        {
            if (expr == null)
            {
                return;
            }
            VarExprent varassign = null;
            bool       finished  = false;

            switch (expr.type)
            {
            case Exprent.Exprent_Assignment:
            {
                AssignmentExprent assexpr = (AssignmentExprent)expr;
                if (assexpr.GetCondType() == AssignmentExprent.Condition_None)
                {
                    Exprent dest = assexpr.GetLeft();
                    if (dest.type == Exprent.Exprent_Var)
                    {
                        varassign = (VarExprent)dest;
                    }
                }
                break;
            }

            case Exprent.Exprent_Function:
            {
                FunctionExprent func = (FunctionExprent)expr;
                switch (func.GetFuncType())
                {
                case FunctionExprent.Function_Iif:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr);
                    SFormsFastMapDirect varmapFalse;
                    if (varmaparr[1] == null)
                    {
                        varmapFalse = new SFormsFastMapDirect(varmaparr[0]);
                    }
                    else
                    {
                        varmapFalse  = varmaparr[1];
                        varmaparr[1] = null;
                    }
                    ProcessExprent(func.GetLstOperands()[1], varmaparr);
                    SFormsFastMapDirect[] varmaparrNeg = new SFormsFastMapDirect[] { varmapFalse, null };
                    ProcessExprent(func.GetLstOperands()[2], varmaparrNeg);
                    MergeMaps(varmaparr[0], varmaparrNeg[0]);
                    varmaparr[1] = null;
                    finished     = true;
                    break;
                }

                case FunctionExprent.Function_Cadd:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr);
                    SFormsFastMapDirect[] varmaparrAnd = new SFormsFastMapDirect[] { new SFormsFastMapDirect
                                                                                         (varmaparr[0]), null };
                    ProcessExprent(func.GetLstOperands()[1], varmaparrAnd);
                    // false map
                    varmaparr[1] = MergeMaps(varmaparr[varmaparr[1] == null ? 0 : 1], varmaparrAnd[varmaparrAnd
                                                                                                   [1] == null ? 0 : 1]);
                    // true map
                    varmaparr[0] = varmaparrAnd[0];
                    finished     = true;
                    break;
                }

                case FunctionExprent.Function_Cor:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr);
                    SFormsFastMapDirect[] varmaparrOr = new SFormsFastMapDirect[] { new SFormsFastMapDirect
                                                                                        (varmaparr[varmaparr[1] == null ? 0 : 1]), null };
                    ProcessExprent(func.GetLstOperands()[1], varmaparrOr);
                    // false map
                    varmaparr[1] = varmaparrOr[varmaparrOr[1] == null ? 0 : 1];
                    // true map
                    varmaparr[0] = MergeMaps(varmaparr[0], varmaparrOr[0]);
                    finished     = true;
                    break;
                }
                }
                break;
            }
            }
            if (finished)
            {
                return;
            }
            List <Exprent> lst = expr.GetAllExprents();

            lst.Remove(varassign);
            foreach (Exprent ex in lst)
            {
                ProcessExprent(ex, varmaparr);
            }
            SFormsFastMapDirect varmap = varmaparr[0];

            if (varassign != null)
            {
                int varindex = varassign.GetIndex();
                if (varassign.GetVersion() == 0)
                {
                    // get next version
                    int nextver = GetNextFreeVersion(varindex);
                    // set version
                    varassign.SetVersion(nextver);
                    SetCurrentVar(varmap, varindex, nextver);
                }
                else
                {
                    SetCurrentVar(varmap, varindex, varassign.GetVersion());
                }
            }
            else if (expr.type == Exprent.Exprent_Var)
            {
                VarExprent vardest  = (VarExprent)expr;
                int        varindex = vardest.GetIndex();
                FastSparseSetFactory <int> .FastSparseSet <int> vers = varmap.Get(varindex);
                int cardinality = vers.GetCardinality();
                if (cardinality == 1)
                {
                    // == 1
                    // set version
                    int it = new Sharpen.EnumeratorAdapter <int>(vers.GetEnumerator()).Next();
                    vardest.SetVersion(it);
                }
                else if (cardinality == 2)
                {
                    // size > 1
                    int            current_vers = vardest.GetVersion();
                    VarVersionPair currpaar     = new VarVersionPair(varindex, current_vers);
                    if (current_vers != 0 && phi.ContainsKey(currpaar))
                    {
                        SetCurrentVar(varmap, varindex, current_vers);
                        // update phi node
                        phi.GetOrNull(currpaar).Union(vers);
                    }
                    else
                    {
                        // increase version
                        int nextver = GetNextFreeVersion(varindex);
                        // set version
                        vardest.SetVersion(nextver);
                        SetCurrentVar(varmap, varindex, nextver);
                        // create new phi node
                        Sharpen.Collections.Put(phi, new VarVersionPair(varindex, nextver), vers);
                    }
                }
            }
        }