Beispiel #1
0
        public override Expr VisitNAryExpr(NAryExpr node)
        {
            // Try to do direct map indexing
            // FIXME: If there are nested mapselects but they don't end on a variable
            // then we'll do a lot of unnecessary work every time we traverse into a map select down.
            var asMapSelect = ExprUtil.AsMapSelect(node);

            if (asMapSelect != null)
            {
                // Gather the indices. They will be backwards as we traversing top down so have to
                // reverse at the end.
                //
                // Here's an example showing this:
                //
                // var m:[int][int]bool;
                // y:= m[0][1]
                //
                // The indicies we want are [0][1], but when traverse we will visit them backwards as
                // we start at the root of the expression tree.
                //
                // The structure of this is
                //
                //            mapselect
                //            /        \
                //    mapselect        1
                //    /      \
                //  m        0
                var  indices  = new List <Expr>();
                Expr firstArg = null;
                do
                {
                    // Traverse multi-arity arguments in reverse because later on we reverse them.
                    for (int index = asMapSelect.Args.Count - 1; index >= 1; --index)
                    {
                        // Don't do index variable mapping here because we might
                        // need to throw away what we've done
                        indices.Add(asMapSelect.Args[index]);
                    }
                    firstArg    = asMapSelect.Args[0];
                    asMapSelect = ExprUtil.AsMapSelect(firstArg);
                } while (asMapSelect != null);

                // Hopefully a map variable we can write to
                var asId = ExprUtil.AsIdentifer(firstArg);

                if (asId != null && asId.Decl.TypedIdent.Type.IsMap)
                {
                    // Do a remapping if necessary
                    // FIXME: This sucks. Fix boogie instead!
                    Variable V = null;
                    if (preReplacementReMap.ContainsKey(asId.Decl))
                    {
                        V = preReplacementReMap[asId.Decl];
                    }
                    else
                    {
                        V = asId.Decl;
                    }

                    // We need to make sure that the map variable isn't bound and that
                    // Note: that map is being fully indexed into and not partially
                    if ((!BoundVariables.Contains(V)) &&
                        indices.Count == MapProxy.ComputeIndicesRequireToDirectlyIndex(asId.Decl.TypedIdent.Type))
                    {
                        // Put indices in correct order
                        indices.Reverse();

                        // Expand the indices so variables are mapped
                        var expandedIndices = new List <Expr>();
                        foreach (var index in indices)
                        {
                            expandedIndices.Add((Expr)this.Visit(index));
                        }

                        var valueFromMap = State.ReadMapVariableInScopeAt(V, expandedIndices);
                        return(valueFromMap);
                    }
                }
            }

            // Handle all other NAryExpr and fall back when we encounter a mapselect we can't support
            // (e.g. the map variable being used is not known).
            return(base.VisitNAryExpr(node));
        }
Beispiel #2
0
        // Only returns true if the indices definitely only alias up to one indice stored
        // in StoresAtSymbolicNonAliasingIndices. i.e.
        //
        // returns true iff
        //
        // the indices do not alias anything in StoresAtSymbolicNonAliasingIndices
        // OR
        // the indices alias a single element in StoresAtSymbolicNonAliasingIndices
        // which ok because this tells us which element to overwrite.
        //
        // Note that if this method returns false it means that the indices "might" alias.
        private bool AliasesZeroOrOneSymbolicNonAliasingIndices(IList <Expr> indices)
        {
            if (indices.Count > 1)
            {
                // Our alias analysis is very primitive and we only allow a single index
                return(false);
            }

            var indexExpr = indices[0];
            // Analysis: We consider the follow expressions to not alias
            // <sym_var>
            // <constant> + <sym_var>
            //
            // Note sym_var must be the same


            // Try single variable
            var asId = ExprUtil.AsIdentifer(indexExpr);

            if (asId != null)
            {
                if (SymVariable == null)
                {
                    // We haven't picked a variable for use in our non aliasing symbolci expressions yet
                    // use this one
                    Debug.Assert(StoresAtSymbolicNonAliasingIndices.Count == 0);
                    SymVariable = asId.Decl;
                    return(true);
                }
                else
                {
                    // We have an existing symbolic variable that we are using
                    if (SymVariable.Equals(asId.Decl))
                    {
                        return(true);
                    }
                    return(false);
                }
            }

            // We are relying on the expression simplification of the expression builder to always
            // but the constant on the left child
            // <constant> + <sym_var>
            var asAdd = ExprUtil.AsAdd(indexExpr);

            if (asAdd != null)
            {
                var lhsAsLit = ExprUtil.AsLiteral(asAdd.Args[0]);
                if (lhsAsLit != null)
                {
                    var rhsAsId = ExprUtil.AsIdentifer(asAdd.Args[1]);
                    if (rhsAsId != null)
                    {
                        if (SymVariable == null)
                        {
                            // We haven't picked a variable for use in our non aliasing symbolci expressions yet
                            // use this one
                            Debug.Assert(StoresAtSymbolicNonAliasingIndices.Count == 0);
                            SymVariable = rhsAsId.Decl;
                            return(true);
                        }
                        else
                        {
                            // We have an existing symbolic variable that we are using
                            if (SymVariable.Equals(rhsAsId.Decl))
                            {
                                return(true);
                            }
                            return(false);
                        }
                    }
                }
            }

            // The indicies might alias something we already have stored.
            return(false);
        }