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