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

Completed UvmIRReader

parent 096d0e87
......@@ -21,8 +21,8 @@ class CFG {
var entry: BasicBlock = null
var params: Seq[Parameter] = null
var bbNs: Namespace[BasicBlock] = null // Consider using one global bb ns
var lvNs: Namespace[LocalValue] = null // Consider using one global value ns
val bbNs: Namespace[BasicBlock] = new SimpleNamespace[BasicBlock] // Consider using one global bb ns
val lvNs: Namespace[LocalValue] = new SimpleNamespace[LocalValue] // Consider using one global value ns
}
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
import uvm._
import uvm.types._
import uvm.ssavalues._
import uvm.ifuncs._
object UvmIRReader {
import UvmIRAST._
......@@ -27,12 +28,18 @@ object UvmIRReader {
}
class Later {
var tooLate = false
var jobs: List[() => Unit] = Nil
def apply(job: () => Unit) {
jobs = job :: jobs
if (tooLate) {
job()
} else {
jobs = job :: jobs
}
}
def doAll() {
tooLate = true
while (!jobs.isEmpty) {
val job = jobs.head
jobs = jobs.tail
......@@ -70,6 +77,7 @@ object UvmIRReader {
case WeakRefCons(t) => TypeWeakRef(null).later(phase1) { _.ty = resTy(t) }
case StructCons(fs) => TypeStruct(null).later(phase1) { _.fieldTy = fs.map(resTy) }
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 FuncCons(s) => TypeFunc(null).later(phase1) { _.sig = resSig(s) }
case ThreadCons => TypeThread()
......@@ -106,6 +114,7 @@ object UvmIRReader {
sig.name = Some(n.name)
bundle.funcSigNs.add(sig)
}
case _ => {}
}
phase1.doAll()
......@@ -139,7 +148,6 @@ object UvmIRReader {
def mkGlobalDataConst(gd: GlobalData): ConstGlobalData = {
val gdc = ConstGlobalData(gd)
gdc.id = IDFactory.getID()
return gdc
}
......@@ -151,18 +159,17 @@ object UvmIRReader {
def mkFuncConst(func: Function): ConstFunc = {
val fc = ConstFunc(func)
fc.id = IDFactory.getID()
return fc
}
def declFunc(n: GID, s: FuncSigExpr): Function = {
val sig = resSig(s)
val func = mkFunc(sig)
func.id = IDFactory.getID()
func.name = Some(n.name)
bundle.funcNs.add(func)
val fc = mkFuncConst(func)
fc.name = Some(n.name)
bundle.globalValueNS.add(fc)
return func
......@@ -185,7 +192,6 @@ object UvmIRReader {
bundle.globalDataNS.add(gd)
val gdc = mkGlobalDataConst(gd)
gdc.name = Some(n.name)
bundle.globalValueNS.add(gdc)
}
case FuncDecl(n, s) => {
......@@ -195,6 +201,7 @@ object UvmIRReader {
val func = declFunc(n, s)
funcDefs = (func, ps, body) :: funcDefs
}
case _ => {}
}
phase2.doAll()
......@@ -223,8 +230,11 @@ object UvmIRReader {
cfg.bbNs.add(bb)
phase3 { () =>
bb.insts = for (instDef <- bbd.insts)
yield mkInst(instDef)
bb.insts = for (instDef <- bbd.insts) yield {
val inst = mkInst(instDef)
cfg.lvNs.add(inst)
inst
}
}
return bb
......@@ -317,15 +327,104 @@ object UvmIRReader {
}
case LandingpadCons =>
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
}
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.entry = entry
......@@ -333,6 +432,10 @@ object UvmIRReader {
phase3.doAll()
phase4.doAll()
for (bb <- cfg.bbs; i <- bb.insts) {
i.resolve()
}
}
for ((func, ps, body) <- funcDefs) {
......
......@@ -5,7 +5,7 @@ import uvm.types._
import uvm.types.CommonTypes._
import uvm.ifuncs._
abstract class Value extends IdentifiedSettable {
abstract class Value extends Identified {
def ty: Type
def resolve() {}
......@@ -15,7 +15,7 @@ abstract class Value extends IdentifiedSettable {
abstract class GlobalValue extends Value
abstract class DeclaredConstant extends GlobalValue {
abstract class DeclaredConstant extends GlobalValue with IdentifiedSettable {
var constTy: Type
def ty = constTy
}
......@@ -28,23 +28,27 @@ case class ConstNull(var constTy: Type) extends DeclaredConstant
case class ConstFunc(var func: Function) extends GlobalValue {
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 {
def ty = gd.ty
override def id: Int = gd.id
override def name: Option[String] = gd.name
}
// Local values: Parameter and Instructions
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
}
// Instructions
abstract class Instruction extends LocalValue
abstract class Instruction extends LocalValue with IdentifiedSettable
/// enumerations
......@@ -148,12 +152,11 @@ abstract class StackAlloc extends AbstractAlloc {
abstract class WeakRefLoader extends Instruction {
def referentTy: Type
var ty: TypeRef = null
var ty: Type = null
override def resolve() {
referentTy match {
case TypeWeakRef(t) => { ty = TypeRef(t) }
case TypeRef(t) => { ty = referentTy.asInstanceOf[TypeRef] }
case _ => { throw new TypeResolutionException("Expect weakref or ref, %s found".format(referentTy)) }
case t => { ty = t }
}
}
}
......@@ -284,7 +287,7 @@ case class InstFence(var ord: MemoryOrdering) extends Instruction {
}
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
}
......
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