Beispiel #1
0
 public bool equalTo(TypeUnit other)
 {
     if (kind_ != other.kind_)
     {
         return(false);
     }
     if (kind_ == Kind.Array && dims_ != other.dims_)
     {
         return(false);
     }
     if (kind_ == Kind.Reference)
     {
         if ((ref_ == null) != (other.ref_ == null))
         {
             return(false);
         }
         if (ref_ != null && !ref_.equalTo(other.ref_))
         {
             return(false);
         }
     }
     else
     {
         if (!type_.equalTo(other.type_))
         {
             return(false);
         }
     }
     return(true);
 }
Beispiel #2
0
 public override void visit(DReturn ret)
 {
     if (graph_.function != null)
     {
         DNode    input = ret.getOperand(0);
         TypeUnit tu    = TypeUnit.FromTag(graph_.function.returnType);
         input.typeSet.addType(tu);
     }
 }
Beispiel #3
0
        public override void visit(DGlobal global)
        {
            if (global.var == null)
            {
                return;
            }

            TypeUnit tu = TypeUnit.FromVariable(global.var);

            global.addType(tu);
        }
Beispiel #4
0
        public override void visit(DDeclareLocal local)
        {
            Variable var = graph_.file.lookupVariable(local.pc, local.offset);

            local.setVariable(var);

            if (var != null)
            {
                TypeUnit tu = TypeUnit.FromVariable(var);
                //Debug.Assert(tu != null);
                local.addType(new TypeUnit(tu));
            }
        }
Beispiel #5
0
        private string buildConstant(DConstant node)
        {
            string prefix = "";

            if (node.typeSet.numTypes == 1)
            {
                TypeUnit tu = node.typeSet[0];
                if (tu.kind == TypeUnit.Kind.Cell && tu.type.type == CellType.Tag)
                {
                    prefix = tu.type.tag.name + " ";
                }
            }
            return(prefix + node.value.ToString());
        }
Beispiel #6
0
        public override void visit(DLoad load)
        {
            TypeSet fromTypes = load.from.typeSet;

            for (int i = 0; i < fromTypes.numTypes; i++)
            {
                TypeUnit tu     = fromTypes[i];
                TypeUnit actual = tu.load();
                if (actual == null)
                {
                    actual = tu;
                }
                load.addType(actual);
            }
        }
Beispiel #7
0
 public override void visit(DLoad load)
 {
     load.from.setUsedAsReference();
     if (load.from.typeSet != null && load.from.typeSet.numTypes == 1)
     {
         TypeUnit tu = load.from.typeSet[0];
         if (tu.kind == TypeUnit.Kind.Array)
         {
             DConstant cv   = new DConstant(0);
             DArrayRef aref = new DArrayRef(load.from, cv, 1);
             block_.nodes.insertAfter(load.from, cv);
             block_.nodes.insertAfter(cv, aref);
             load.replaceOperand(0, aref);
         }
     }
 }
Beispiel #8
0
 public void addType(TypeUnit tu)
 {
     if (types_ == null)
     {
         types_ = new List <TypeUnit>();
     }
     else
     {
         for (int i = 0; i < types_.Count; i++)
         {
             if (types_[i].equalTo(tu))
             {
                 return;
             }
         }
     }
     types_.Add(tu);
 }
Beispiel #9
0
        private DNode ConstantToReference(DConstant node, TypeUnit tu)
        {
            Variable global = graph_.file.lookupGlobal(node.value);

            if (global == null)
            {
                graph_.file.lookupVariable(node.pc, node.value, Scope.Static);
            }
            if (global != null)
            {
                return(new DGlobal(global));
            }

            if (tu != null && tu.type.isString)
            {
                return(new DString(graph_.file.stringFromData(node.value)));
            }
            return(null);
        }
Beispiel #10
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)));
                }
            }
        }
Beispiel #11
0
        private static bool IsArray(TypeSet ts)
        {
            if (ts == null)
            {
                return(false);
            }
            if (ts.numTypes != 1)
            {
                return(false);
            }
            TypeUnit tu = ts[0];

            if (tu.kind == TypeUnit.Kind.Array)
            {
                return(true);
            }
            if (tu.kind == TypeUnit.Kind.Reference && tu.inner.kind == TypeUnit.Kind.Array)
            {
                return(true);
            }
            return(false);
        }
Beispiel #12
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);
        }
Beispiel #13
0
        public static TypeUnit FromVariable(Variable var)
        {
            switch (var.type)
            {
            case VariableType.Normal:
                return(FromTag(var.tag));

            case VariableType.Array:
                return(new TypeUnit(new PawnType(var.tag), var.dims.Length));

            case VariableType.Reference:
            {
                TypeUnit tu = new TypeUnit(new PawnType(var.tag));
                return(new TypeUnit(tu));
            }

            case VariableType.ArrayReference:
            {
                TypeUnit tu = new TypeUnit(new PawnType(var.tag), var.dims.Length);
                return(new TypeUnit(tu));
            }
            }
            return(null);
        }
