Пример #1
0
        private static bool GetUsedVersions(SSAUConstructorSparseEx ssa, VarVersionPair
                                            var, List <VarVersionNode> res)
        {
            VarVersionsGraph            ssuversions = ssa.GetSsuversions();
            VarVersionNode              varnode     = ssuversions.nodes.GetWithKey(var);
            HashSet <VarVersionNode>    setVisited  = new HashSet <VarVersionNode>();
            HashSet <VarVersionNode>    setNotDoms  = new HashSet <VarVersionNode>();
            LinkedList <VarVersionNode> stack       = new LinkedList <VarVersionNode>();

            stack.AddLast(varnode);
            while (!(stack.Count == 0))
            {
                VarVersionNode nd = stack.RemoveAtReturningValue(0);
                setVisited.Add(nd);
                if (nd != varnode && (nd.flags & VarVersionNode.Flag_Phantom_Finexit) == 0)
                {
                    res.Add(nd);
                }
                foreach (VarVersionEdge edge in nd.succs)
                {
                    VarVersionNode succ = edge.dest;
                    if (!setVisited.Contains(edge.dest))
                    {
                        bool isDominated = true;
                        foreach (VarVersionEdge prededge in succ.preds)
                        {
                            if (!setVisited.Contains(prededge.source))
                            {
                                isDominated = false;
                                break;
                            }
                        }
                        if (isDominated)
                        {
                            stack.AddLast(succ);
                        }
                        else
                        {
                            setNotDoms.Add(succ);
                        }
                    }
                }
            }
            setNotDoms.RemoveAll(setVisited);
            return(!(setNotDoms.Count == 0));
        }
Пример #2
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);
                }
            }
        }
Пример #3
0
        public virtual void SimplifyStackVars(RootStatement root, StructMethod mt, StructClass
                                              cl)
        {
            HashSet <int>           setReorderedIfs = new HashSet <int>();
            SSAUConstructorSparseEx ssau            = null;

            while (true)
            {
                bool found = false;
                SSAConstructorSparseEx ssa = new SSAConstructorSparseEx();
                ssa.SplitVariables(root, mt);
                SimplifyExprentsHelper sehelper = new SimplifyExprentsHelper(ssau == null);
                while (sehelper.SimplifyStackVarsStatement(root, setReorderedIfs, ssa, cl))
                {
                    found = true;
                }
                SetVersionsToNull(root);
                SequenceHelper.CondenseSequences(root);
                ssau = new SSAUConstructorSparseEx();
                ssau.SplitVariables(root, mt);
                if (IterateStatements(root, ssau))
                {
                    found = true;
                }
                SetVersionsToNull(root);
                if (!found)
                {
                    break;
                }
            }
            // remove unused assignments
            ssau = new SSAUConstructorSparseEx();
            ssau.SplitVariables(root, mt);
            IterateStatements(root, ssau);
            SetVersionsToNull(root);
        }
