Esempio n. 1
0
        private string buildLoadStoreRef(DNode node)
        {
            switch (node.type)
            {
            case NodeType.TempName:
            {
                DTempName temp = (DTempName)node;
                return(temp.name);
            }

            case NodeType.DeclareLocal:
            {
                DDeclareLocal local = (DDeclareLocal)node;
                return(local.var.name);
            }

            case NodeType.ArrayRef:
                return(buildArrayRef((DArrayRef)node));

            case NodeType.LocalRef:
            {
                DLocalRef     lref  = (DLocalRef)node;
                DDeclareLocal local = lref.local;
                if (local.var.type == VariableType.ArrayReference || local.var.type == VariableType.Array)
                {
                    return(local.var.name + "[0]");
                }
                if (local.var.type == VariableType.Reference)
                {
                    return(local.var.name);
                }
                throw new Exception("unknown local ref");
            }

            case NodeType.Global:
            {
                DGlobal global = (DGlobal)node;
                if (global.var == null)
                {
                    return("__unk");
                }
                return(global.var.name);
            }

            case NodeType.Load:
            {
                DLoad load = (DLoad)node;

                Debug.Assert(load.from.type == NodeType.DeclareLocal ||
                             load.from.type == NodeType.ArrayRef ||
                             load.from.type == NodeType.Global);
                return(buildLoadStoreRef(load.from));
            }

            default:
                throw new Exception("unknown load");
            }
        }
Esempio n. 2
0
 private void writeTempName(DTempName name)
 {
     if (name.getOperand(0) != null)
     {
         outputLine("int " + name.name + " = " + buildExpression(name.getOperand(0)) + ";");
     }
     else
     {
         outputLine("int " + name.name + ";");
     }
 }
Esempio n. 3
0
        public override void visit(DPhi phi)
        {
            // Convert a phi into a move on each incoming edge. Declare the
            // temporary name in the dominator.
            NodeBlock idom = graph_[phi.block.lir.idom.id];

            DTempName name = new DTempName(graph_.tempName());
            idom.prepend(name);

            for (int i = 0; i < phi.numOperands; i++)
            {
                DNode input = phi.getOperand(i);
                DStore store = new DStore(name, input);
                NodeBlock pred = graph_[phi.block.lir.getPredecessor(i).id];
                pred.prepend(store);
            }

            phi.replaceAllUsesWith(name);
        }
Esempio n. 4
0
        public override void visit(DPhi phi)
        {
            // Convert a phi into a move on each incoming edge. Declare the
            // temporary name in the dominator.
            var idom = graph_[phi.block.lir.idom.id];

            var name = new DTempName(graph_.tempName());

            idom.prepend(name);

            for (var i = 0; i < phi.numOperands; i++)
            {
                var input = phi.getOperand(i);
                var store = new DStore(name, input);
                var pred  = graph_[phi.block.lir.getPredecessor(i).id];
                pred.prepend(store);
            }

            phi.replaceAllUsesWith(name);
        }
Esempio n. 5
0
        private string buildExpression(DNode node)
        {
            switch (node.type)
            {
            case NodeType.Constant:
                return(buildConstant((DConstant)node));

            case NodeType.Boolean:
                return(buildBoolean((DBoolean)node));

            case NodeType.Float:
                return(buildFloat((DFloat)node));

            case NodeType.Character:
                return(buildCharacter((DCharacter)node));

            case NodeType.Function:
                return(buildFunction((DFunction)node));

            case NodeType.Load:
                return(buildLoad((DLoad)node));

            case NodeType.String:
                return(buildString(((DString)node).value));

            case NodeType.LocalRef:
                return(buildLocalRef((DLocalRef)node));

            case NodeType.ArrayRef:
                return(buildArrayRef((DArrayRef)node));

            case NodeType.Unary:
                return(buildUnary((DUnary)node));

            case NodeType.Binary:
                return(buildBinary((DBinary)node));

            case NodeType.SysReq:
                return(buildSysReq((DSysReq)node));

            case NodeType.Call:
                return(buildCall((DCall)node));

            case NodeType.DeclareLocal:
            {
                DDeclareLocal local = (DDeclareLocal)node;
                return(local.var.name);
            }

            case NodeType.TempName:
            {
                DTempName name = (DTempName)node;
                return(name.name);
            }

            case NodeType.Global:
            {
                DGlobal global = (DGlobal)node;
                return(global.var.name);
            }

            case NodeType.InlineArray:
            {
                return(buildInlineArray((DInlineArray)node));
            }

            default:
                throw new Exception("waT");
            }
        }
Esempio n. 6
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();
            }
        }
Esempio n. 7
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();
            }
        }
Esempio n. 8
0
 private void writeTempName(DTempName name)
 {
     if (name.getOperand(0) != null)
         outputLine("int " + name.name + " = " + buildExpression(name.getOperand(0)) + ";");
     else
         outputLine("int " + name.name + ";");
 }