diff --git a/src/main/scala/uvm/comminsts/comminsts.scala b/src/main/scala/uvm/comminsts/comminsts.scala index 21cfefe324a4505a91d627206ff55df7256a6cb2..51234b6902f9ed572ae18c2811f2d9faa207e416 100644 --- a/src/main/scala/uvm/comminsts/comminsts.scala +++ b/src/main/scala/uvm/comminsts/comminsts.scala @@ -2,18 +2,18 @@ package uvm.comminsts import uvm._ -case class CommInst(val id: Int, val name: Option[String]) extends Identified +case class CommInst(val id: Int, val name: Option[String], val isTerminator: Boolean) extends Identified object CommInsts extends SimpleNamespace[CommInst] { - private def commInst(id: Int, name: String) { - val ci = CommInst(id, Some(name)) + private def commInst(id: Int, name: String, isTerminator: Boolean = false) { + val ci = CommInst(id, Some(name), isTerminator) add(ci) } commInst(0x201, "@uvm.new_stack") commInst(0x202, "@uvm.kill_stack") - commInst(0x203, "@uvm.thread_exit") + commInst(0x203, "@uvm.thread_exit", isTerminator = true) commInst(0x204, "@uvm.current_stack") commInst(0x211, "@uvm.tr64.is_fp") diff --git a/src/main/scala/uvm/refimpl/MicroVM.scala b/src/main/scala/uvm/refimpl/MicroVM.scala index 952ffe38b9f468b24868ce3c47dc0e908a7c29dc..f82358436d7108000f66f96b7a3aee8752d24f6d 100644 --- a/src/main/scala/uvm/refimpl/MicroVM.scala +++ b/src/main/scala/uvm/refimpl/MicroVM.scala @@ -10,6 +10,7 @@ import uvm.refimpl.itpr._ import uvm.refimpl.mem._ import uvm.refimpl.mem.TypeSizes.Word import uvm.refimpl.nat.NativeCallHelper +import uvm.staticanalysis.StaticAnalyzer object MicroVM { val DEFAULT_HEAP_SIZE: Word = 4L * 1024L * 1024L; // 4MiB @@ -41,6 +42,7 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE, val irReader = new UIRTextReader(new IDFactory(MicroVM.FIRST_CLIENT_USABLE_ID)) val hailScriptLoader = new HailScriptLoader() + val staticAnalyzer = new StaticAnalyzer() { // VOID, BYTE, BYTE_ARRAY: The micro VM allocates stacks on the heap in the large object space. @@ -66,6 +68,8 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE, * Add things from a bundle to the Micro VM. */ def addBundle(bundle: TrantientBundle) { + staticAnalyzer.checkBundle(bundle, Some(globalBundle)) + globalBundle.merge(bundle); for (gc <- bundle.globalCellNs.all) { diff --git a/src/main/scala/uvm/ssavariables/ssavariables.scala b/src/main/scala/uvm/ssavariables/ssavariables.scala index 94c24d0c5722b2365c22fac9a012abb167f4c3e8..c8c435951f505f22c304278319f742c7bde485b0 100644 --- a/src/main/scala/uvm/ssavariables/ssavariables.scala +++ b/src/main/scala/uvm/ssavariables/ssavariables.scala @@ -255,8 +255,12 @@ case class InstCCall(var callConv: Flag, var funcTy: Type, var sig: FuncSig, var case class InstNewThread(var stack: SSAVariable, var newStackAction: NewStackAction, var excClause: Option[ExcClause]) extends Instruction with HasExcClause case class InstSwapStack(var swappee: SSAVariable, var curStackAction: CurStackAction, var newStackAction: NewStackAction, - var excClause: Option[ExcClause], var keepAlives: Seq[LocalVariable]) extends HasExcClause with HasKeepAliveClause with OSRPoint + var excClause: Option[ExcClause], var keepAlives: Seq[LocalVariable]) extends HasExcClause with HasKeepAliveClause with OSRPoint { + override def canTerminate: Boolean = curStackAction == KillOld() || excClause.isDefined +} case class InstCommInst(var inst: CommInst, var flagList: Seq[Flag], var typeList: Seq[Type], var funcSigList: Seq[FuncSig], var argList: Seq[SSAVariable], var excClause: Option[ExcClause], var keepAlives: Seq[LocalVariable]) - extends HasTypeList with HasArgList with HasExcClause with HasKeepAliveClause + extends HasTypeList with HasArgList with HasExcClause with HasKeepAliveClause { + override def canTerminate: Boolean = excClause.isDefined || inst.isTerminator +} diff --git a/src/main/scala/uvm/staticanalysis/StaticAnalyzer.scala b/src/main/scala/uvm/staticanalysis/StaticAnalyzer.scala index 6de6451360f38f2d5c0046faee05360cf041ce67..41ae9a53ad70ef0c67edd592e6d4da4c2abffabb 100644 --- a/src/main/scala/uvm/staticanalysis/StaticAnalyzer.scala +++ b/src/main/scala/uvm/staticanalysis/StaticAnalyzer.scala @@ -245,6 +245,7 @@ class StaticAnalyzer { pretty = Seq(g, ty)) case ty: TypeHybrid => throw error("Global cell %s: Global cell cannot have hybrid type.".format(g.repr), pretty = Seq(g, ty)) + case _ => } } } @@ -328,13 +329,6 @@ class StaticAnalyzer { .format(fv.repr, bb.repr, lastInst.repr, destBB.repr, dest), pretty = Seq(lastInst, destBB)) } - } else { - if (!destBB.excParam.isDefined) { - throw error(("FuncVer %s BB %s Inst %s: Exceptional destination %s must have exceptional parameter.\n" + - "DestClause: %s") - .format(fv.repr, bb.repr, lastInst.repr, destBB.repr, dest), - pretty = Seq(lastInst, destBB)) - } } } } diff --git a/src/test/scala/uvm/staticanalysis/StaticAnalysisTest.scala b/src/test/scala/uvm/staticanalysis/StaticAnalysisTest.scala index 161ee76732e14cff721131021fecb27643d812e9..c8ea5bdeee4c8baa282295dfe4c21eac1ee3de42 100644 --- a/src/test/scala/uvm/staticanalysis/StaticAnalysisTest.scala +++ b/src/test/scala/uvm/staticanalysis/StaticAnalysisTest.scala @@ -255,22 +255,6 @@ class StaticAnalysisTest extends FlatSpec with Matchers { """) } - it should "complain if an exceptional dest does not have exc param" in { - catchExceptionWhenAnalyzing(""" - .typedef @i32 = int<32> - .const @1 <@i32> = 1 - .funcsig @sig = () -> () - .funcdef @f VERSION %v1 <@sig> { - %entry(): - CALL <@sig> @f () EXC(%b1() %b2()) - %b1(): - RET () - %b2(): - RET () - } - """) - } - it should "complain if a normal dest has exc param" in { catchExceptionWhenAnalyzing(""" .typedef @i32 = int<32> diff --git a/tests/uvm-refimpl-test/futex-tests.uir b/tests/uvm-refimpl-test/futex-tests.uir index 1e47cb21bd3eeb11c3bd0f1c7952fc40a68a6686..2542fd88f5fa3500d85aed830fb85d2c7ed22884 100644 --- a/tests/uvm-refimpl-test/futex-tests.uir +++ b/tests/uvm-refimpl-test/futex-tests.uir @@ -81,7 +81,7 @@ %wait_body(<@thread> %nt <@thread> %nt2): %rv = [%trap_wait] TRAP <@i32> KEEPALIVE (%nt %nt2) %is_1 = EQ <@i32> %rv @I32_1 - BRANCH2 %is_1 %wait_exit() %wait_body() + BRANCH2 %is_1 %wait_exit() %wait_body(%nt %nt2) %wait_exit(): %nwakes = COMMINST @uvm.futex.cmp_requeue <@i32> (@the_futex @the_other_futex @I32_0 @I32_1) diff --git a/tests/uvm-refimpl-test/osr-tests.uir b/tests/uvm-refimpl-test/osr-tests.uir index db80cc360fb64405a8ea835797a6302c68a4236c..54c596a0f404cdc0b6f00ebe6f2df8c85f40ba25 100644 --- a/tests/uvm-refimpl-test/osr-tests.uir +++ b/tests/uvm-refimpl-test/osr-tests.uir @@ -68,7 +68,7 @@ .const @I64_42 <@i64> = 42 -.funcdef @forty_two_returner VERSION %v1 <@v_i> { +.funcdef @forty_two_returner VERSION %v1 <@v_v> { %entry(): RET @I64_42 } diff --git a/tests/uvm-refimpl-test/primitives.uir b/tests/uvm-refimpl-test/primitives.uir index 3fdf4e66e23e9efc94c5a5efd1a29c3be313654f..2f493c7fa546985bd3a30b1cde61658c10ab38a3 100644 --- a/tests/uvm-refimpl-test/primitives.uir +++ b/tests/uvm-refimpl-test/primitives.uir @@ -143,7 +143,7 @@ .const @D_40 <@double> = 40.0d .const @D_50 <@double> = 50.0d .const @D_100 <@double> = 100.0d -.const @D_NAN <@float> = nand +.const @D_NAN <@double> = nand .const @4xI32_V1 <@4xi32> = {@I32_0 @I32_1 @I32_2 @I32_3} .const @4xI32_V2 <@4xi32> = {@I32_4 @I32_5 @I32_6 @I32_7} diff --git a/tests/uvm-refimpl-test/simple-sum.uir b/tests/uvm-refimpl-test/simple-sum.uir index 4b3a663eebd0c0ede40ef82615c49b1dbefc7f47..2f6e651a2cf416142fa8eaf05826e098e7ebab66 100644 --- a/tests/uvm-refimpl-test/simple-sum.uir +++ b/tests/uvm-refimpl-test/simple-sum.uir @@ -1,6 +1,6 @@ // require "primitives.uir" -.funcsig @simplesum_sig = (@i64 @i64) -> (@void) +.funcsig @simplesum_sig = (@i64 @i64) -> () .funcdef @simplesum VERSION @simplesum_v1 <@simplesum_sig> { %entry (<@i64> %from <@i64> %to): [%starttrap] TRAP <>