Пример #4
0
        private bool IterateStatements(RootStatement root, SSAUConstructorSparseEx ssa)
        {
            FlattenStatementsHelper flatthelper = new FlattenStatementsHelper();
            DirectGraph             dgraph      = flatthelper.BuildDirectGraph(root);
            bool res = false;
            HashSet <DirectNode>    setVisited = new HashSet <DirectNode>();
            LinkedList <DirectNode> stack      = new LinkedList <DirectNode>();
            LinkedList <Dictionary <VarVersionPair, Exprent> > stackMaps = new LinkedList <Dictionary <VarVersionPair, Exprent> >();

            stack.AddLast(dgraph.first);
            stackMaps.AddLast(new Dictionary <VarVersionPair, Exprent>());
            while (!(stack.Count == 0))
            {
                DirectNode nd = Sharpen.Collections.RemoveFirst(stack);
                Dictionary <VarVersionPair, Exprent> mapVarValues = Sharpen.Collections.RemoveFirst
                                                                        (stackMaps);
                if (setVisited.Contains(nd))
                {
                    continue;
                }
                setVisited.Add(nd);
                List <List <Exprent> > lstLists = new List <List <Exprent> >();
                if (!(nd.exprents.Count == 0))
                {
                    lstLists.Add(nd.exprents);
                }
                if (nd.succs.Count == 1)
                {
                    DirectNode ndsucc = nd.succs[0];
                    if (ndsucc.type == DirectNode.Node_Tail && !(ndsucc.exprents.Count == 0))
                    {
                        lstLists.Add(nd.succs[0].exprents);
                        nd = ndsucc;
                    }
                }
                for (int i = 0; i < lstLists.Count; i++)
                {
                    List <Exprent> lst   = lstLists[i];
                    int            index = 0;
                    while (index < lst.Count)
                    {
                        Exprent next = null;
                        if (index == lst.Count - 1)
                        {
                            if (i < lstLists.Count - 1)
                            {
                                next = lstLists[i + 1][0];
                            }
                        }
                        else
                        {
                            next = lst[index + 1];
                        }
                        int[] ret = IterateExprent(lst, index, next, mapVarValues, ssa);
                        if (ret[0] >= 0)
                        {
                            index = ret[0];
                        }
                        else
                        {
                            index++;
                        }
                        res |= (ret[1] == 1);
                    }
                }
                foreach (DirectNode ndx in nd.succs)
                {
                    stack.AddLast(ndx);
                    stackMaps.AddLast(new Dictionary <VarVersionPair, Exprent>(mapVarValues));
                }
                // make sure the 3 special exprent lists in a loop (init, condition, increment) are not empty
                // change loop type if necessary
                if ((nd.exprents.Count == 0) && (nd.type == DirectNode.Node_Init || nd.type == DirectNode
                                                 .Node_Condition || nd.type == DirectNode.Node_Increment))
                {
                    nd.exprents.Add(null);
                    if (nd.statement.type == Statement.Type_Do)
                    {
                        DoStatement loop = (DoStatement)nd.statement;
                        if (loop.GetLooptype() == DoStatement.Loop_For && loop.GetInitExprent() == null &&
                            loop.GetIncExprent() == null)
                        {
                            // "downgrade" loop to 'while'
                            loop.SetLooptype(DoStatement.Loop_While);
                        }
                    }
                }
            }
            return(res);
        }
Пример #5
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);
        }
Пример #6
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);
        }
Пример #7
0
        private static object[] IterateChildExprent(Exprent exprent, Exprent parent, Exprent
                                                    next, Dictionary <VarVersionPair, Exprent> mapVarValues, SSAUConstructorSparseEx
                                                    ssau)
        {
            bool changed = false;

            foreach (Exprent expr in exprent.GetAllExprents())
            {
                var oldExpr = expr;
                while (true)
                {
                    object[] arr     = IterateChildExprent(oldExpr, parent, next, mapVarValues, ssau);
                    Exprent  retexpr = (Exprent)arr[0];
                    changed |= (bool)arr[1];
                    bool isReplaceable = (bool)arr[2];
                    if (retexpr != null)
                    {
                        if (isReplaceable)
                        {
                            ReplaceSingleVar(exprent, (VarExprent)oldExpr, retexpr, ssau);
                            oldExpr = retexpr;
                        }
                        else
                        {
                            exprent.ReplaceExprent(oldExpr, retexpr);
                        }
                        changed = true;
                    }
                    if (!isReplaceable)
                    {
                        break;
                    }
                }
            }
            Exprent dest = IsReplaceableVar(exprent, mapVarValues);

            if (dest != null)
            {
                return(new object[] { dest, true, true });
            }
            VarExprent left  = null;
            Exprent    right = null;

            if (exprent.type == Exprent.Exprent_Assignment)
            {
                AssignmentExprent @as = (AssignmentExprent)exprent;
                if (@as.GetLeft().type == Exprent.Exprent_Var)
                {
                    left  = (VarExprent)@as.GetLeft();
                    right = @as.GetRight();
                }
            }
            if (left == null)
            {
                return(new object[] { null, changed, false });
            }
            bool isHeadSynchronized = false;

            if (next == null && parent.type == Exprent.Exprent_Monitor)
            {
                MonitorExprent monexpr = (MonitorExprent)parent;
                if (monexpr.GetMonType() == MonitorExprent.Monitor_Enter && exprent.Equals(monexpr
                                                                                           .GetValue()))
                {
                    isHeadSynchronized = true;
                }
            }
            // stack variable or synchronized head exprent
            if (!left.IsStack() && !isHeadSynchronized)
            {
                return(new object[] { null, changed, false });
            }
            VarVersionPair        leftpaar = new VarVersionPair(left);
            List <VarVersionNode> usedVers = new List <VarVersionNode>();
            bool notdom = GetUsedVersions(ssau, leftpaar, usedVers);

            if (!notdom && (usedVers.Count == 0))
            {
                return(new object[] { right, changed, false });
            }
            // stack variables only
            if (!left.IsStack())
            {
                return(new object[] { null, changed, false });
            }
            int useflags = right.GetExprentUse();

            if ((useflags & Exprent.Both_Flags) != Exprent.Both_Flags)
            {
                return(new object[] { null, changed, false });
            }
            Dictionary <int, HashSet <VarVersionPair> > mapVars = GetAllVarVersions(leftpaar, right
                                                                                    , ssau);

            if (mapVars.ContainsKey(leftpaar.var) && notdom)
            {
                return(new object[] { null, changed, false });
            }
            Sharpen.Collections.Remove(mapVars, leftpaar.var);
            HashSet <VarVersionPair> setAllowedVars = GetAllVersions(parent);

            if (next != null)
            {
                Sharpen.Collections.AddAll(setAllowedVars, GetAllVersions(next));
            }
            bool vernotreplaced = false;
            HashSet <VarVersionPair> setTempUsedVers = new HashSet <VarVersionPair>();

            foreach (VarVersionNode usedvar in usedVers)
            {
                VarVersionPair usedver = new VarVersionPair(usedvar.var, usedvar.version);
                if (IsVersionToBeReplaced(usedver, mapVars, ssau, leftpaar) && (right.type == Exprent
                                                                                .Exprent_Var || setAllowedVars.Contains(usedver)))
                {
                    setTempUsedVers.Add(usedver);
                }
                else
                {
                    vernotreplaced = true;
                }
            }
            if (!notdom && !vernotreplaced)
            {
                foreach (VarVersionPair usedver in setTempUsedVers)
                {
                    Exprent copy = right.Copy();
                    if (right.type == Exprent.Exprent_Field && ssau.GetMapFieldVars().ContainsKey(right
                                                                                                  .id))
                    {
                        Sharpen.Collections.Put(ssau.GetMapFieldVars(), copy.id, ssau.GetMapFieldVars().GetOrNullable
                                                    (right.id));
                    }
                    Sharpen.Collections.Put(mapVarValues, usedver, copy);
                }
                // remove assignment
                return(new object[] { right, changed, false });
            }
            return(new object[] { null, changed, false });
        }
