Example #1
0
        public void removeUse(int index, DNode node)
        {
            DUse use = null;

            foreach (var u in uses)
            {
                if (u.index == index && u.node == node)
                {
                    use = u;
                    break;
                }
            }
            //Debug.Assert(use != null);
            uses.Remove(use);
        }
Example #2
0
        private static void RemoveDeadCodeInBlock(NodeBlock block)
        {
            for (NodeList.reverse_iterator iter = block.nodes.rbegin(); iter.more();)
            {
                if (iter.node.type == NodeType.DeclareLocal)
                {
                    DDeclareLocal decl = (DDeclareLocal)iter.node;
                    if (decl.var == null &&
                        (decl.uses.Count == 0 ||
                         (decl.uses.Count == 1 && decl.value != null)))
                    {
                        // This was probably just a stack temporary.
                        if (decl.uses.Count == 1)
                        {
                            DUse use = decl.uses.First.Value;
                            use.node.replaceOperand(use.index, decl.value);
                        }
                        iter.node.removeFromUseChains();
                        block.nodes.remove(iter);
                        continue;
                    }
                }

                if ((iter.node.type == NodeType.Store &&
                     iter.node.getOperand(0).type == NodeType.Heap &&
                     iter.node.getOperand(0).uses.Count == 1))
                {
                    iter.node.removeFromUseChains();
                    block.nodes.remove(iter);
                }

                if (!iter.node.idempotent || iter.node.guard || iter.node.uses.Count > 0)
                {
                    iter.next();
                    continue;
                }

                iter.node.removeFromUseChains();
                block.nodes.remove(iter);
            }
        }
Example #3
0
        private static bool AnalyzeHeapNode(NodeBlock block, DHeap node)
        {
            // Easy case: compiler needed a lvalue.
            if (node.uses.Count == 2)
            {
                DUse lastUse  = node.uses.Last();
                DUse firstUse = node.uses.First();
                if ((lastUse.node.type == NodeType.Call ||
                     lastUse.node.type == NodeType.SysReq) &&
                    firstUse.node.type == NodeType.Store &&
                    firstUse.index == 0)
                {
                    lastUse.node.replaceOperand(lastUse.index, firstUse.node.getOperand(1));
                    return(true);
                }

                if ((lastUse.node.type == NodeType.Call ||
                     lastUse.node.type == NodeType.SysReq) &&
                    firstUse.node.type == NodeType.MemCopy &&
                    firstUse.index == 0)
                {
                    // heap -> memcpy always reads from DAT + constant
                    DMemCopy     memcopy = (DMemCopy)firstUse.node;
                    DConstant    cv      = (DConstant)memcopy.from;
                    DInlineArray ia      = new DInlineArray(cv.value, memcopy.bytes);
                    block.nodes.insertAfter(node, ia);
                    lastUse.node.replaceOperand(lastUse.index, ia);

                    // Give the inline array some type information.
                    Signature signature = SignatureOf(lastUse.node);
                    TypeUnit  tu        = TypeUnit.FromArgument(signature.args[lastUse.index]);
                    ia.addType(tu);
                    return(true);
                }
            }

            return(false);
        }
Example #4
0
        private void renameBlock(NodeBlock block)
        {
            for (NodeList.iterator iter = block.nodes.begin(); iter.more();)
            {
                DNode node = iter.node;
                switch (node.type)
                {
                case NodeType.TempName:
                case NodeType.Jump:
                case NodeType.JumpCondition:
                case NodeType.Store:
                case NodeType.Return:
                case NodeType.IncDec:
                case NodeType.DeclareStatic:
                case NodeType.Switch:
                {
                    iter.next();
                    continue;
                }

                case NodeType.DeclareLocal:
                {
                    DDeclareLocal decl = (DDeclareLocal)node;
                    if (decl.var == null)
                    {
                        if (decl.uses.Count <= 1)
                        {
                            // This was probably just a stack temporary.
                            if (decl.uses.Count == 1)
                            {
                                DUse use = decl.uses.First.Value;
                                use.node.replaceOperand(use.index, decl.value);
                            }
                            block.nodes.remove(iter);
                            continue;
                        }
                        DTempName name = new DTempName(graph_.tempName());
                        node.replaceAllUsesWith(name);
                        name.init(decl.value);
                        block.nodes.replace(iter, name);
                    }
                    iter.next();
                    continue;
                }

                case NodeType.SysReq:
                case NodeType.Call:
                {
                    // Calls are statements or expressions, so we can't
                    // remove them if they have no uses.
                    if (node.uses.Count <= 1)
                    {
                        if (node.uses.Count == 1)
                        {
                            block.nodes.remove(iter);
                        }
                        else
                        {
                            iter.next();
                        }
                        continue;
                    }
                    break;
                }

                case NodeType.Constant:
                {
                    // Constants can be deeply copied.
                    block.nodes.remove(iter);
                    continue;
                }

                default:
                {
                    if (node.uses.Count <= 1)
                    {
                        // This node has one or zero uses, so instead of
                        // renaming it, we remove it from the instruction
                        // stream. This way the source printer will deep-
                        // print it instead of using its 'SSA' name.
                        block.nodes.remove(iter);
                        continue;
                    }

                    break;
                }
                }

                // If we've reached here, the expression has more than one use
                // and we have to wrap it in some kind of name, lest we
                // duplicate it in the expression tree which may be illegal.
                DTempName replacement = new DTempName(graph_.tempName());
                node.replaceAllUsesWith(replacement);
                replacement.init(node);
                block.nodes.replace(iter, replacement);
                iter.next();
            }
        }