Beispiel #14
0
        private string buildInlineArray(DInlineArray ia)
        {
            Debug.Assert(ia.typeSet.numTypes == 1);
            TypeUnit tu = ia.typeSet[0];

            Debug.Assert(tu.kind == TypeUnit.Kind.Array);
            Debug.Assert(tu.dims == 1);

            if (tu.type.isString)
            {
                string s = file_.stringFromData(ia.address);
                return(buildString(s));
            }

            string text = "{";

            for (int i = 0; i < ia.size / 4; i++)
            {
                if (tu.type.type == CellType.Float)
                {
                    float f = file_.floatFromData(ia.address + i * 4);
                    text += f;
                }
                else
                {
                    int v = file_.int32FromData(ia.address);
                    text += buildTag(tu.type) + v;
                }
                if (i != (ia.size / 4) - 1)
                {
                    text += ",";
                }
            }
            text += "}";
            return(text);
        }
Beispiel #15
0
 public TypeUnit(TypeUnit other)
 {
     kind_ = Kind.Reference;
     ref_  = other;
 }
Beispiel #16
0
 public void addType(TypeUnit tu)
 {
     //Debug.Assert(tu != null);
     ensureTypeSet().addType(tu);
 }
Beispiel #17
0
        public override void visit(DConstant node)
        {
            DNode replacement = null;

            if (node.typeSet.numTypes == 1)
            {
                TypeUnit tu = node.typeSet[0];
                switch (tu.kind)
                {
                case TypeUnit.Kind.Cell:
                {
                    switch (tu.type.type)
                    {
                    case CellType.Bool:
                        replacement = new DBoolean(node.value != 0);
                        break;

                    case CellType.Character:
                        replacement = new DCharacter(Convert.ToChar(node.value));
                        break;

                    case CellType.Float:
                    {
                        //Debug.Assert(BitConverter.IsLittleEndian);
                        byte[] bits = BitConverter.GetBytes(node.value);
                        float  v    = BitConverter.ToSingle(bits, 0);
                        replacement = new DFloat(v);
                        break;
                    }

                    case CellType.Function:
                    {
                        Public   p        = graph_.file.publics[node.value >> 1];
                        Function function = graph_.file.lookupFunction(p.address);
                        replacement = new DFunction(p.address, function);
                        break;
                    }

                    default:
                        return;
                    }
                    break;
                }

                case TypeUnit.Kind.Array:
                {
                    replacement = ConstantToReference(node, tu);
                    break;
                }

                default:
                    return;
                }
            }

            if (replacement == null && node.usedAsReference)
            {
                replacement = ConstantToReference(node, null);
            }
            if (replacement != null)
            {
                block_.nodes.insertAfter(node, replacement);
                node.replaceAllUsesWith(replacement);
            }
        }
Beispiel #18
0
        private DNode ConstantToReference(DConstant node, TypeUnit tu)
        {
            Variable global = graph_.file.lookupGlobal(node.value);
            if (global == null)
                graph_.file.lookupVariable(node.pc, node.value, Scope.Static);
            if (global != null)
                return new DGlobal(global);

            if (tu != null && tu.type.isString)
                return new DString(graph_.file.stringFromData(node.value));
            return null;
        }
Beispiel #19
0
 public void addType(TypeUnit tu)
 {
     //Debug.Assert(tu != null);
     ensureTypeSet().addType(tu);
 }
Beispiel #20
0
 public void addType(TypeUnit tu)
 {
     if (types_ == null)
     {
         types_ = new List<TypeUnit>();
     }
     else
     {
         for (int i = 0; i < types_.Count; i++)
         {
             if (types_[i].equalTo(tu))
                 return;
         }
     }
     types_.Add(tu);
 }
Beispiel #21
0
 public static TypeUnit FromVariable(Variable var)
 {
     switch (var.type)
     {
         case VariableType.Normal:
             return FromTag(var.tag);
         case VariableType.Array:
             return new TypeUnit(new PawnType(var.tag), var.dims.Length);
         case VariableType.Reference:
         {
             TypeUnit tu = new TypeUnit(new PawnType(var.tag));
             return new TypeUnit(tu);
         }
         case VariableType.ArrayReference:
         {
             TypeUnit tu = new TypeUnit(new PawnType(var.tag), var.dims.Length);
             return new TypeUnit(tu);
         }
     }
     return null;
 }
Beispiel #22
0
 public bool equalTo(TypeUnit other)
 {
     if (kind_ != other.kind_)
         return false;
     if (kind_ == Kind.Array && dims_ != other.dims_)
         return false;
     if (kind_ == Kind.Reference)
     {
         if ((ref_ == null) != (other.ref_ == null))
             return false;
         if (ref_ != null && !ref_.equalTo(other.ref_))
             return false;
     }
     else
     {
         if (!type_.equalTo(other.type_))
             return false;
     }
     return true;
 }
Beispiel #23
0
 public TypeUnit(TypeUnit other)
 {
     kind_ = Kind.Reference;
     ref_ = other;
 }