Пример #8
0
        private int[] IterateExprent(List <Exprent> lstExprents, int index, Exprent next,
                                     Dictionary <VarVersionPair, Exprent> mapVarValues, SSAUConstructorSparseEx ssau)
        {
            Exprent exprent = lstExprents[index];
            int     changed = 0;

            foreach (Exprent expr in exprent.GetAllExprents())
            {
                var oldExpr = expr;
                while (true)
                {
                    object[] arr     = IterateChildExprent(oldExpr, exprent, next, mapVarValues, ssau);
                    Exprent  retexpr = (Exprent)arr[0];
                    changed |= (bool)arr[1] ? 1 : 0;
                    bool isReplaceable = (bool)arr[2];
                    if (retexpr != null)
                    {
                        if (isReplaceable)
                        {
                            ReplaceSingleVar(exprent, (VarExprent)oldExpr, retexpr, ssau);
                            oldExpr = retexpr;
                        }
                        else
                        {
                            exprent.ReplaceExprent(oldExpr, retexpr);
                        }
                        changed = 1;
                    }
                    if (!isReplaceable)
                    {
                        break;
                    }
                }
            }
            // no var on the highest level, so no replacing
            VarExprent left  = null;
            Exprent    right = null;

            if (exprent.type == Exprent.Exprent_Assignment)
            {
                AssignmentExprent @as = (AssignmentExprent)exprent;
                if (@as.GetLeft().type == Exprent.Exprent_Var)
                {
                    left  = (VarExprent)@as.GetLeft();
                    right = @as.GetRight();
                }
            }
            if (left == null)
            {
                return(new int[] { -1, changed });
            }
            VarVersionPair        leftpaar = new VarVersionPair(left);
            List <VarVersionNode> usedVers = new List <VarVersionNode>();
            bool notdom = GetUsedVersions(ssau, leftpaar, usedVers);

            if (!notdom && (usedVers.Count == 0))
            {
                if (left.IsStack() && (right.type == Exprent.Exprent_Invocation || right.type ==
                                       Exprent.Exprent_Assignment || right.type == Exprent.Exprent_New))
                {
                    if (right.type == Exprent.Exprent_New)
                    {
                        // new Object(); permitted
                        NewExprent nexpr = (NewExprent)right;
                        if (nexpr.IsAnonymous() || nexpr.GetNewType().arrayDim > 0 || nexpr.GetNewType().
                            type != ICodeConstants.Type_Object)
                        {
                            return(new int[] { -1, changed });
                        }
                    }
                    lstExprents[index] = right;
                    return(new int[] { index + 1, 1 });
                }
                else if (right.type == Exprent.Exprent_Var)
                {
                    lstExprents.RemoveAtReturningValue(index);
                    return(new int[] { index, 1 });
                }
                else
                {
                    return(new int[] { -1, changed });
                }
            }
            int useflags = right.GetExprentUse();

            // stack variables only
            if (!left.IsStack() && (right.type != Exprent.Exprent_Var || ((VarExprent)right).
                                    IsStack()))
            {
                // special case catch(... ex)
                return(new int[] { -1, changed });
            }
            if ((useflags & Exprent.Multiple_Uses) == 0 && (notdom || usedVers.Count > 1))
            {
                return(new int[] { -1, changed });
            }
            Dictionary <int, HashSet <VarVersionPair> > mapVars = GetAllVarVersions(leftpaar, right
                                                                                    , ssau);
            bool isSelfReference = mapVars.ContainsKey(leftpaar.var);

            if (isSelfReference && notdom)
            {
                return(new int[] { -1, changed });
            }
            HashSet <VarVersionPair> setNextVars = next == null ? null : GetAllVersions(next);

            // FIXME: fix the entire method!
            if (right.type != Exprent.Exprent_Const && right.type != Exprent.Exprent_Var && setNextVars
                != null && mapVars.ContainsKey(leftpaar.var))
            {
                foreach (VarVersionNode usedvar in usedVers)
                {
                    if (!setNextVars.Contains(new VarVersionPair(usedvar.var, usedvar.version)))
                    {
                        return(new int[] { -1, changed });
                    }
                }
            }
            Sharpen.Collections.Remove(mapVars, leftpaar.var);
            bool vernotreplaced = false;
            bool verreplaced    = false;
            HashSet <VarVersionPair> setTempUsedVers = new HashSet <VarVersionPair>();

            foreach (VarVersionNode usedvar in usedVers)
            {
                VarVersionPair usedver = new VarVersionPair(usedvar.var, usedvar.version);
                if (IsVersionToBeReplaced(usedver, mapVars, ssau, leftpaar) && (right.type == Exprent
                                                                                .Exprent_Const || right.type == Exprent.Exprent_Var || right.type == Exprent.Exprent_Field ||
                                                                                setNextVars == null || setNextVars.Contains(usedver)))
                {
                    setTempUsedVers.Add(usedver);
                    verreplaced = true;
                }
                else
                {
                    vernotreplaced = true;
                }
            }
            if (isSelfReference && vernotreplaced)
            {
                return(new int[] { -1, changed });
            }
            else
            {
                foreach (VarVersionPair usedver in setTempUsedVers)
                {
                    Exprent copy = right.Copy();
                    if (right.type == Exprent.Exprent_Field && ssau.GetMapFieldVars().ContainsKey(right
                                                                                                  .id))
                    {
                        Sharpen.Collections.Put(ssau.GetMapFieldVars(), copy.id, ssau.GetMapFieldVars().GetOrNullable
                                                    (right.id));
                    }
                    Sharpen.Collections.Put(mapVarValues, usedver, copy);
                }
            }
            if (!notdom && !vernotreplaced)
            {
                // remove assignment
                lstExprents.RemoveAtReturningValue(index);
                return(new int[] { index, 1 });
            }
            else if (verreplaced)
            {
                return(new int[] { index + 1, changed });
            }
            else
            {
                return(new int[] { -1, changed });
            }
        }