WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

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

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