Commit f2aac08e authored by Kunshan Wang's avatar Kunshan Wang

Type inferer as class, and stricter static check.

Type inferer and predefined entities are no longer single objects.  They
can be instantiated like other classes.

An SSA variable now has an `inferred type` field which represents its
type.  The type is filled in when loading a bundle, and can be dependedn
on during execution.

Added stricter static checking related to variable types.
parent fb6c7513
......@@ -65,6 +65,8 @@ class MicroVM private (val vmConf: VMConf, val allArgs: Option[Seq[String]]) ext
val stats = new VMStats()
val staticAnalyzer = new StaticAnalyzer()
val globalBundle = new GlobalBundle()
val constantPool = new ConstantPool()
......@@ -76,7 +78,7 @@ class MicroVM private (val vmConf: VMConf, val allArgs: Option[Seq[String]]) ext
// BYTES, BYTES_R, REFS, REFS_R: Types for the @uvm.meta.* common instructions.
import InternalTypes._
import staticAnalyzer.predefinedEntities._
for (ty <- Seq(VOID, BYTE, BYTE_ARRAY, BYTES, BYTES_R, REFS, REFS_R)) {
globalBundle.typeNs.add(ty)
}
......@@ -93,6 +95,9 @@ class MicroVM private (val vmConf: VMConf, val allArgs: Option[Seq[String]]) ext
for (ty <- Seq(C_INT, C_CHAR, C_CHARP, C_CHARPP)) {
globalBundle.typeNs.add(ty)
}
// Perform type inference on all preloaded s
staticAnalyzer.typeInferer.inferBundle(globalBundle)
}
/**
......@@ -126,7 +131,6 @@ class MicroVM private (val vmConf: VMConf, val allArgs: Option[Seq[String]]) ext
val irBuilderRegistry = new IDObjectKeeper[IRBuilder]("IR builder")
val irReader = new UIRTextReader(idFactory, recordSourceInfo = vmConf.sourceInfo)
val hailScriptLoader = new HailScriptLoader(recordSourceInfo = vmConf.sourceInfo)
val staticAnalyzer = new StaticAnalyzer()
val bootImageBuilder = new BootImageBuilder()
......@@ -151,13 +155,16 @@ class MicroVM private (val vmConf: VMConf, val allArgs: Option[Seq[String]]) ext
* Add things from a bundle to the Micro VM.
*/
def addBundle(bundle: TrantientBundle) {
// Make sure all SSA variables have undergone type inference
staticAnalyzer.typeInferer.inferBundle(bundle)
if (vmConf.dumpBundle) {
val dbs = new DebugBundleSerializer(bundle)
dbs.writeUIR(new OutputStreamWriter(System.err))
}
if (vmConf.staticCheck) {
staticAnalyzer.checkBundle(bundle, Some(globalBundle))
staticAnalyzer.bundleChecker.checkBundle(bundle, Some(globalBundle))
}
globalBundle.merge(bundle);
......
This diff is collapsed.
......@@ -14,27 +14,26 @@ import java.util.zip.ZipFile
import scala.collection.Map
import scala.collection.mutable.HashMap
import org.slf4j.LoggerFactory
import com.typesafe.scalalogging.Logger
import uvm.{ MuID, MuName }
import uvm.refimpl.{ Word, WORD_SIZE_BYTES }
import uvm.refimpl.{ WORD_SIZE_BYTES, Word }
import uvm.refimpl.MicroVM
import uvm.refimpl.cmdline.NativeArgv
import uvm.refimpl.itpr.BoxInt
import uvm.refimpl.itpr.BoxPointer
import uvm.refimpl.itpr.HowToResume
import uvm.refimpl.itpr.OpHelper
import uvm.refimpl.mem.HeaderUtils
import uvm.refimpl.mem.TypeSizes
import uvm.refimpl.nat.NativeSupport
import uvm.types.TypeHybrid
import uvm.utils.IOHelpers
import uvm.utils.IOHelpers.forEachLine
import uvm.utils.MappedIDFactory
import uvm.utils.WithUtils.tryWithResource
import scala.collection.mutable.ArrayBuffer
import uvm.refimpl.itpr.HowToResume
import uvm.refimpl.cmdline.NativeArgv
import uvm.refimpl.itpr.BoxInt
import uvm.refimpl.InternalTypePool
import uvm.refimpl.InternalTypes
import uvm.refimpl.itpr.BoxPointer
import uvm.utils.IOHelpers
import com.typesafe.scalalogging.Logger
import org.slf4j.LoggerFactory
import uvm.refimpl.mem.HeaderUtils
object BootImageLoader {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
......@@ -44,8 +43,8 @@ object BootImageLoader {
}
class BootImageLoader(file: String, maybeAllArgs: Option[Seq[String]])(implicit microVM: MicroVM) extends AutoCloseable {
import BootImageLoader._
import BootImageFile._
import BootImageLoader._
private val globalBundle = microVM.globalBundle
private val memoryManager = microVM.memoryManager
......
package uvm.refimpl.cmdline
import java.io.BufferedReader
import java.io.InputStreamReader
import java.nio.charset.StandardCharsets
import java.util.zip.ZipFile
import scala.collection.mutable.HashMap
import uvm.{MuID, MuName}
import uvm.refimpl.HowToResume.PassValues
import uvm.refimpl.InternalTypes
import uvm.refimpl.MicroVM
import uvm.refimpl.UvmRuntimeException
import uvm.refimpl.VMConf
import uvm.refimpl.WORD_SIZE_BYTES
import uvm.refimpl.nat.NativeSupport
import uvm.utils.WithUtils.tryWithResource
/** Run Mu from the command line. */
......
......@@ -70,6 +70,8 @@ class InstanceHailScriptLoader(microVM: MicroVM, memorySupport: MemorySupport, m
val recordSourceInfo: Boolean) extends AdvancedAntlrHelper {
import HailScriptLoader._
private val predefinedEntities = microVM.staticAnalyzer.predefinedEntities
val sourceLines = source.lines.toIndexedSeq
private type HailObjMap = HashMap[HailName, MuRefValue]
......@@ -229,7 +231,7 @@ class InstanceHailScriptLoader(microVM: MicroVM, memorySupport: MemorySupport, m
def unexpectedGlobalTypeError(gv: GlobalVariable): Nothing = {
throw new UvmHailParsingException(inCtx(rv, "Unsuitable global variable type. Expected: %s, Found: %s".format(
lty, TypeInferer.inferType(gv))))
lty, gv.inferredType)))
}
// Reused by their types as well as tagref64
......@@ -254,7 +256,7 @@ class InstanceHailScriptLoader(microVM: MicroVM, memorySupport: MemorySupport, m
def resForRefType(rv: RValueContext): (MuRefValue, Boolean) = {
rv match {
case nu: RVNullContext => (mc.handleFromConst(InternalTypes.NULL_REF_VOID.id).asInstanceOf[MuRefValue], true)
case nu: RVNullContext => (mc.handleFromConst(predefinedEntities.NULL_REF_VOID.id).asInstanceOf[MuRefValue], true)
case hr: RVHailRefContext => (resRVHailRef(hr), false)
case _ => unexpectedRValueError()
}
......@@ -367,7 +369,7 @@ class InstanceHailScriptLoader(microVM: MicroVM, memorySupport: MemorySupport, m
}
case t: TypeIRef => {
val hr = rv match {
case nu: RVNullContext => mc.handleFromConst(InternalTypes.NULL_IREF_VOID.id)
case nu: RVNullContext => mc.handleFromConst(predefinedEntities.NULL_IREF_VOID.id)
case io: RVIRefOfContext => evalLValue(io.lValue()).iref
case RVGlobalOf(gv: GlobalCell) => mc.handleFromGlobal(gv.id)
case RVGlobalOf(gv) => unexpectedGlobalTypeError(gv)
......@@ -378,7 +380,7 @@ class InstanceHailScriptLoader(microVM: MicroVM, memorySupport: MemorySupport, m
}
case t: TypeFuncRef => {
val hr = rv match {
case nu: RVNullContext => mc.handleFromConst(InternalTypes.NULL_FUNCREF_VV.id)
case nu: RVNullContext => mc.handleFromConst(predefinedEntities.NULL_FUNCREF_VV.id)
case RVGlobalOf(gv: Function) => mc.handleFromFunc(gv.id)
case RVGlobalOf(gv) => unexpectedGlobalTypeError(gv)
case _ => unexpectedRValueError()
......@@ -388,7 +390,7 @@ class InstanceHailScriptLoader(microVM: MicroVM, memorySupport: MemorySupport, m
}
case t: TypeThreadRef => {
val hr = rv match {
case nu: RVNullContext => mc.handleFromConst(InternalTypes.NULL_THREADREF.id)
case nu: RVNullContext => mc.handleFromConst(predefinedEntities.NULL_THREADREF.id)
case _ => unexpectedRValueError()
}
mc.store(NOT_ATOMIC, lir, hr)
......@@ -396,7 +398,7 @@ class InstanceHailScriptLoader(microVM: MicroVM, memorySupport: MemorySupport, m
}
case t: TypeStackRef => {
val hr = rv match {
case nu: RVNullContext => mc.handleFromConst(InternalTypes.NULL_STACKREF.id)
case nu: RVNullContext => mc.handleFromConst(predefinedEntities.NULL_STACKREF.id)
case _ => unexpectedRValueError()
}
mc.store(NOT_ATOMIC, lir, hr)
......
......@@ -17,6 +17,8 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
implicit protected def microVM: MicroVM
implicit protected def memorySupport: MemorySupport
private def internalEntityPool = microVM.staticAnalyzer.internalEntityPool
/** Interpret the current instruction. */
protected def interpretCurrentInstruction(): Unit = try {
logger.debug(ctx + "Executing instruction...")
......@@ -459,7 +461,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
}
case i @ InstLoad(ptr, ord, referentTy, loc, excClause) => {
val uty = InternalTypePool.unmarkedOf(referentTy)
val uty = internalEntityPool.unmarkedOf(referentTy)
val ib = resultBox(0)
val addr = addressOf(ptr, loc)
......@@ -472,7 +474,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
}
case i @ InstStore(ptr, ord, referentTy, loc, newVal, excClause) => {
val uty = InternalTypePool.unmarkedOf(referentTy)
val uty = internalEntityPool.unmarkedOf(referentTy)
val nvb = boxOf(newVal)
val addr = addressOf(ptr, loc)
......@@ -485,7 +487,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
}
case i @ InstCmpXchg(ptr, weak, ordSucc, ordFail, referentTy, loc, expected, desired, excClause) => {
val uty = InternalTypePool.unmarkedOf(referentTy)
val uty = internalEntityPool.unmarkedOf(referentTy)
val eb = boxOf(expected)
val db = boxOf(desired)
val br = resultBox(0)
......@@ -502,7 +504,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
}
case i @ InstAtomicRMW(ptr, ord, op, referentTy, loc, opnd, excClause) => {
val uty = InternalTypePool.unmarkedOf(referentTy)
val uty = internalEntityPool.unmarkedOf(referentTy)
val ob = boxOf(opnd)
val ib = resultBox(0)
......
......@@ -715,10 +715,10 @@ object MemoryOperations {
*
* @return The address of the allocated object.
*/
def strToBytes(str: String)(implicit memorySupport: MemorySupport, mutator: Mutator): Word = {
def strToBytes(str: String)(implicit microVM: MicroVM, memorySupport: MemorySupport, mutator: Mutator): Word = {
val bytes = str.getBytes(US_ASCII)
val len = bytes.length
val loc = mutator.newHybrid(InternalTypes.BYTES, len)
val loc = mutator.newHybrid(microVM.staticAnalyzer.predefinedEntities.BYTES, len)
memorySupport.storeLong(loc, bytes.length.toLong)
val begin = loc + WORD_SIZE_BYTES
memorySupport.storeBytes(begin, bytes, 0, len, true)
......
......@@ -515,7 +515,7 @@ class DefinedMuFrame(
}
private def putBox(lv: LocalVariable) {
val ty = TypeInferer.inferType(lv)
val ty = lv.inferredType
try {
boxes.put(lv, ValueBox.makeBoxForType(ty))
} catch {
......
......@@ -52,7 +52,7 @@ class MemoryManager(val vmConf: VMConf)(implicit microVM: MicroVM) extends AutoC
def makeMutator(name: String): Mutator = heap.makeMutator(name)
def makeStackMemory(mutator: Mutator): StackMemory = {
val objRef = mutator.newHybrid(InternalTypes.BYTE_ARRAY, vmConf.stackSize)
val objRef = mutator.newHybrid(microVM.staticAnalyzer.predefinedEntities.BYTE_ARRAY, vmConf.stackSize)
val stackMemory = new StackMemory(objRef, vmConf.stackSize)
stackMemory
}
......
......@@ -6,7 +6,14 @@ import uvm._
import uvm.comminsts._
import uvm.types._
abstract class SSAVariable extends ChildNode
abstract class SSAVariable extends ChildNode {
/**
* The type is discovered by the static analyser at bundle loading time.
* During the execution of Mu IR programs, the MicroVM implementation can
* assume this field is already assigned.
*/
var inferredType: Type = null
}
// Global variables: Constants, Global Cells and Functions (Function is defined in controlFlow.scala)
......
This diff is collapsed.
package uvm.staticanalysis
import uvm.types._
import uvm.utils.LazyPool
class InternalEntityPool {
val intOf = LazyPool(TypeInt)
val refOf = LazyPool(TypeRef)
val irefOf = LazyPool(TypeIRef)
val ptrOf = LazyPool(TypeUPtr)
val funcOf = LazyPool(TypeFuncRef)
val funcPtrOf = LazyPool(TypeUFuncPtr)
val vecOf = LazyPool[(Type, Long), TypeVector] { case (t, l) => TypeVector(t, l) }
def unmarkedOf(t: Type): Type = t match {
case TypeWeakRef(r) => refOf(r)
case _ => t
}
}
\ No newline at end of file
package uvm.staticanalysis
import uvm._
import uvm.ssavariables._
import uvm.types._
import uvm.utils.IDFactory
class PredefinedEntities(privateIDFactory: IDFactory) {
import uvm.RichIdentifiedSettable._
def internal(name: MuName): (MuID, MuName) = {
val id = privateIDFactory.getID()
val n = "@uvm.internal.types." + name
(id, n)
}
val C_INT = TypeInt(32) := internal("c_int")
val C_CHAR = TypeInt(8) := internal("c_char")
val C_CHARP = TypeUPtr(C_CHAR) := internal("c_charp")
val C_CHARPP = TypeUPtr(C_CHARP) := internal("c_charpp")
val I1 = TypeInt(1) := internal("i1")
val I6 = TypeInt(6) := internal("i6")
val I8 = TypeInt(6) := internal("i8")
val I16 = TypeInt(6) := internal("i16")
val I32 = TypeInt(32) := internal("i32")
val I52 = TypeInt(52) := internal("i52")
val I64 = TypeInt(52) := internal("i64")
val FLOAT = TypeFloat() := internal("float")
val DOUBLE = TypeDouble() := internal("double")
val VOID = TypeVoid() := internal("void")
val BYTE = TypeInt(8) := internal("byte")
val BYTE_ARRAY = TypeHybrid(Seq(), BYTE) := internal("byte_array")
val REF_VOID = TypeRef(VOID) := internal("ref_void")
val IREF_VOID = TypeIRef(VOID) := internal("iref_void")
val SIG_VV = FuncSig(Seq(), Seq()) := internal("sig_vv")
val FUNCREF_VV = TypeFuncRef(SIG_VV) := internal("funcref_vv")
val STACKREF = TypeStackRef() := internal("stackref")
val THREADREF = TypeThreadRef() := internal("threadref")
val FRAMECURSORREF = TypeFrameCursorRef() := internal("framecursorref")
val IRBUILDERREF = TypeIRBuilderRef() := internal("irbuilderref")
val TAGREF64 = TypeTagRef64() := internal("tagref64")
val BYTES = TypeHybrid(Seq(I64), I8) := (0x260, "@uvm.meta.bytes")
val BYTES_R = TypeRef(BYTES) := (0x261, "@uvm.meta.bytes_r")
val REFS = TypeHybrid(Seq(I64), REF_VOID) := (0x262, "@uvm.meta.refs")
val REFS_R = TypeRef(BYTES) := (0x263, "@uvm.meta.refs_r")
val NULL_REF_VOID = ConstNull(REF_VOID) := internal("null_ref_void")
val NULL_IREF_VOID = ConstNull(IREF_VOID) := internal("null_iref_void")
val NULL_FUNCREF_VV = ConstNull(FUNCREF_VV) := internal("null_funcref_vv")
val NULL_THREADREF = ConstNull(THREADREF) := internal("null_threadref")
val NULL_STACKREF = ConstNull(STACKREF) := internal("null_stackref")
}
\ No newline at end of file
package uvm.refimpl
package uvm.staticanalysis
import uvm._
import uvm.FuncSig
import uvm.ssavariables._
import uvm.types._
import uvm.utils.IDFactory
import uvm.utils.LazyPool
import uvm.ssavariables._
object InternalTypes {
import uvm.RichIdentifiedSettable._
val privateIDFactory = IDFactory.newPrivateIDFactory() // IDs from 32768-65535 are for implementation internal use.
class TypeInferer(
predefinedEntities: PredefinedEntities,
internalEntityPool: InternalEntityPool) {
import predefinedEntities._
import internalEntityPool._
def internal(name: MuName): (MuID, MuName) = {
val id = privateIDFactory.getID()
val n = "@uvm.internal.types." + name
(id, n)
def ptrOrIRefOf(ptr: Boolean, ty: Type): Type = {
if (ptr) ptrOf(ty) else irefOf(ty)
}
val C_INT = TypeInt(32) := internal("c_int")
val C_CHAR = TypeInt(8) := internal("c_char")
val C_CHARP = TypeUPtr(C_CHAR) := internal("c_charp")
val C_CHARPP = TypeUPtr(C_CHARP) := internal("c_charpp")
val I1 = TypeInt(1) := internal("i1")
val I6 = TypeInt(6) := internal("i6")
val I8 = TypeInt(6) := internal("i8")
val I16 = TypeInt(6) := internal("i16")
val I32 = TypeInt(32) := internal("i32")
val I52 = TypeInt(52) := internal("i52")
val I64 = TypeInt(52) := internal("i64")
val FLOAT = TypeFloat() := internal("float")
val DOUBLE = TypeDouble() := internal("double")
val VOID = TypeVoid() := internal("void")
val BYTE = TypeInt(8) := internal("byte")
val BYTE_ARRAY = TypeHybrid(Seq(), BYTE) := internal("byte_array")
val REF_VOID = TypeRef(VOID) := internal("ref_void")
val IREF_VOID = TypeIRef(VOID) := internal("iref_void")
val SIG_VV = FuncSig(Seq(), Seq()) := internal("sig_vv")
val FUNCREF_VV = TypeFuncRef(SIG_VV) := internal("funcref_vv")
val STACKREF = TypeStackRef() := internal("stackref")
val THREADREF = TypeThreadRef() := internal("threadref")
val FRAMECURSORREF = TypeFrameCursorRef() := internal("framecursorref")
val IRBUILDERREF = TypeIRBuilderRef() := internal("irbuilderref")
val TAGREF64 = TypeTagRef64() := internal("tagref64")
val BYTES = TypeHybrid(Seq(I64), I8) := (0x260, "@uvm.meta.bytes")
val BYTES_R = TypeRef(BYTES) := (0x261, "@uvm.meta.bytes_r")
val REFS = TypeHybrid(Seq(I64), REF_VOID) := (0x262, "@uvm.meta.refs")
val REFS_R = TypeRef(BYTES) := (0x263, "@uvm.meta.refs_r")
val NULL_REF_VOID = ConstNull(REF_VOID) := internal("null_ref_void")
val NULL_IREF_VOID = ConstNull(IREF_VOID) := internal("null_iref_void")
val NULL_FUNCREF_VV = ConstNull(FUNCREF_VV) := internal("null_funcref_vv")
val NULL_THREADREF = ConstNull(THREADREF) := internal("null_threadref")
val NULL_STACKREF = ConstNull(STACKREF) := internal("null_stackref")
}
object InternalTypePool {
val intOf = LazyPool(TypeInt)
val refOf = LazyPool(TypeRef)
val irefOf = LazyPool(TypeIRef)
val ptrOf = LazyPool(TypeUPtr)
val funcOf = LazyPool(TypeFuncRef)
val funcPtrOf = LazyPool(TypeUFuncPtr)
val vecOf = LazyPool[(Type, Long), TypeVector] { case (t, l) => TypeVector(t, l) }
def unmarkedOf(t: Type): Type = t match {
case TypeWeakRef(r) => refOf(r)
case _ => t
/**
* Perform type inference on all entities, global or local, in the bundle b.
*/
def inferBundle(b: Bundle): Unit = {
for (v <- b.globalVarNs.all) {
inferAndSet(v)
}
}
object TypeInferer {
import InternalTypePool._
import InternalTypes._
for (fv <- b.funcVerNs.all) {
for (bb <- fv.bbs) {
for (v <- bb.localVarNs.all) {
inferAndSet(v)
}
}
}
}
def ptrOrIRefOf(ptr: Boolean, ty: Type): Type = {
if (ptr) ptrOf(ty) else irefOf(ty)
private def inferAndSet(v: SSAVariable): Unit = {
val inferredType = inferType(v)
v.inferredType = inferredType
}
def inferType(v: SSAVariable): Type = v match {
......@@ -95,7 +49,7 @@ object TypeInferer {
try {
resTys(r.index)
} catch {
case e: IndexOutOfBoundsException => throw new UvmRefImplException(
case e: IndexOutOfBoundsException => throw new StaticAnalyserException(
s"Instruction ${r.inst} produces only ${resTys.size} results, but result index ${r.index} is requested")
}
}
......
package uvm.staticanalysis
import uvm.UvmException
class StaticAnalyserException(message: String = null, cause: Throwable = null) extends UvmException(message, cause)
\ No newline at end of file
......@@ -6,6 +6,9 @@ abstract class Type extends TopLevel {
override final def toString: String = Type.prettyPrint(this)
}
abstract trait AbstractEQComparableType extends Type
abstract trait AbstractULTComparableType extends Type
abstract class AbstractFPType extends Type
abstract class AbstractGenRefType extends Type
......@@ -16,7 +19,7 @@ abstract class AbstractRefType extends AbstractGenRefType {
abstract class AbstractObjRefType extends AbstractRefType
abstract class AbstractOpaqueRefType extends AbstractGenRefType
abstract class AbstractOpaqueRefType extends AbstractGenRefType with AbstractEQComparableType
abstract class AbstractCompositeType extends Type
......@@ -29,9 +32,9 @@ abstract class AbstractSeqType extends AbstractCompositeType {
def len: Long
}
abstract class AbstractPointerType extends Type
abstract class AbstractPointerType extends Type with AbstractEQComparableType with AbstractULTComparableType
case class TypeInt(var length: Int) extends Type
case class TypeInt(var length: Int) extends Type with AbstractEQComparableType with AbstractULTComparableType
case class TypeFloat() extends AbstractFPType
case class TypeDouble() extends AbstractFPType
case class TypeUPtr(var ty: Type) extends AbstractPointerType
......@@ -41,10 +44,10 @@ case class TypeHybrid(var fieldTys: Seq[Type], var varTy: Type) extends Abstract
case class TypeArray(var elemTy: Type, var len: Long) extends AbstractSeqType
case class TypeVector(var elemTy: Type, var len: Long) extends AbstractSeqType
case class TypeVoid() extends Type
case class TypeRef(var ty: Type) extends AbstractObjRefType
case class TypeIRef(var ty: Type) extends AbstractRefType
case class TypeRef(var ty: Type) extends AbstractObjRefType with AbstractEQComparableType
case class TypeIRef(var ty: Type) extends AbstractRefType with AbstractEQComparableType with AbstractULTComparableType
case class TypeWeakRef(var ty: Type) extends AbstractObjRefType
case class TypeTagRef64() extends Type
case class TypeTagRef64() extends Type with AbstractEQComparableType
case class TypeFuncRef(var sig: FuncSig) extends AbstractOpaqueRefType
case class TypeThreadRef() extends AbstractOpaqueRefType
case class TypeStackRef() extends AbstractOpaqueRefType
......
......@@ -33,6 +33,8 @@ class UvmHailBasicTest extends UvmHailTesterBase {
it should "create objects of primitive types and assign to global cells" in {
val mc = microVM.newContext()
val predefinedEntities = microVM.staticAnalyzer.predefinedEntities
loadHailFromFile(mc, "tests/uvm-hail-test/basic-hail-test.hail")
mc.loadIntGlobal("@g_ri8") shouldBe 0x5a
......@@ -42,12 +44,12 @@ class UvmHailBasicTest extends UvmHailTesterBase {
mc.loadFloatGlobal("@g_rfloat") shouldBe 3.14F
mc.loadDoubleGlobal("@g_rdouble") shouldBe 6.28
mc.refEq(mc.loadRefGlobal("@g_rrv"), mc.handleFromConst(InternalTypes.NULL_REF_VOID.id).asInstanceOf[MuGenRefValue]) shouldBe true
mc.refEq(mc.loadIRefGlobal("@g_rirv"), mc.handleFromConst(InternalTypes.NULL_IREF_VOID.id).asInstanceOf[MuGenRefValue]) shouldBe true
mc.refEq(mc.loadRefGlobal("@g_rwrv"), mc.handleFromConst(InternalTypes.NULL_REF_VOID.id).asInstanceOf[MuGenRefValue]) shouldBe true
mc.refEq(mc.loadFuncRefGlobal("@g_rfrv_v"), mc.handleFromConst(InternalTypes.NULL_FUNCREF_VV.id).asInstanceOf[MuGenRefValue]) shouldBe true
mc.refEq(mc.loadThreadRefGlobal("@g_rthread"), mc.handleFromConst(InternalTypes.NULL_THREADREF.id).asInstanceOf[MuGenRefValue]) shouldBe true
mc.refEq(mc.loadStackRefGlobal("@g_rstack"), mc.handleFromConst(InternalTypes.NULL_STACKREF.id).asInstanceOf[MuGenRefValue]) shouldBe true
mc.refEq(mc.loadRefGlobal("@g_rrv"), mc.handleFromConst(predefinedEntities.NULL_REF_VOID.id).asInstanceOf[MuGenRefValue]) shouldBe true
mc.refEq(mc.loadIRefGlobal("@g_rirv"), mc.handleFromConst(predefinedEntities.NULL_IREF_VOID.id).asInstanceOf[MuGenRefValue]) shouldBe true
mc.refEq(mc.loadRefGlobal("@g_rwrv"), mc.handleFromConst(predefinedEntities.NULL_REF_VOID.id).asInstanceOf[MuGenRefValue]) shouldBe true
mc.refEq(mc.loadFuncRefGlobal("@g_rfrv_v"), mc.handleFromConst(predefinedEntities.NULL_FUNCREF_VV.id).asInstanceOf[MuGenRefValue]) shouldBe true
mc.refEq(mc.loadThreadRefGlobal("@g_rthread"), mc.handleFromConst(predefinedEntities.NULL_THREADREF.id).asInstanceOf[MuGenRefValue]) shouldBe true
mc.refEq(mc.loadStackRefGlobal("@g_rstack"), mc.handleFromConst(predefinedEntities.NULL_STACKREF.id).asInstanceOf[MuGenRefValue]) shouldBe true
mc.closeContext()
}
......
......@@ -484,7 +484,7 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
val a1 = ctx.handleFromPtr("@ptri64", 2)
testFunc(ctx, func, Seq(a0, a1)) { (ctx, th, st, wp) =>
val Seq(eq, ne, ult, ule, ugt, uge, slt, sle, sgt, sge) = ctx.dumpKeepalives(st, 0)
val Seq(eq, ne, ult, ule, ugt, uge) = ctx.dumpKeepalives(st, 0)
eq.vb.asUInt(1) shouldEqual 0
ne.vb.asUInt(1) shouldEqual 1
......@@ -492,16 +492,12 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
ule.vb.asUInt(1) shouldEqual 1
ugt.vb.asUInt(1) shouldEqual 0
uge.vb.asUInt(1) shouldEqual 0
slt.vb.asUInt(1) shouldEqual 1
sle.vb.asUInt(1) shouldEqual 1
sgt.vb.asUInt(1) shouldEqual 0
sge.vb.asUInt(1) shouldEqual 0
Rebind(st, PassValues(Seq()))
}
testFunc(ctx, func, Seq(a0, a0)) { (ctx, th, st, wp) =>
val Seq(eq, ne, ult, ule, ugt, uge, slt, sle, sgt, sge) = ctx.dumpKeepalives(st, 0)
val Seq(eq, ne, ult, ule, ugt, uge) = ctx.dumpKeepalives(st, 0)
eq.vb.asUInt(1) shouldEqual 1
ne.vb.asUInt(1) shouldEqual 0
......@@ -509,25 +505,6 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
ule.vb.asUInt(1) shouldEqual 1
ugt.vb.asUInt(1) shouldEqual 0
uge.vb.asUInt(1) shouldEqual 1
slt.vb.asUInt(1) shouldEqual 0
sle.vb.asUInt(1) shouldEqual 1
sgt.vb.asUInt(1) shouldEqual 0
sge.vb.asUInt(1) shouldEqual 1
Rebind(st, PassValues(Seq()))
}
val a2 = ctx.handleFromPtr("@ptri64", -3)
testFunc(ctx, func, Seq(a0, a2)) { (ctx, th, st, wp) =>
val Seq(eq, ne, ult, ule, ugt, uge, slt, sle, sgt, sge) = ctx.dumpKeepalives(st, 0)
eq.vb.asUInt(1) shouldEqual 0
ne.vb.asUInt(1) shouldEqual 1
slt.vb.asUInt(1) shouldEqual 0
sle.vb.asUInt(1) shouldEqual 0
sgt.vb.asUInt(1) shouldEqual 1
sge.vb.asUInt(1) shouldEqual 1
Rebind(st, PassValues(Seq()))
}
......
......@@ -4,23 +4,23 @@ import uvm.GlobalBundle
import uvm.UvmTestBase
import uvm.ir.textinput.IRParsing
class StaticAnalysisTest extends UvmTestBase with IRParsing {
class BundleCheckerTest extends UvmTestBase with IRParsing {
def printException(e: Exception): Unit = travisFriendlyExceptionPrint(e)
behavior of "StaticAnalyzer"
behavior of "BundleChecker"
def shouldWorkFineIn(text: String): Unit = {
val gb = new GlobalBundle()
val b = parseText(text, gb)
new StaticAnalyzer().checkBundle(b, Some(gb))
new BundleChecker().checkBundle(b, Some(gb))
}
def catchExceptionWhenAnalyzing(text: String): Unit = {
val gb = new GlobalBundle()
val b = parseText(text, gb)
try {
new StaticAnalyzer().checkBundle(b, Some(gb))
new BundleChecker().checkBundle(b, Some(gb))
fail()
} catch {
case e: StaticCheckingException => // expected
......
......@@ -164,13 +164,9 @@
%ule = ULE <@ptri64> %p0 %p1
%ugt = UGT <@ptri64> %p0 %p1
%uge = UGE <@ptri64> %p0 %p1
%slt = SLT <@ptri64> %p0 %p1
%sle = SLE <@ptri64> %p0 %p1
%sgt = SGT <@ptri64> %p0 %p1
%sge = SGE <@ptri64> %p0 %p1
[%trap] TRAP <> KEEPALIVE (
%eq %ne %ult %ule %ugt %uge %slt %sle %sgt %sge
%eq %ne %ult %ule %ugt %uge
)
COMMINST @uvm.thread_exit
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment