Пример #1
0
        private void visitSignature(DNode call, Signature signature)
        {
            for (int i = 0; i < call.numOperands && i < signature.args.Length; i++)
            {
                DNode    node = call.getOperand(i);
                Argument arg  = i < signature.args.Length
                               ? signature.args[i]
                               : signature.args[signature.args.Length - 1];

                TypeUnit tu = TypeUnit.FromArgument(arg);
                if (tu != null)
                {
                    node.addType(tu);
                }
            }

            // Peek ahead for constants.
            if (signature.args.Length > 0 &&
                signature.args[signature.args.Length - 1].type == VariableType.Variadic)
            {
                for (int i = signature.args.Length - 1; i < call.numOperands; i++)
                {
                    DNode node = call.getOperand(i);
                    if (node.type != NodeType.Constant)
                    {
                        continue;
                    }

                    DConstant constNode = (DConstant)node;
                    Variable  global    = graph_.file.lookupGlobal(constNode.value);
                    if (global != null)
                    {
                        call.replaceOperand(i, new DGlobal(global));
                        continue;
                    }

                    // Guess a string...
                    call.replaceOperand(i, new DString(graph_.file.stringFromData(constNode.value)));
                }
            }
        }
Пример #2
0
        private void visitSignature(DNode call, Signature signature)
        {
            for (int i = 0; i < call.numOperands && i < signature.args.Length; i++)
            {
                DNode node = call.getOperand(i);
                Argument arg = i < signature.args.Length
                               ? signature.args[i]
                               : signature.args[signature.args.Length - 1];

                TypeUnit tu = TypeUnit.FromArgument(arg);
                if (tu != null)
                    node.addType(tu);
            }

            // Peek ahead for constants.
            if (signature.args.Length > 0 &&
                signature.args[signature.args.Length - 1].type == VariableType.Variadic)
            {
                for (int i = signature.args.Length - 1; i < call.numOperands; i++)
                {
                    DNode node = call.getOperand(i);
                    if (node.type != NodeType.Constant)
                        continue;

                    DConstant constNode = (DConstant)node;
                    Variable global = graph_.file.lookupGlobal(constNode.value);
                    if (global != null)
                    {
                        call.replaceOperand(i, new DGlobal(global));
                        continue;
                    }

                    // Guess a string...
                    call.replaceOperand(i, new DString(graph_.file.stringFromData(constNode.value)));
                }
            }
        }
Пример #3
0
        private static bool CollapseArrayReferences(NodeBlock block)
        {
            bool changed = false;

            for (NodeList.reverse_iterator iter = block.nodes.rbegin(); iter.more(); iter.next())
            {
                DNode node = iter.node;

                if (node.type == NodeType.Store || node.type == NodeType.Load)
                {
                    if (node.getOperand(0).type != NodeType.ArrayRef && IsArray(node.getOperand(0).typeSet))
                    {
                        DConstant index0 = new DConstant(0);
                        DArrayRef aref0  = new DArrayRef(node.getOperand(0), index0, 0);
                        block.nodes.insertBefore(node, index0);
                        block.nodes.insertBefore(node, aref0);
                        node.replaceOperand(0, aref0);
                        continue;
                    }
                }

                if (node.type != NodeType.Binary)
                {
                    continue;
                }

                DBinary binary = (DBinary)node;
                if (binary.spop != SPOpcode.add)
                {
                    continue;
                }

                if (binary.lhs.type == NodeType.LocalRef)
                {
                    //Debug.Assert(true);
                }

                // Check for an array index.
                DNode abase = GuessArrayBase(binary.lhs, binary.rhs);
                if (abase == null)
                {
                    continue;
                }
                DNode index = (abase == binary.lhs) ? binary.rhs : binary.lhs;

                if (!IsReallyLikelyArrayCompute(binary, abase))
                {
                    continue;
                }

                // Multi-dimensional arrays are indexed like:
                // x[y] => x + x[y]
                //
                // We recognize this and just remove the add, ignoring the
                // underlying representation of the array.
                if (index.type == NodeType.Load && index.getOperand(0) == abase)
                {
                    node.replaceAllUsesWith(index);
                    node.removeFromUseChains();
                    block.nodes.remove(iter);
                    changed = true;
                    continue;
                }

                // Otherwise, create a new array reference.
                DArrayRef aref = new DArrayRef(abase, index);
                iter.node.replaceAllUsesWith(aref);
                iter.node.removeFromUseChains();
                block.nodes.remove(iter);
                block.nodes.insertBefore(iter.node, aref);
                changed = true;
            }

            return(changed);
        }