GitLab will be upgraded to the 12.10.14-ce.0 on 28 Sept 2020 at 2.00pm (AEDT) to 2.30pm (AEDT). During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to us at N110 (b) CSIT building.

Commit f0f14163 authored by Kunshan Wang's avatar Kunshan Wang

WIP: Converting symbolic AST to internal AST

parent 1d811787
package uvm.ir.irbuilder
import uvm._
import uvm.ssavariables._
import uvm.types._
import uvm.utils.Later
import uvm.utils.Later._
import uvm.ir.irbuilder.IRBuilderNode._
import scala.collection.mutable.ArrayBuffer
/** This class converts the soup of ID-referenced nodes into the refimpl's internal AST. */
class BundleConstructor(idNameMap: Map[MuID, MuName], nodeList: Seq[IRBuilderNode], globalBundle: GlobalBundle) {
val idNodeMap = nodeList.map(n => (n.id, n)).toMap
val bundle = new TrantientBundle()
def setIDAndMaybeName[T <: IdentifiedSettable](obj: T, id: MuID): T = {
obj.id = id
obj.name = idNameMap.get(id)
obj
}
def cascadeLookup[T <: Identified](id: MuID, ns1: Namespace[T], ns2: Namespace[T]): T = {
ns1.get(id).getOrElse {
ns2.get(id).getOrElse {
throw new UnknownIDException(id)
}
}
}
implicit def resTy(id: MuID): Type = cascadeLookup(id, bundle.typeNs, globalBundle.typeNs)
implicit def resSig(id: MuID): FuncSig = cascadeLookup(id, bundle.funcSigNs, globalBundle.funcSigNs)
implicit def resConst(id: MuID): Constant = cascadeLookup(id, bundle.constantNs, globalBundle.constantNs)
implicit def resGlobalVar(id: MuID): GlobalVariable = cascadeLookup(id, bundle.globalVarNs, globalBundle.globalVarNs)
implicit def resFunc(id: MuID): Function = cascadeLookup(id, bundle.funcNs, globalBundle.funcNs)
implicit def resConstInt(id: MuID): ConstInt = resConst(id) match {
case ci: ConstInt => ci
case other => throw new AssertionError("Constant int expected, but %d found. ID: %d".format(other.getClass.getName, id))
}
def makeBundle(): TrantientBundle = {
// Classify nodes into categories for phasing.
val typeNodes = new ArrayBuffer[IRTypeNode]
val sigNodes = new ArrayBuffer[IRSigNode]
val constNodes = new ArrayBuffer[IRConstNode]
val otherTopLevelNodes = new ArrayBuffer[OtherTopLevelNode]
val funcVers = new ArrayBuffer[NodeFuncVer]()
val otherNodes = new ArrayBuffer[IRBuilderNode]
nodeList foreach {
case n: IRTypeNode => typeNodes += n
case n: IRSigNode => sigNodes += n
case n: IRConstNode => constNodes += n
case n: OtherTopLevelNode => otherTopLevelNodes += n
case n: NodeFuncVer => funcVers += n
case n => otherNodes += n
}
// Phase 1: create types and sigs, and resolve their refs
val phase1 = new Later()
typeNodes foreach { irNode =>
val muNode: Type = irNode match {
case NodeTypeInt(id, len) => new TypeInt(len)
case NodeTypeFloat(id) => new TypeFloat()
case NodeTypeDouble(id) => new TypeDouble()
case NodeTypeUPtr(id, ty) => new TypeUPtr(null).later(phase1) { t => t.ty = ty }
case NodeTypeUFuncPtr(id, sig) => new TypeUFuncPtr(null).later(phase1) { t => t.sig = sig }
case NodeTypeStruct(id, fieldTys) => new TypeStruct(null).later(phase1) { t =>
t.fieldTys = fieldTys.map(resTy)
}
case NodeTypeHybrid(id, fixedTys, varTy) => new TypeHybrid(null, null).later(phase1) { t =>
t.fieldTys = fixedTys.map(resTy)
t.varTy = varTy
}
case NodeTypeArray(id, elemTy, len) => new TypeArray(null, len).later(phase1) { t =>
t.elemTy = elemTy
}
case NodeTypeVector(id, elemTy, len) => new TypeVector(null, len).later(phase1) { t =>
t.elemTy = elemTy
}
case NodeTypeVoid(id) => new TypeVoid()
case NodeTypeRef(id, ty) => new TypeRef(null).later(phase1) { t => t.ty = ty }
case NodeTypeIRef(id, ty) => new TypeIRef(null).later(phase1) { t => t.ty = ty }
case NodeTypeWeakRef(id, ty) => new TypeWeakRef(null).later(phase1) { t => t.ty = ty }
case NodeTypeFuncRef(id, sig) => new TypeFuncRef(null).later(phase1) { t => t.sig = sig }
case NodeTypeTagRef64(id) => new TypeTagRef64()
case NodeTypeThreadRef(id) => new TypeThreadRef()
case NodeTypeStackRef(id) => new TypeStackRef()
case NodeTypeFrameCursorRef(id) => new TypeFrameCursorRef()
case NodeTypeIRBuilderRef(id) => new TypeIRBuilderRef()
}
setIDAndMaybeName(muNode, irNode.id)
bundle.typeNs.add(muNode)
}
sigNodes foreach { irNode =>
val NodeFuncSig(id, paramTys, retTys) = irNode
val muNode: FuncSig = new FuncSig(null, null).later(phase1) { sig =>
sig.paramTys = paramTys.map(resTy)
sig.retTys = retTys.map(resTy)
}
setIDAndMaybeName(muNode, irNode.id)
bundle.funcSigNs.add(muNode)
}
phase1.doAll()
// Now, all types and sigs are created and their references are resolved.
// Phase 2: create and resolve consts, global cells, funcs, expfuncs and resolve their refs.
val phase2 = new Later()
constNodes foreach { irNode =>
val muNode: Constant = irNode match {
case NodeConstInt(id, ty, value) => new ConstInt(ty, value)
case NodeConstFloat(id, ty, value) => new ConstFloat(ty, value)
case NodeConstDouble(id, ty, value) => new ConstDouble(ty, value)
case NodeConstNull(id, ty) => new ConstNull(ty)
case NodeConstExtern(id, ty, symbol) => new ConstExtern(ty, symbol)
case NodeConstSeq(id, ty, elems) => new ConstSeq(ty, null).later(phase2) { c =>
c.elems = elems.map(resGlobalVar)
}
}
setIDAndMaybeName(muNode, irNode.id)
bundle.constantNs.add(muNode)
}
otherTopLevelNodes foreach {
case NodeGlobalCell(id: MuID, ty: MuTypeNode) => {
val muNode = new GlobalCell(ty)
setIDAndMaybeName(muNode, id)
bundle.globalCellNs.add(muNode)
}
case NodeFunc(id: MuID, sig: MuFuncSigNode) => {
val muNode = new Function()
muNode.sig = sig
setIDAndMaybeName(muNode, id)
bundle.funcNs.add(muNode)
}
case NodeExpFunc(id: MuID, func: MuFuncNode, callconv: Flag, cookie: MuConstIntNode) => {
val muNode = new ExposedFunc(func, callconv, cookie)
setIDAndMaybeName(muNode, id)
bundle.expFuncNs.add(muNode)
}
}
phase2.doAll()
// Now all top-level definitions are created and their inter-references are resolved
// Phase 3: Define all defined functions (.funcdef)
val phase3 = new Later()
funcVers foreach { irNode =>
val muNode = new FuncVer(irNode.func)
setIDAndMaybeName(muNode, irNode.id)
bundle.funcVerNs.add(muNode)
phase3 { () =>
defineFunction(irNode, muNode)
}
}
phase3.doAll()
bundle
}
def defineFunction(irNode: NodeFuncVer, muFunc: FuncVer): Unit = {
???
}
}
\ No newline at end of file
......@@ -58,6 +58,7 @@ trait IRBuilderListener {
def onBundleAbort(irBuilder: IRBuilder): Unit
}
/** The client-visible API for constructing Mu IR bundles. */
class IRBuilder(val id: MuInternalID,
globalBundle: GlobalBundle, idFactory: IDFactory, irBuilderListener: Option[IRBuilderListener])
extends HasID {
......@@ -72,7 +73,10 @@ class IRBuilder(val id: MuInternalID,
nodeList += node
}
def makeBundle(): TrantientBundle = ???
def makeBundle(): TrantientBundle = {
val bc = new BundleConstructor(idNameMap.toMap, nodeList, globalBundle)
bc.makeBundle()
}
def load(): Unit = {
val trantientBundle = makeBundle()
......
package uvm.ir.irbuilder
import uvm.UvmException
import uvm.MuID
/** Base class for exceptions thrown by the IR builder. */
class IRBuilderException(message: String = null, cause: Throwable = null) extends UvmException(message, cause)
......@@ -8,9 +9,17 @@ class IRBuilderException(message: String = null, cause: Throwable = null) extend
/**
* Thrown if the Mu name provided to setName is illegal
*/
class IllegalNameException(message: String = null, cause: Throwable = null) extends UvmException(message, cause)
class IllegalNameException(message: String = null, cause: Throwable = null) extends IRBuilderException(message, cause)
/**
* Thrown if the external symbol provided to new_const_extern is illegal
*/
class IllegalSymbolException(message: String = null, cause: Throwable = null) extends UvmException(message, cause)
\ No newline at end of file
class IllegalSymbolException(message: String = null, cause: Throwable = null) extends IRBuilderException(message, cause)
/**
* Thrown if an ID cannot be resolved
*/
class UnknownIDException(id: MuID, cause: Throwable = null) extends {
private val msg = "ID %d not found".format(id)
} with IRBuilderException(msg, cause)
......@@ -20,6 +20,7 @@ import uvm.utils.AdvancedAntlrHelper
import uvm.utils.AntlrHelpers.AccumulativeAntlrErrorListener
import uvm.utils.IDFactory
import uvm.utils.IOHelpers
import uvm.utils.Later
class UIRTextReader(val defaultIDFactory: IDFactory, val recordSourceInfo: Boolean = true) {
import UIRTextReader._
......@@ -83,7 +84,7 @@ class UIRTextReader(val defaultIDFactory: IDFactory, val recordSourceInfo: Boole
private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: String, ir: IrContext,
globalBundle: GlobalBundle, val recordSourceInfo: Boolean) extends AdvancedAntlrHelper {
import UIRTextReader._
import uvm.ir.textinput.Later.Laterable
import uvm.utils.Later.Laterable
def sourceLines = source.lines.toIndexedSeq
......
package uvm.ir.textinput
package uvm.utils
class Later {
var tooLate = false
......
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