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); }
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); } }
public override void visit(DGlobal global) { if (global.var == null) { return; } TypeUnit tu = TypeUnit.FromVariable(global.var); global.addType(tu); }
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)); } }
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()); }
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); } }
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); } } }
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); }
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); }
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))); } } }
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); }
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); }
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); }
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); }
public TypeUnit(TypeUnit other) { kind_ = Kind.Reference; ref_ = other; }
public void addType(TypeUnit tu) { //Debug.Assert(tu != null); ensureTypeSet().addType(tu); }
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); } }
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; }
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); }
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; }
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; }