Commit a8ffa3e5 authored by Kunshan Wang's avatar Kunshan Wang

Tested TextIRWriter

parent e2ff5a00
......@@ -3,7 +3,6 @@ package uvm.clientsupport.text
import scala.beans._
import java.util._
import DefaultTypes._
import uvm.ir.textinput.gen.UIRParser.TopLevelDefContext
/**
* This object contains common types and helper methods.
......@@ -154,6 +153,11 @@ class ConstStruct() extends ConstDef {
@BeanProperty var fields: List[MuName] = makeList()
}
/** A vector constant. */
class ConstVector() extends ConstDef {
@BeanProperty var elems: List[MuName] = makeList()
}
/** A NULL constant. */
class ConstNull() extends ConstDef {
}
......@@ -379,9 +383,9 @@ trait FixedAlloc {
/** MixIn for hybrid allocation (NEWHYBRID and ALLOCAHYBRID) */
trait HybridAlloc {
/** The type to allocate. */
@BeanProperty var allocTy: TypeHybrid = _ // T1 in spec
@BeanProperty var allocTy: TypeMuName = _ // T1 in spec
/** The type of the length argument. Must be int. */
@BeanProperty var lenTy: TypeInt = _ // T2 in spec
@BeanProperty var lenTy: TypeMuName = _ // T2 in spec
/** The length. */
@BeanProperty var length: VarMuName = _
}
......@@ -507,20 +511,20 @@ class InstNewStack() extends Instruction with CallLike with HasExcClause
abstract class CurStackClause
/** RET_WITH */
case class RetWith(
@BeanProperty var retTy: TypeMuName /* T1 */) extends CurStackClause
@BeanProperty var retTy: TypeMuName /* T1 */ ) extends CurStackClause
/** KILL_OLD */
case class KillOld() extends CurStackClause
abstract class NewStackClause
/** PASS_VALUE */
case class PassValue(
@BeanProperty var argTy: TypeMuName /* T2 */,
@BeanProperty var argTy: TypeMuName /* T2 */ ,
@BeanProperty var arg: VarMuName) extends NewStackClause
/** PASS_VOID */
case class PassVoid() extends NewStackClause
/** THROW_EXC */
case class ThrowExc(
@BeanProperty var exc: VarMuName) extends NewStackClause
@BeanProperty var exc: VarMuName) extends NewStackClause
/** SWAPSTACK */
class InstSwapStack() extends Instruction with HasExcClause with HasKeepAlives {
......
......@@ -5,7 +5,7 @@ import scala.collection.JavaConversions._
object TextIRWriter {
def bundleToText(bundle: Bundle): String = {
val sb = new StringBuilder()
for (d <- bundle.typeDefs) sb ++= typeToText(d) ++= "\n"
for (d <- bundle.funcSigDefs) sb ++= funcSigToText(d) ++= "\n"
for (d <- bundle.constDefs) sb ++= constToText(d) ++= "\n"
......@@ -20,18 +20,13 @@ object TextIRWriter {
def typeToText(typeDef: TypeDef): String = {
val name = typeDef.name
val ctor = typeDef match {
case t: TypeInt => "int<%d>".format(t.len)
case t: TypeFloat => "float"
case t: TypeDouble => "double"
case t: TypeRef => "ref<%s>".format(t.ty)
case t: TypeIRef => "iref<%s>".format(t.ty)
case t: TypeWeakRef => "weakref<%s>".format(t.ty)
case t: TypeStruct => {
val sb = new StringBuilder("struct<")
for (ty <- t.fieldTy) sb ++= " " ++= ty
sb ++= " >"
sb.toString
}
case t: TypeInt => "int<%d>".format(t.len)
case t: TypeFloat => "float"
case t: TypeDouble => "double"
case t: TypeRef => "ref<%s>".format(t.ty)
case t: TypeIRef => "iref<%s>".format(t.ty)
case t: TypeWeakRef => "weakref<%s>".format(t.ty)
case t: TypeStruct => "struct<%s>".format(t.fieldTy.mkString(" "))
case t: TypeArray => "array<%s %d>".format(t.elemTy, t.len)
case t: TypeHybrid => "hybrid<%s %s>".format(t.fixedTy, t.varTy)
case t: TypeVoid => "void"
......@@ -47,27 +42,19 @@ object TextIRWriter {
}
def funcSigToText(funcSigDef: FuncSigDef): String = {
val paramTys = {
val sb = new StringBuilder(" ")
for (ty <- funcSigDef.paramTy) sb ++= ty ++= " "
sb.toString
}
".funcsig %s = %s (%s)".format(funcSigDef.name, funcSigDef.retTy, funcSigDef.paramTy)
val paramTys = funcSigDef.paramTy.mkString(" ")
".funcsig %s = %s (%s)".format(funcSigDef.name, funcSigDef.retTy, paramTys)
}
def constToText(constDef: ConstDef): String = {
val name = constDef.name
val ty = constDef.ty
val ctor: String = constDef match {
case c: ConstInt => c.num.toString
case c: ConstFloat => "bitsf(0x%x)".format(java.lang.Float.floatToRawIntBits(c.num))
case c: ConstDouble => "bitsd(0x%x)".format(java.lang.Double.doubleToRawLongBits(c.num))
case c: ConstStruct => {
val sb = new StringBuilder("{ ")
for (f <- c.fields) sb ++= f ++= " "
sb ++= "}"
sb.toString
}
case c: ConstInt => c.num.toString
case c: ConstFloat => "bitsf(0x%x)".format(java.lang.Float.floatToRawIntBits(c.num))
case c: ConstDouble => "bitsd(0x%x)".format(java.lang.Double.doubleToRawLongBits(c.num))
case c: ConstStruct => "{%s}".format(c.fields.mkString(" "))
case c: ConstVector => "VEC{%s}".format(c.elems.mkString(" "))
case c: ConstNull => "NULL"
case c: ConstPointer => c.addr.toString
}
......@@ -109,8 +96,8 @@ object TextIRWriter {
case i: InstBinOp => "%s <%s> %s %s %s".format(i.op, i.opndTy, i.op1, i.op2, maybeExcClause(i))
case i: InstCmp => "%s <%s> %s %s".format(i.op, i.opndTy, i.op1, i.op2)
case i: InstConv => "%s <%s %s> %s".format(i.op, i.fromTy, i.toTy, i.opnd)
case i: InstSelect => "SELECT <%s %s> %s %s".format(i.condTy, i.opndTy, i.cond, i.ifTrue, i.ifFalse)
case i: InstBranch => "BRAHCN %s".format(i.dest)
case i: InstSelect => "SELECT <%s %s> %s %s %s".format(i.condTy, i.opndTy, i.cond, i.ifTrue, i.ifFalse)
case i: InstBranch => "BRANCH %s".format(i.dest)
case i: InstBranch2 => "BRANCH2 %s %s %s".format(i.cond, i.ifTrue, i.ifFalse)
case i: InstSwitch => {
val sHead = "SWITCH <%s> %s %s {\n".format(i.opndTy, i.opnd, i.defDest)
......@@ -143,13 +130,13 @@ object TextIRWriter {
case i: InstThrow => "THROW %s".format(i.excVal)
case i: InstLandingPad => "LANDINGPAD"
case i: InstExtractValue => "EXTRACTVALUE <%s %d> %s".format(i.strTy, i.index, i.opnd)
case i: InstInsertValue => "INSERT <%s %d> %s %s".format(i.strTy, i.index, i.opnd, i.newVal)
case i: InstInsertValue => "INSERTVALUE <%s %d> %s %s".format(i.strTy, i.index, i.opnd, i.newVal)
case i: InstExtractElement => "EXTRACTELEMENT <%s %s> %s %s".format(i.vecTy, i.indTy, i.opnd, i.index)
case i: InstInsertElement => "INSERTELEMENT <%s %s> %s %s %s".format(i.vecTy, i.indTy, i.opnd, i.index, i.newVal)
case i: InstShuffleVector => "SHUFFLEVECTOR <%s %s> %s %s %s".format(i.vecTy, i.maskTy, i.vec1, i.vec2, i.mask)
case i: InstNew => "NEW <%s> %s".format(i.allocTy, maybeExcClause(i))
case i: InstNewHybrid => "NEWHYBRID <%s %s> %s %s".format(i.allocTy, i.lenTy, i.length, maybeExcClause(i))
case i: InstAlloca => "ALLOCA<%s> %s".format(i.allocTy, maybeExcClause(i))
case i: InstAlloca => "ALLOCA <%s> %s".format(i.allocTy, maybeExcClause(i))
case i: InstAllocaHybrid => "ALLOCAHYBRID <%s %s> %s %s".format(i.allocTy, i.lenTy, i.length, maybeExcClause(i))
case i: InstGetIRef => "GETIREF <%s> %s".format(i.referentTy, i.opnd)
case i: InstGetFieldIRef => "GETFIELDIREF %s <%s %d> %s".format(maybePtr(i), i.referentTy, i.index, i.opnd)
......@@ -169,7 +156,7 @@ object TextIRWriter {
case i: InstCCall => {
val argList = i.argList.mkString(" ")
val ka = maybeKeepAlives(i)
"CCALL %s <%s %s> %s %s %s".format(i.callConv, i.calleeTy, i.sig, i.callee, argList, ka)
"CCALL %s <%s %s> %s (%s) %s".format(i.callConv, i.calleeTy, i.sig, i.callee, argList, ka)
}
case i: InstNewStack => {
val argList = i.argList.mkString(" ")
......@@ -178,11 +165,11 @@ object TextIRWriter {
}
case i: InstSwapStack => {
val curStackClause = i.curStackClause match {
case RetWith(t) => "RET_WITH(%s)".format(t)
case RetWith(t) => "RET_WITH (%s)".format(t)
case KillOld() => "KILL_OLD"
}
val newStackClause = i.newStackClause match {
case PassValue(t, v) => "PASS_VALUE(%s %s)".format(t, v)
case PassValue(t, v) => "PASS_VALUE <%s> %s".format(t, v)
case PassVoid() => "PASS_VOID"
case ThrowExc(e) => "THROW_EXC(%s)".format(e)
}
......
package uvm.clientsupport.text
import scala.collection.JavaConversions._
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import org.scalatest.matchers.{ Matcher, MatchResult }
import TextIRWriter._
import uvm.ir.textinput.UIRTextReader
import uvm.ir.textinput.IDFactory
class TextIRWriterTest extends FlatSpec with Matchers {
behavior of "TextIRWriter"
it should "correctly write types" in {
typeToText {
val t = new TypeInt()
t.name = "@a"
t.len = 32
t
} shouldEqual ".typedef @a = int<32>"
typeToText {
val t = new TypeFloat()
t.name = "@a"
t
} shouldEqual ".typedef @a = float"
typeToText {
val t = new TypeDouble()
t.name = "@a"
t
} shouldEqual ".typedef @a = double"
typeToText {
val t = new TypeRef()
t.name = "@a"
t.ty = "@b"
t
} shouldEqual ".typedef @a = ref<@b>"
typeToText {
val t = new TypeIRef()
t.name = "@a"
t.ty = "@b"
t
} shouldEqual ".typedef @a = iref<@b>"
typeToText {
val t = new TypeWeakRef()
t.name = "@a"
t.ty = "@b"
t
} shouldEqual ".typedef @a = weakref<@b>"
typeToText {
val t = new TypeStruct()
t.name = "@a"
t.fieldTy ++= Seq("@x", "@y", "@z")
t
} shouldEqual ".typedef @a = struct<@x @y @z>"
typeToText {
val t = new TypeArray()
t.name = "@a"
t.elemTy = "@b"
t.len = 123456789012345L
t
} shouldEqual ".typedef @a = array<@b 123456789012345>"
typeToText {
val t = new TypeHybrid()
t.name = "@a"
t.fixedTy = "@b"
t.varTy = "@c"
t
} shouldEqual ".typedef @a = hybrid<@b @c>"
typeToText {
val t = new TypeFunc()
t.name = "@a"
t.sig = "@b"
t
} shouldEqual ".typedef @a = func<@b>"
typeToText {
val t = new TypeThread()
t.name = "@a"
t
} shouldEqual ".typedef @a = thread"
typeToText {
val t = new TypeStack()
t.name = "@a"
t
} shouldEqual ".typedef @a = stack"
typeToText {
val t = new TypeTagRef64()
t.name = "@a"
t
} shouldEqual ".typedef @a = tagref64"
typeToText {
val t = new TypePtr()
t.name = "@a"
t.ty = "@b"
t
} shouldEqual ".typedef @a = ptr<@b>"
typeToText {
val t = new TypeFuncPtr()
t.name = "@a"
t.sig = "@b"
t
} shouldEqual ".typedef @a = funcptr<@b>"
}
it should "correctly write function signature definitions" in {
funcSigToText {
val s = new FuncSigDef()
s.name = "@sig"
s.retTy = "@r"
s.paramTy ++= Seq("@a", "@b", "@c", "@d")
s
} shouldEqual ".funcsig @sig = @r (@a @b @c @d)"
}
it should "correctly write constant definitions" in {
constToText {
val c = new ConstInt()
c.name = "@C"
c.ty = "@i64"
c.num = 1357924680123456789L
c
} shouldEqual ".const @C <@i64> = 1357924680123456789"
constToText {
val c = new ConstFloat()
c.name = "@C"
c.ty = "@float"
c.num = java.lang.Float.intBitsToFloat(0x7fc00001)
c
} shouldEqual ".const @C <@float> = bitsf(0x7fc00001)"
constToText {
val c = new ConstDouble()
c.name = "@C"
c.ty = "@double"
c.num = java.lang.Double.longBitsToDouble(0x3ff0000000000000L)
c
} shouldEqual ".const @C <@double> = bitsd(0x3ff0000000000000)"
constToText {
val c = new ConstStruct()
c.name = "@C"
c.ty = "@foo"
c.fields ++= Seq("@a", "@b", "@c")
c
} shouldEqual ".const @C <@foo> = {@a @b @c}"
constToText {
val c = new ConstVector()
c.name = "@C"
c.ty = "@foo"
c.elems ++= Seq("@a", "@b", "@c")
c
} shouldEqual ".const @C <@foo> = VEC{@a @b @c}"
constToText {
val c = new ConstNull()
c.name = "@C"
c.ty = "@r"
c
} shouldEqual ".const @C <@r> = NULL"
constToText {
val c = new ConstPointer()
c.name = "@C"
c.ty = "@p"
c.addr = 1357924680123456789L
c
} shouldEqual ".const @C <@p> = 1357924680123456789"
}
it should "correctly write global cell definitions" in {
globalToText {
val g = new GlobalCellDef()
g.name = "@g"
g.ty = "@i64"
g
} shouldEqual ".global @g <@i64>"
}
it should "correctly write function declarations" in {
funcDeclToText {
val f = new FuncDecl()
f.name = "@f"
f.sig = "@s"
f
} shouldEqual ".funcdecl @f <@s>"
}
it should "correctly write function exposing definitions" in {
funcExpToText {
val e = new FuncExpDef()
e.name = "@e"
e.func = "@f"
e.callConv = "#DEFAULT"
e.cookie = "@C"
e
} shouldEqual ".expose @e = @f #DEFAULT @C"
}
it should "correctly write instructions" in {
instToText {
val i = new InstBinOp()
i.name = "@i"
i.op = "SDIV"
i.opndTy = "@i32"
i.op1 = "@a"
i.op2 = "@b"
i.excClause = ExcClause("@nor", "@exc")
i
} shouldEqual "@i = SDIV <@i32> @a @b EXC(@nor @exc)"
instToText {
val i = new InstCmp()
i.name = "@i"
i.op = "EQ"
i.opndTy = "@i32"
i.op1 = "@a"
i.op2 = "@b"
i
} shouldEqual "@i = EQ <@i32> @a @b"
instToText {
val i = new InstConv()
i.name = "@i"
i.op = "TRUNC"
i.fromTy = "@i32"
i.toTy = "@i16"
i.opnd = "@a"
i
} shouldEqual "@i = TRUNC <@i32 @i16> @a"
instToText {
val i = new InstSelect()
i.name = "@i"
i.condTy = "@v4i1"
i.opndTy = "@v4i32"
i.cond = "@cond"
i.ifTrue = "@val1"
i.ifFalse = "@val2"
i
} shouldEqual "@i = SELECT <@v4i1 @v4i32> @cond @val1 @val2"
instToText {
val i = new InstBranch()
i.name = "@i"
i.dest = "@d"
i
} shouldEqual "@i = BRANCH @d"
instToText {
val i = new InstBranch2()
i.name = "@i"
i.cond = "@c"
i.ifTrue = "@d1"
i.ifFalse = "@d2"
i
} shouldEqual "@i = BRANCH2 @c @d1 @d2"
instToText {
val i = new InstSwitch()
i.name = "@i"
i.opndTy = "@T"
i.opnd = "@o"
i.defDest = "@d0"
i.cases ++= Seq(
SwitchCase("@v1", "@d1"),
SwitchCase("@v2", "@d2"),
SwitchCase("@v3", "@d3"))
i
}.replaceAll("\\s+", "") shouldEqual "@i = SWITCH <@T> @o @d0 {@v1:@d1;@v2:@d2;@v3:@d3;}".replaceAll("\\s+", "")
instToText {
val i = new InstPhi()
i.name = "@i"
i.opndTy = "@T"
i.cases ++= Seq(
PhiCase("@s1", "@v1"),
PhiCase("@s2", "@v2"),
PhiCase("@s3", "@v3"))
i
}.replaceAll("\\s+", "") shouldEqual "@i = PHI <@T> {@s1:@v1;@s2:@v2;@s3:@v3;}".replaceAll("\\s+", "")
instToText {
val i = new InstCall()
i.name = "@i"
i.sig = "@s"
i.callee = "@c"
i.argList ++= Seq("@x", "@y", "@z")
i.excClause = ExcClause("@nor", "@exc")
i.keepAlives ++= Seq("@u", "@v")
i
} shouldEqual "@i = CALL <@s> @c (@x @y @z) EXC(@nor @exc) KEEPALIVE(@u @v)"
instToText {
val i = new InstTailCall()
i.name = "@i"
i.sig = "@s"
i.callee = "@c"
i.argList ++= Seq("@x", "@y", "@z")
i
} shouldEqual "@i = TAILCALL <@s> @c (@x @y @z)"
instToText {
val i = new InstRet()
i.name = "@i"
i.retTy = "@t"
i.retVal = "@v"
i
} shouldEqual "@i = RET <@t> @v"
instToText {
val i = new InstRetVoid()
i.name = "@i"
i
} shouldEqual "@i = RETVOID"
instToText {
val i = new InstThrow()
i.name = "@i"
i.excVal = "@e"
i
} shouldEqual "@i = THROW @e"
instToText {
val i = new InstLandingPad()
i.name = "@i"
i
} shouldEqual "@i = LANDINGPAD"
instToText {
val i = new InstExtractValue()
i.name = "@i"
i.strTy = "@s"
i.index = 3
i.opnd = "@x"
i
} shouldEqual "@i = EXTRACTVALUE <@s 3> @x"
instToText {
val i = new InstInsertValue()
i.name = "@i"
i.strTy = "@s"
i.index = 3
i.opnd = "@x"
i.newVal = "@y"
i
} shouldEqual "@i = INSERTVALUE <@s 3> @x @y"
instToText {
val i = new InstExtractElement()
i.name = "@i"
i.vecTy = "@v"
i.indTy = "@i32"
i.opnd = "@x"
i.index = "@n"
i
} shouldEqual "@i = EXTRACTELEMENT <@v @i32> @x @n"
instToText {
val i = new InstInsertElement()
i.name = "@i"
i.vecTy = "@v"
i.indTy = "@i32"
i.opnd = "@x"
i.index = "@n"
i.newVal = "@y"
i
} shouldEqual "@i = INSERTELEMENT <@v @i32> @x @n @y"
instToText {
val i = new InstShuffleVector()
i.name = "@i"
i.vecTy = "@v"
i.maskTy = "@m"
i.vec1 = "@x"
i.vec2 = "@y"
i.mask = "@z"
i
} shouldEqual "@i = SHUFFLEVECTOR <@v @m> @x @y @z"
instToText {
val i = new InstNew()
i.name = "@i"
i.allocTy = "@t"
i.excClause = ExcClause("@n", "@e")
i
} shouldEqual "@i = NEW <@t> EXC(@n @e)"
instToText {
val i = new InstNewHybrid()
i.name = "@i"
i.allocTy = "@t"
i.lenTy = "@i32"
i.length = "@l"
i.excClause = ExcClause("@n", "@e")
i
} shouldEqual "@i = NEWHYBRID <@t @i32> @l EXC(@n @e)"
instToText {
val i = new InstAlloca()
i.name = "@i"
i.allocTy = "@t"
i.excClause = ExcClause("@n", "@e")
i
} shouldEqual "@i = ALLOCA <@t> EXC(@n @e)"
instToText {
val i = new InstAllocaHybrid()
i.name = "@i"
i.allocTy = "@t"
i.lenTy = "@i32"
i.length = "@l"
i.excClause = ExcClause("@n", "@e")
i
} shouldEqual "@i = ALLOCAHYBRID <@t @i32> @l EXC(@n @e)"
instToText {
val i = new InstGetIRef()
i.name = "@i"
i.referentTy = "@t"
i.opnd = "@r"
i
} shouldEqual "@i = GETIREF <@t> @r"
instToText {
val i = new InstGetFieldIRef()
i.name = "@i"
i.ptr = true
i.referentTy = "@t"
i.index = 3
i.opnd = "@r"
i
} shouldEqual "@i = GETFIELDIREF PTR <@t 3> @r"
instToText {
val i = new InstGetElemIRef()
i.name = "@i"
i.ptr = true
i.referentTy = "@t"
i.indTy = "@i32"
i.opnd = "@r"
i.index = "@i"
i
} shouldEqual "@i = GETELEMIREF PTR <@t @i32> @r @i"
instToText {
val i = new InstShiftIRef()
i.name = "@i"
i.ptr = true
i.referentTy = "@t"
i.offTy = "@i32"
i.opnd = "@r"
i.offset = "@i"
i
} shouldEqual "@i = SHIFTIREF PTR <@t @i32> @r @i"
instToText {
val i = new InstGetFixedPartIRef()
i.name = "@i"
i.ptr = true
i.referentTy = "@t"
i.opnd = "@r"
i
} shouldEqual "@i = GETFIXEDPARTIREF PTR <@t> @r"
instToText {
val i = new InstGetVarPartIRef()
i.name = "@i"
i.ptr = true
i.referentTy = "@t"
i.opnd = "@r"
i
} shouldEqual "@i = GETVARPARTIREF PTR <@t> @r"
instToText {
val i = new InstLoad()
i.name = "@i"
i.ptr = true
i.ord = "SEQ_CST"
i.referentTy = "@t"
i.loc = "@r"
i.excClause = ExcClause("@n", "@e")
i
} shouldEqual "@i = LOAD PTR SEQ_CST <@t> @r EXC(@n @e)"
instToText {
val i = new InstStore()
i.name = "@i"
i.ptr = true
i.ord = "SEQ_CST"
i.referentTy = "@t"
i.loc = "@r"
i.newVal = "@n"
i.excClause = ExcClause("@n", "@e")
i
} shouldEqual "@i = STORE PTR SEQ_CST <@t> @r @n EXC(@n @e)"
instToText {
val i = new InstCmpXchg()
i.name = "@i"
i.ptr = true
i.weak = true
i.ordSucc = "ACQ_REL"
i.ordFail = "ACQUIRE"
i.referentTy = "@t"