Index: vm/jitrino/src/optimizer/simplifier.cpp =================================================================== --- vm/jitrino/src/optimizer/simplifier.cpp (revision 631140) +++ vm/jitrino/src/optimizer/simplifier.cpp (working copy) @@ -1795,6 +1795,21 @@ Modifier ovfmod, Opnd* src) { + // get rid of redundant conversion + Inst *opndInst = src->getInst(); + if (toType == opndInst->getType() && (dstType == src->getType())) { + return src; + } + ConstInst *cinst = opndInst->asConstInst(); + if (cinst) { + ConstInst::ConstValue srcval = cinst->getValue(); + ConstInst::ConstValue res; + Type::Tag fromType = opndInst->getType(); + if (ConstantFolder::foldConv(fromType, toType, ovfmod, srcval, res)) { + if (dstType->tag == toType) + return genLdConstant(dstType, res)->getDst(); + } + } return NULL; } @@ -1804,6 +1819,21 @@ Modifier ovfmod, Opnd* src) { + // get rid of redundant conversion + Inst *opndInst = src->getInst(); + if (toType == opndInst->getType() && (dstType == src->getType())) { + return src; + } + ConstInst *cinst = opndInst->asConstInst(); + if (cinst) { + ConstInst::ConstValue srcval = cinst->getValue(); + ConstInst::ConstValue res; + Type::Tag fromType = opndInst->getType(); + if (ConstantFolder::foldConv(fromType, toType, ovfmod, srcval, res)) { + if (dstType->tag == toType) + return genLdConstant(dstType, res)->getDst(); + } + } return NULL; } @@ -3127,8 +3157,9 @@ Opnd* Simplifier::simplifyAddScaledIndex(Opnd* base, Opnd* index) { ConstInst* constIndexInst = index->getInst()->asConstInst(); - if ((constIndexInst != NULL) && (index->getType()->tag == Type::Int32)) { - if (constIndexInst->getValue().i4 == 0) + if ( constIndexInst != NULL ) { + assert(index->getType()->isInteger()); + if (constIndexInst->getValue().i8 == 0) return base; } return NULL; Index: vm/jitrino/src/optimizer/constantfolder.cpp =================================================================== --- vm/jitrino/src/optimizer/constantfolder.cpp (revision 631140) +++ vm/jitrino/src/optimizer/constantfolder.cpp (working copy) @@ -549,118 +549,114 @@ bool ovfm = (mod.getOverflowModifier()!=Overflow_None); switch (toType) { case Type::Int32: - switch (fromType) { - case Type::Int32: - res.i4 = src.i4; return true; - case Type::UInt32: - res.i4 = src.i4; - if (ovfm && (src.i4 < 0)) return false; - return true; - case Type::Int64: - res.i4 = CAST(int32, src.i8); - if (ovfm && (src.i8 != CAST(int64, res.i4))) return false; - return true; - case Type::UInt64: - res.i4 = CAST(int32, CAST(uint64, src.i8)); - if (ovfm && (CAST(uint64, src.i8) != CAST(uint64, res.i4))) return false; - return true; - case Type::Single: +#ifndef PONTER64 + case Type::IntPtr: +#endif + if (Type::isInteger(fromType)) { + if (Type::isIntegerOf4Signed(fromType)) { + res.i4 = src.i4; return true; + } else if (Type::isIntegerOf4Unsigned(fromType)) { + res.i4 = src.i4; + if (ovfm && (src.i4 < 0)) return false; + return true; + } else if (Type::isIntegerOf8Signed(fromType)) { + res.i4 = CAST(int32, src.i8); + if (ovfm && (src.i8 != CAST(int64, res.i4))) return false; + return true; + } else if (Type::isIntegerOf8Unsigned(fromType)) { + res.i4 = CAST(int32, CAST(uint64, src.i8)); + if (ovfm && (CAST(uint64, src.i8) != CAST(uint64, res.i4))) return false; + return true; + } + assert(0); + } else if (fromType == Type::Single) { res.i4 = float2int(src.s); if (ovfm && (src.s != CAST(float, res.i4))) return false; return true; - case Type::Double: + } else if (fromType == Type::Double) { res.i4 = float2int(src.d); if (ovfm && (src.d != CAST(double, res.i4))) return false; return true; - case Type::Float: - default: - break; } break; case Type::UInt32: - switch (fromType) { - case Type::Int32: - if (ovfm && (src.i4 < 0)) return false; - res.i4 = src.i4; return true; - case Type::UInt32: - res.i4 = src.i4; return true; - case Type::Int64: - res.i4 = CAST(int32, CAST(uint32, src.i8)); - if (ovfm && (src.i8 != CAST(int64, CAST(uint32, res.i4)))) return false; - return true; - case Type::UInt64: - res.i4 = CAST(int32, CAST(uint32, CAST(uint64, src.i8))); - if (ovfm && (CAST(uint64, src.i8) != CAST(uint64, CAST(uint32, res.i4)))) - return false; - return true; - case Type::Single: +#ifndef PONTER64 + case Type::UIntPtr: +#endif + if (Type::isInteger(fromType)) { + if (Type::isIntegerOf4Bytes(fromType)) { + res.i4 = src.i4; return true; + } else if (Type::isIntegerOf8Signed(fromType)) { + res.i4 = CAST(int32, CAST(uint32, src.i8)); + if (ovfm && (src.i8 != CAST(int64, CAST(uint32, res.i4)))) return false; + return true; + } else if (Type::isIntegerOf8Unsigned(fromType)) { + res.i4 = CAST(int32, CAST(uint32, CAST(uint64, src.i8))); + if (ovfm && (CAST(uint64, src.i8) != CAST(uint64, CAST(uint32, res.i4)))) return false; + return true; + } + assert(0); + } else if (fromType == Type::Single) { res.i4 = float2uint(src.s); if (ovfm && (src.s != CAST(float, CAST(uint32, res.i4)))) return false; return true; - case Type::Double: + } else if (fromType == Type::Double) { res.i4 = float2uint(src.d); if (ovfm && (src.d != CAST(double, CAST(uint32, res.i4)))) return false; return true; - case Type::Float: - default: - break; } break; case Type::Int64: - if (ovfm) { assert(mod.getOverflowModifier()==Overflow_Signed); }; - switch (fromType) { - case Type::Int32: - res.i8 = src.i4; return true; - case Type::UInt32: - res.i8 = CAST(uint32, src.i4); - if (ovfm && (src.i4 < 0)) return false; - return true; - case Type::Int64: - res.i8 = src.i8; return true; - case Type::UInt64: - res.i8 = src.i8; - if (ovfm && (src.i8 < 0)) return false; - return true; - case Type::Single: +#ifdef PONTER64 + case Type::IntPtr: +#endif + assert(!ovfm || mod.getOverflowModifier()==Overflow_Signed); + if (Type::isInteger(fromType)) { + if (Type::isIntegerOf4Signed(fromType)) { + res.i8 = src.i4; return true; + } else if (Type::isIntegerOf4Unsigned(fromType)) { + res.i8 = CAST(uint32, src.i4); + if (ovfm && (src.i4 < 0)) return false; + return true; + } else if (Type::isIntegerOf8Signed(fromType)) { + res.i8 = src.i8; return true; + } else if (Type::isIntegerOf8Unsigned(fromType)) { + res.i8 = src.i8; + if (ovfm && (src.i8 < 0)) return false; + return true; + } + assert(0); + } else if (fromType == Type::Single) { res.i8 = float2int(src.s); if (ovfm && (src.s != CAST(float, res.i8))) return false; return true; - case Type::Double: + } else if (fromType == Type::Double) { res.i8 = float2int(src.d); if (ovfm && (src.d != CAST(double, res.i8))) return false; return true; - case Type::Float: - default: - break; } break; case Type::UInt64: - if (ovfm) { assert(mod.getOverflowModifier()==Overflow_Unsigned); }; - switch (fromType) { - case Type::Int32: - res.i8 = CAST(uint64, CAST(uint32, src.i4)); - if (ovfm && (src.i4 < 0)) return false; - return true; - case Type::UInt32: - res.i8 = CAST(uint64, CAST(uint32, src.i4)); return true; - case Type::Int64: - res.i8 = src.i8; - if (ovfm && (src.i8 < 0)) return false; - return true; - case Type::UInt64: - if (ovfm && (src.i8 < 0)) return false; - res.i8 = src.i8; return true; - case Type::Single: +#ifdef PONTER64 + case Type::UIntPtr: +#endif + assert(!ovfm || mod.getOverflowModifier()==Overflow_Unsigned); + if (Type::isInteger(fromType)) { + if (Type::isIntegerOf4Signed(fromType)) { + res.i8 = CAST(uint64, CAST(uint32, src.i4)); + if (ovfm && (src.i4 < 0)) return false; + return true; + } else if (Type::isIntegerOf4Unsigned(fromType)) { + res.i8 = CAST(uint64, CAST(uint32, src.i4)); return true; + } else if (Type::isIntegerOf8Bytes(fromType)) { + res.i8 = src.i8; return true; + } + } else if (fromType == Type::Single) { res.i8 = float2uint(src.s); - if (ovfm) { - return false; - } + if (ovfm) return false; return true; - case Type::Double: - return false; - case Type::Float: - default: - break; + } else if (fromType == Type::Double) { + return false; } break; case Type::Single: @@ -705,6 +701,16 @@ break; } break; + case Type::UnmanagedPtr: + // Let's accept the convertion from properly sized integer +#ifdef PONTER64 + if (Type::isIntegerOf8Bytes(fromType)) { +#else + if (Type::isIntegerOf4Bytes(fromType)) { +#endif + return true; + } + break; default: break; } Index: vm/jitrino/src/shared/Type.h =================================================================== --- vm/jitrino/src/shared/Type.h (revision 631140) +++ vm/jitrino/src/shared/Type.h (working copy) @@ -370,6 +370,22 @@ uint32 getId() { return id; } + // This is for switching integer types depending on the size +#ifdef POINTER64 + static bool isIntegerOf4Signed(Tag tag) { return tag == Int32; } + static bool isIntegerOf4Unsigned(Tag tag) { return tag == UInt32; } + static bool isIntegerOf8Signed(Tag tag) { return tag == Int64 || tag == IntPtr; } + static bool isIntegerOf8Unsigned(Tag tag) { return tag == UInt64 || tag == UIntPtr; } +#else + static bool isIntegerOf4Signed(Tag tag) { return tag == Int32 || tag == IntPtr; } + static bool isIntegerOf4Unsigned(Tag tag) { return tag == UInt32 || tag == UIntPtr; } + static bool isIntegerOf8Signed(Tag tag) { return tag == Int64; } + static bool isIntegerOf8Unsigned(Tag tag) { return tag == UInt64; } +#endif + static bool isIntegerOf4Bytes(Tag tag) { return isIntegerOf4Signed(tag) || isIntegerOf4Unsigned(tag); } + static bool isIntegerOf8Bytes(Tag tag) { return isIntegerOf8Signed(tag) || isIntegerOf8Unsigned(tag); } + + protected: virtual bool _isFinalClass() {return false;} Index: vm/jitrino/src/optimizer/escanalyzer.cpp =================================================================== --- vm/jitrino/src/optimizer/escanalyzer.cpp (revision 631140) +++ vm/jitrino/src/optimizer/escanalyzer.cpp (working copy) @@ -356,13 +356,16 @@ break; case Op_TauLdInd: // ldind { + Opnd* src = inst->getSrc(0); + if(src->getType()->isUnmanagedPtr()) + break; // skip load from unmanaged source type = inst->getDst()->getType(); if (type->isReference()) { //isObject()) { assert(findCnGNode_op(inst->getDst()->getId())==NULL); cgnode = addCnGNode_op(inst,type,NT_LDOBJ); exam2Insts->push_back(inst); } - if (inst->getSrc(0)->getInst()->getOpcode()==Op_LdStaticAddr) + if (src->getInst()->getOpcode()==Op_LdStaticAddr) break; if (type->isValue()) { assert(findCnGNode_op(inst->getDst()->getId())==NULL);