Commit 6ab25910 authored by Kunshan Wang's avatar Kunshan Wang

Completed UvmIRReader

parent 096d0e87
...@@ -21,8 +21,8 @@ class CFG { ...@@ -21,8 +21,8 @@ class CFG {
var entry: BasicBlock = null var entry: BasicBlock = null
var params: Seq[Parameter] = null var params: Seq[Parameter] = null
var bbNs: Namespace[BasicBlock] = null // Consider using one global bb ns val bbNs: Namespace[BasicBlock] = new SimpleNamespace[BasicBlock] // Consider using one global bb ns
var lvNs: Namespace[LocalValue] = null // Consider using one global value ns val lvNs: Namespace[LocalValue] = new SimpleNamespace[LocalValue] // Consider using one global value ns
} }
class BasicBlock extends IdentifiedSettable { class BasicBlock extends IdentifiedSettable {
......
package uvm.ir.textinput
import scala.collection.JavaConversions._
import uvm._
import uvm.types._
import uvm.ssavalues._
import uvm.ir.textinput.gen._
import org.antlr.v4.runtime._
import org.antlr.v4.runtime.tree.TerminalNode
import uIRParser._
object AntlrUvmIRReader {
def read(ir: String): Bundle = {
val input = new ANTLRInputStream(ir)
val lexer = new uIRLexer(input)
val tokens = new CommonTokenStream(lexer)
val parser = new uIRParser(tokens)
val ast = parser.ir();
read(ast)
}
def read(ir: java.io.Reader): Bundle = {
val input = new ANTLRInputStream(ir)
val lexer = new uIRLexer(input)
val tokens = new CommonTokenStream(lexer)
val parser = new uIRParser(tokens)
val ast = parser.ir();
read(ast)
}
object IDFactory {
private var id: Int = 65536
def getID(): Int = {
val myID = id
id = id + 1
return myID
}
}
class Later {
var jobs: List[() => Unit] = Nil
def apply(job: () => Unit) {
jobs = job :: jobs
}
def doAll() {
while (!jobs.isEmpty) {
val job = jobs.head
jobs = jobs.tail
job()
}
}
def isEmpty: Boolean = jobs.isEmpty
}
implicit class Laterable[T](val anything: T) {
def later(lat: Later)(job: T => Unit): T = {
lat(() => job(anything))
anything
}
}
implicit def terminalToString(tn: TerminalNode): String = tn.getText()
implicit def IntLiteralToBigInt(il: IntLiteralContext): BigInt = {
val txt = il.getText()
val (neg, beg) = txt(0) match {
case '+' => (false, 1)
case '-' => (true, 1)
case _ => (false, 0)
}
il match {
case dec: DecIntLiteralContext => BigInt(txt.substring(beg), 10)
case oct: OctIntLiteralContext => BigInt(txt.substring(beg + 1), 8)
case hex: HexIntLiteralContext => BigInt(txt.substring(beg + 2), 16)
}
}
implicit def floatLiteralToFloat(fl: FloatLiteralContext): Float = fl match {
case num: FloatNumberContext => num.FP_NUM().getText().toFloat
case bits: FloatBitsContext => java.lang.Float.intBitsToFloat(bits.intLiteral().intValue())
case _ => fl.getText() match {
case "nan" => java.lang.Float.NaN
case "-inf" => java.lang.Float.NEGATIVE_INFINITY
case "+inf" => java.lang.Float.POSITIVE_INFINITY
}
}
implicit def doubleLiteralToDouble(dl: DoubleLiteralContext): Double = dl match {
case num: DoubleNumberContext => num.FP_NUM().getText().toDouble
case bits: DoubleBitsContext => java.lang.Double.longBitsToDouble(bits.intLiteral().longValue())
case _ => dl.getText() match {
case "nan" => java.lang.Double.NaN
case "-inf" => java.lang.Double.NEGATIVE_INFINITY
case "+inf" => java.lang.Double.POSITIVE_INFINITY
}
}
def read(ir: IrContext): Bundle = {
val bundle = new Bundle()
val phase1 = new Later()
def resTy(te: TypeContext): Type = te match {
case rt: ReferencedTypeContext => bundle.typeNs(rt.GLOBAL_ID().getText())
case it: InLineTypeContext => mkType(it.typeConstructor())
}
def mkType(tc: TypeConstructorContext): Type = {
val ty = tc match {
case it: IntTypeContext => TypeInt(it.intLiteral().intValue())
case ft: FloatTypeContext => TypeFloat()
case dt: DoubleTypeContext => TypeDouble()
case rt: RefTypeContext => TypeRef(null).later(phase1) { _.ty = resTy(rt.`type`()) }
case irt: IRefTypeContext => TypeIRef(null).later(phase1) { _.ty = resTy(irt.`type`()) }
case wrt: WeakRefTypeContext => TypeWeakRef(null).later(phase1) { _.ty = resTy(wrt.`type`()) }
case st: StructTypeContext => TypeStruct(null).later(phase1) { _.fieldTy = st.`type`().map(resTy) }
case at: ArrayTypeContext => TypeArray(null, at.intLiteral().longValue()).later(phase1) { _.elemTy = resTy(at.`type`()) }
case ht: HybridTypeContext => TypeHybrid(null, null).later(phase1) { t => t.fixedPart = resTy(ht.`type`(0)); t.varPart = resTy(ht.`type`(1)) }
case vt: VoidTypeContext => TypeVoid()
case ft: FuncTypeContext => TypeFunc(null).later(phase1) { _.sig = resSig(ft.funcSig()) }
case thr: ThreadTypeContext => TypeThread()
case sta: StackTypeContext => TypeStack()
case tr64: TagRef64TypeContext => TypeTagRef64()
case _ => throw new TextIRParsingException("foo")
}
ty.id = IDFactory.getID()
return ty
}
def resSig(fs: FuncSigContext): FuncSig = fs match {
case rfs: ReferencedFuncSigContext => bundle.funcSigNs(rfs.GLOBAL_ID())
case ilfs: InLineFuncSigContext => mkSig(ilfs.funcSigConstructor())
}
def mkSig(fsc: FuncSigConstructorContext): FuncSig = {
val sig = FuncSig(null, null).later(phase1) { sig =>
sig.retTy = resTy(fsc.`type`().head)
sig.paramTy = fsc.`type`().tail.map(resTy)
}
sig.id = IDFactory.getID()
return sig
}
ir.metaData().foreach { rule =>
rule.getChild(0) match {
case td: TypeDefContext => {
val ty = mkType(td.typeConstructor())
ty.name = Some(td.GLOBAL_ID())
bundle.typeNs.add(ty)
}
case fsd: FuncSigDefContext => {
val sig = mkSig(fsd.funcSigConstructor())
sig.name = Some(fsd.GLOBAL_ID())
bundle.funcSigNs.add(sig)
}
case _ =>
}
}
phase1.doAll()
return bundle
}
}
\ No newline at end of file
...@@ -3,6 +3,7 @@ package uvm.ir.textinput ...@@ -3,6 +3,7 @@ package uvm.ir.textinput
import uvm._ import uvm._
import uvm.types._ import uvm.types._
import uvm.ssavalues._ import uvm.ssavalues._
import uvm.ifuncs._
object UvmIRReader { object UvmIRReader {
import UvmIRAST._ import UvmIRAST._
...@@ -27,12 +28,18 @@ object UvmIRReader { ...@@ -27,12 +28,18 @@ object UvmIRReader {
} }
class Later { class Later {
var tooLate = false
var jobs: List[() => Unit] = Nil var jobs: List[() => Unit] = Nil
def apply(job: () => Unit) { def apply(job: () => Unit) {
jobs = job :: jobs if (tooLate) {
job()
} else {
jobs = job :: jobs
}
} }
def doAll() { def doAll() {
tooLate = true
while (!jobs.isEmpty) { while (!jobs.isEmpty) {
val job = jobs.head val job = jobs.head
jobs = jobs.tail jobs = jobs.tail
...@@ -70,6 +77,7 @@ object UvmIRReader { ...@@ -70,6 +77,7 @@ object UvmIRReader {
case WeakRefCons(t) => TypeWeakRef(null).later(phase1) { _.ty = resTy(t) } case WeakRefCons(t) => TypeWeakRef(null).later(phase1) { _.ty = resTy(t) }
case StructCons(fs) => TypeStruct(null).later(phase1) { _.fieldTy = fs.map(resTy) } case StructCons(fs) => TypeStruct(null).later(phase1) { _.fieldTy = fs.map(resTy) }
case ArrayCons(et, l) => TypeArray(null, l).later(phase1) { _.elemTy = resTy(et) } case ArrayCons(et, l) => TypeArray(null, l).later(phase1) { _.elemTy = resTy(et) }
case HybridCons(fp, vp) => TypeHybrid(null, null).later(phase1) { h => h.fixedPart = resTy(fp); h.varPart = resTy(vp) }
case VoidCons => TypeVoid() case VoidCons => TypeVoid()
case FuncCons(s) => TypeFunc(null).later(phase1) { _.sig = resSig(s) } case FuncCons(s) => TypeFunc(null).later(phase1) { _.sig = resSig(s) }
case ThreadCons => TypeThread() case ThreadCons => TypeThread()
...@@ -106,6 +114,7 @@ object UvmIRReader { ...@@ -106,6 +114,7 @@ object UvmIRReader {
sig.name = Some(n.name) sig.name = Some(n.name)
bundle.funcSigNs.add(sig) bundle.funcSigNs.add(sig)
} }
case _ => {}
} }
phase1.doAll() phase1.doAll()
...@@ -139,7 +148,6 @@ object UvmIRReader { ...@@ -139,7 +148,6 @@ object UvmIRReader {
def mkGlobalDataConst(gd: GlobalData): ConstGlobalData = { def mkGlobalDataConst(gd: GlobalData): ConstGlobalData = {
val gdc = ConstGlobalData(gd) val gdc = ConstGlobalData(gd)
gdc.id = IDFactory.getID()
return gdc return gdc
} }
...@@ -151,18 +159,17 @@ object UvmIRReader { ...@@ -151,18 +159,17 @@ object UvmIRReader {
def mkFuncConst(func: Function): ConstFunc = { def mkFuncConst(func: Function): ConstFunc = {
val fc = ConstFunc(func) val fc = ConstFunc(func)
fc.id = IDFactory.getID()
return fc return fc
} }
def declFunc(n: GID, s: FuncSigExpr): Function = { def declFunc(n: GID, s: FuncSigExpr): Function = {
val sig = resSig(s) val sig = resSig(s)
val func = mkFunc(sig) val func = mkFunc(sig)
func.id = IDFactory.getID()
func.name = Some(n.name) func.name = Some(n.name)
bundle.funcNs.add(func) bundle.funcNs.add(func)
val fc = mkFuncConst(func) val fc = mkFuncConst(func)
fc.name = Some(n.name)
bundle.globalValueNS.add(fc) bundle.globalValueNS.add(fc)
return func return func
...@@ -185,7 +192,6 @@ object UvmIRReader { ...@@ -185,7 +192,6 @@ object UvmIRReader {
bundle.globalDataNS.add(gd) bundle.globalDataNS.add(gd)
val gdc = mkGlobalDataConst(gd) val gdc = mkGlobalDataConst(gd)
gdc.name = Some(n.name)
bundle.globalValueNS.add(gdc) bundle.globalValueNS.add(gdc)
} }
case FuncDecl(n, s) => { case FuncDecl(n, s) => {
...@@ -195,6 +201,7 @@ object UvmIRReader { ...@@ -195,6 +201,7 @@ object UvmIRReader {
val func = declFunc(n, s) val func = declFunc(n, s)
funcDefs = (func, ps, body) :: funcDefs funcDefs = (func, ps, body) :: funcDefs
} }
case _ => {}
} }
phase2.doAll() phase2.doAll()
...@@ -223,8 +230,11 @@ object UvmIRReader { ...@@ -223,8 +230,11 @@ object UvmIRReader {
cfg.bbNs.add(bb) cfg.bbNs.add(bb)
phase3 { () => phase3 { () =>
bb.insts = for (instDef <- bbd.insts) bb.insts = for (instDef <- bbd.insts) yield {
yield mkInst(instDef) val inst = mkInst(instDef)
cfg.lvNs.add(inst)
inst
}
} }
return bb return bb
...@@ -317,15 +327,104 @@ object UvmIRReader { ...@@ -317,15 +327,104 @@ object UvmIRReader {
} }
case LandingpadCons => case LandingpadCons =>
InstLandingpad() InstLandingpad()
case ExtractValueCons(t, n, v) =>
InstExtractValue(resTy(t).asInstanceOf[TypeStruct], n, null).later(phase4) { i =>
i.opnd = vc(i.strTy, v)
}
case InsertValueCons(t, n, v, nv) =>
InstInsertValue(resTy(t).asInstanceOf[TypeStruct], n, null, null).later(phase4) { i =>
i.opnd = vc(i.strTy, v); i.newVal = vc(i.strTy.fieldTy(n), nv)
}
case NewCons(t) => InstNew(resTy(t))
case NewHybridCons(t, v) =>
InstNewHybrid(resTy(t).asInstanceOf[TypeHybrid], null).later(phase4) { i =>
i.length = vnc(v)
}
case AllocaCons(t) => InstAlloca(resTy(t))
case AllocaHybridCons(t, v) =>
InstAllocaHybrid(resTy(t).asInstanceOf[TypeHybrid], null).later(phase4) { i =>
i.length = vnc(v)
}
case GetIRefCons(t, v) =>
InstGetIRef(resTy(t), null).later(phase4) { i =>
i.opnd = vc(i.referentTy, v)
}
case GetFieldIRefCons(t, n, v) =>
InstGetFieldIRef(resTy(t).asInstanceOf[TypeStruct], n, null).later(phase4) { i =>
i.opnd = vc(i.referentTy, v)
}
case GetElemIRefCons(t, v, n) =>
InstGetElemIRef(resTy(t).asInstanceOf[TypeArray], null, null).later(phase4) { i =>
i.opnd = vc(i.referentTy, v); i.index = vc(i.referentTy, n)
}
case ShiftIRefCons(t, v, n) =>
InstShiftIRef(resTy(t), null, null).later(phase4) { i =>
i.opnd = vc(i.referentTy, v); i.offset = vc(i.referentTy, n)
}
case GetFixedPartIRefCons(t, v) =>
InstGetFixedPartIRef(resTy(t).asInstanceOf[TypeHybrid], null).later(phase4) { i =>
i.opnd = vc(i.referentTy, v)
}
case GetVarPartIRefCons(t, v) =>
InstGetVarPartIRef(resTy(t).asInstanceOf[TypeHybrid], null).later(phase4) { i =>
i.opnd = vc(i.referentTy, v)
}
case LoadCons(o, t, v) =>
InstLoad(MemoryOrdering.withName(o), resTy(t), null).later(phase4) { i =>
i.loc = vnc(v)
}
case StoreCons(o, t, v, nv) =>
InstStore(MemoryOrdering.withName(o), resTy(t), null, null).later(phase4) { i =>
i.loc = vnc(v); i.newVal = vc(i.referentTy, nv)
}
case CmpXchgCons(os, of, t, v, e, d) =>
InstCmpXchg(MemoryOrdering.withName(os), MemoryOrdering.withName(of),
resTy(t), null, null, null).later(phase4) { i =>
i.loc = vnc(v); i.expected = vc(i.referentTy, e); i.desired = vc(i.referentTy, d)
}
case AtomicRMWCons(o, op, t, v, v2) =>
InstAtomicRMW(MemoryOrdering.withName(o), AtomicRMWOptr.withName(op),
resTy(t), null, null).later(phase4) { i =>
i.loc = vnc(v); i.opnd = vc(i.referentTy, v2)
}
case FenceCons(o) => InstFence(MemoryOrdering.withName(o))
case TrapCons(t, n, e, ka) =>
InstTrap(resTy(t), resBB(n), resBB(e), null).later(phase4) { i =>
i.keepAlives = resKA(ka)
}
case WatchpointCons(wid, t, d, n, e, ka) =>
InstWatchpoint(wid, resTy(t), resBB(d), resBB(n), resBB(e), null).later(phase4) { i =>
i.keepAlives = resKA(ka)
}
case CCallCons(cc, s, f, a) =>
InstCCall(CallConv.withName(cc), resSig(s), null, null).later(phase4) { i =>
i.callee = vnc(f); i.args = resArgs(i.sig, a)
}
case NewStackCons(s, f, a) =>
InstNewStack(resSig(s), null, null).later(phase4) { i =>
i.callee = vnc(f); i.args = resArgs(i.sig, a)
}
case ICallCons(f, a, ka) =>
InstICall(IFuncs(f.name), null, null).later(phase4) { i =>
i.args = resArgs(i.iFunc.sig, a); i.keepAlives = resKA(ka)
}
case IInvokeCons(f, a, n, e, ka) =>
InstIInvoke(IFuncs(f.name), null, resBB(n), resBB(e), null).later(phase4) { i =>
i.args = resArgs(i.iFunc.sig, a); i.keepAlives = resKA(ka)
}
} }
inst.id = IDFactory.getID()
inst.name = for (lid <- instDef.name) yield lid.name
return inst return inst
} }
val entry = makeBB(body.entry) val entry = makeBB(body.entry)
val rest = body.bbs.map(makeBB).toList val rest = body.bbs.map(makeBB)
val bbs = entry :: rest val bbs = Seq(entry) ++ rest
cfg.bbs = bbs cfg.bbs = bbs
cfg.entry = entry cfg.entry = entry
...@@ -333,6 +432,10 @@ object UvmIRReader { ...@@ -333,6 +432,10 @@ object UvmIRReader {
phase3.doAll() phase3.doAll()
phase4.doAll() phase4.doAll()
for (bb <- cfg.bbs; i <- bb.insts) {
i.resolve()
}
} }
for ((func, ps, body) <- funcDefs) { for ((func, ps, body) <- funcDefs) {
......
...@@ -5,7 +5,7 @@ import uvm.types._ ...@@ -5,7 +5,7 @@ import uvm.types._
import uvm.types.CommonTypes._ import uvm.types.CommonTypes._
import uvm.ifuncs._ import uvm.ifuncs._
abstract class Value extends IdentifiedSettable { abstract class Value extends Identified {
def ty: Type def ty: Type
def resolve() {} def resolve() {}
...@@ -15,7 +15,7 @@ abstract class Value extends IdentifiedSettable { ...@@ -15,7 +15,7 @@ abstract class Value extends IdentifiedSettable {
abstract class GlobalValue extends Value abstract class GlobalValue extends Value
abstract class DeclaredConstant extends GlobalValue { abstract class DeclaredConstant extends GlobalValue with IdentifiedSettable {
var constTy: Type var constTy: Type
def ty = constTy def ty = constTy
} }
...@@ -28,23 +28,27 @@ case class ConstNull(var constTy: Type) extends DeclaredConstant ...@@ -28,23 +28,27 @@ case class ConstNull(var constTy: Type) extends DeclaredConstant
case class ConstFunc(var func: Function) extends GlobalValue { case class ConstFunc(var func: Function) extends GlobalValue {
def ty = func.sig.retTy def ty = func.sig.retTy
override def id: Int = func.id
override def name: Option[String] = func.name
} }
case class ConstGlobalData(var gd: GlobalData) extends GlobalValue { case class ConstGlobalData(var gd: GlobalData) extends GlobalValue {
def ty = gd.ty def ty = gd.ty
override def id: Int = gd.id
override def name: Option[String] = gd.name
} }
// Local values: Parameter and Instructions // Local values: Parameter and Instructions
abstract class LocalValue extends Value abstract class LocalValue extends Value
case class Parameter(var sig: FuncSig, var index: Int) extends LocalValue { case class Parameter(var sig: FuncSig, var index: Int) extends LocalValue with IdentifiedSettable {
def ty = sig.retTy def ty = sig.retTy
} }
// Instructions // Instructions
abstract class Instruction extends LocalValue abstract class Instruction extends LocalValue with IdentifiedSettable
/// enumerations /// enumerations
...@@ -148,12 +152,11 @@ abstract class StackAlloc extends AbstractAlloc { ...@@ -148,12 +152,11 @@ abstract class StackAlloc extends AbstractAlloc {
abstract class WeakRefLoader extends Instruction { abstract class WeakRefLoader extends Instruction {
def referentTy: Type def referentTy: Type
var ty: TypeRef = null var ty: Type = null
override def resolve() { override def resolve() {
referentTy match { referentTy match {
case TypeWeakRef(t) => { ty = TypeRef(t) } case TypeWeakRef(t) => { ty = TypeRef(t) }
case TypeRef(t) => { ty = referentTy.asInstanceOf[TypeRef] } case t => { ty = t }
case _ => { throw new TypeResolutionException("Expect weakref or ref, %s found".format(referentTy)) }
} }
} }
} }
...@@ -284,7 +287,7 @@ case class InstFence(var ord: MemoryOrdering) extends Instruction { ...@@ -284,7 +287,7 @@ case class InstFence(var ord: MemoryOrdering) extends Instruction {
} }
case class InstAtomicRMW(var ord: MemoryOrdering, var op: AtomicRMWOptr, case class InstAtomicRMW(var ord: MemoryOrdering, var op: AtomicRMWOptr,
var referentTy: Type, var loc: Value, var newVal: Value) extends Instruction { var referentTy: Type, var loc: Value, var opnd: Value) extends Instruction {
def ty = referentTy def ty = referentTy
} }
......
package uvm.ir.textinput
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import uvm.Bundle
class AntlrUvmIRReaderSpec extends FlatSpec with Matchers {
def parseFile(fileName: String): Bundle = {
AntlrUvmIRReader.read(new java.io.FileReader(fileName))
}
"The AntlrUvmIRParser" should "parse simple type definitions" in {
parseFile("tests/uvm-parsing-test/types.uir")
}
it should "parse simple constant definitions" in {
parseFile("tests/uvm-parsing-test/constants.uir")
}
it should "parse simple function definitions" in {
parseFile("tests/uvm-parsing-test/functions.uir")
}
it should "parse simple instruction definitions" in {
parseFile("tests/uvm-parsing-test/instructions.uir")
}
}
\ No newline at end of file
package uvm.ir.textinput
trait TestingBundlesValidators {
def validateTypes {
}
}
\ No newline at end of file
package uvm.ir.textinput
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import uvm.Bundle
class UvmIRReaderSpec extends FlatSpec with Matchers {
def parseFile(fileName: String): Bundle = {
UvmIRReader.read(new java.io.FileReader(fileName))
}
"The IRParser" should "parse simple type definitions" in {
parseFile("tests/uvm-parsing-test/types.uir")
}
it should "parse simple constant definitions" in {
parseFile("tests/uvm-parsing-test/constants.uir")
}
it should "parse simple function definitions" in {
parseFile("tests/uvm-parsing-test/functions.uir")
}
it should "parse simple instruction definitions" in {
parseFile("tests/uvm-parsing-test/instructions.uir")
}
}
\ No newline at end of file
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