Bundle.scala 4.17 KB
Newer Older
Kunshan Wang's avatar
Kunshan Wang committed
1 2
package uvm

3
import uvm.types._
4
import uvm.ssavariables._
Kunshan Wang's avatar
Kunshan Wang committed
5
import scala.collection.mutable.HashMap
Kunshan Wang's avatar
Kunshan Wang committed
6

Kunshan Wang's avatar
Kunshan Wang committed
7
abstract class Bundle {
Kunshan Wang's avatar
Kunshan Wang committed
8 9 10
  /*
   * There is a hierarchy of namespaces. A subnode is a subset of the parent.
   * 
Kunshan Wang's avatar
Kunshan Wang committed
11
   * + allNs                // All globally Identified entities
12 13 14 15 16 17 18 19
   *   + typeNs             // All types
   *   + funcSigNs          // All function signatures
   *   + funcVerNs          // All function versions
   *   + varNs              // All variables, global or local
   *     + globalVarNs      // Global variables
   *       + constantNs     // Constants
   *       + globalCellNs   // Global cells
   *       + funcNs         // Functions
20
   *       + expFuncNs      // Exposed functions
Kunshan Wang's avatar
Kunshan Wang committed
21 22
   *     + localVarNs       // Local variables (per basic block)
   *   + bbNs               // Basic blocks (per function version)
Kunshan Wang's avatar
Kunshan Wang committed
23 24
   *   + instNs							// All instructions
   *   	 + localInstNs  		// Instructions in a basic block (per basic block)
Kunshan Wang's avatar
Kunshan Wang committed
25
   * 
Kunshan Wang's avatar
Kunshan Wang committed
26
   * bbNs and localVarNs are part of particular FuncVers and BBs.
Kunshan Wang's avatar
Kunshan Wang committed
27
   */
28

Kunshan Wang's avatar
Kunshan Wang committed
29
  val allNs = new NestedNamespace[Identified](None)
30

Kunshan Wang's avatar
Kunshan Wang committed
31 32 33 34
  val typeNs = allNs.makeSubSpace[Type]()
  val funcSigNs = allNs.makeSubSpace[FuncSig]()
  val funcVerNs = allNs.makeSubSpace[FuncVer]()
  val varNs = allNs.makeSubSpace[SSAVariable]()
Kunshan Wang's avatar
Kunshan Wang committed
35

Kunshan Wang's avatar
Kunshan Wang committed
36 37 38 39 40
  val globalVarNs = varNs.makeSubSpace[GlobalVariable]()
  val constantNs = globalVarNs.makeSubSpace[Constant]()
  val globalCellNs = globalVarNs.makeSubSpace[GlobalCell]()
  val funcNs = globalVarNs.makeSubSpace[Function]()
  val expFuncNs = globalVarNs.makeSubSpace[ExposedFunc]()
Kunshan Wang's avatar
Kunshan Wang committed
41 42
  
  val instNs = allNs.makeSubSpace[Instruction]()
Kunshan Wang's avatar
Kunshan Wang committed
43
}
44

Kunshan Wang's avatar
Kunshan Wang committed
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
/**
 * This kind of bundle is generated when parsing a .UIR file.
 * <p>
 * In this kind of bundle, a Function does not have a FuncVer as its version.
 * The funcNs only contains new functions declared in this bundle, not existing
 * functions declared previously. When this bundle is merged with the global bundle,
 * both funcNs and funcVerNs are simply merged, and new FuncVer objects become the
 * newest version of the Function, whether the Function is newly declared or not.
 */
class TrantientBundle extends Bundle {
  /**
   * All functions (declared here or previously) that are defined in this bundle.
   * <p>
   * Mainly for debugging purpose.
   */
  //val defFuncNs = new SimpleNamespace[Function]
}

/**
 * This kind of bundle holds the global state. Functions and versions are fully merged.
 */
class GlobalBundle extends Bundle {
67 68
  private def simpleMerge[T <: Identified](oldNs: Namespace[T], newNs: Namespace[T]) {
    for (cand <- newNs.all) {
Kunshan Wang's avatar
Kunshan Wang committed
69 70
      try {
        oldNs.add(cand)
Kunshan Wang's avatar
Kunshan Wang committed
71 72 73 74 75 76 77 78 79 80 81 82
        def assertPresent[T <: Identified](ns: NestedNamespace[T], obj: T): Unit = {
          assert(ns.get(obj.id) == Some(obj))
          if (obj.id == 65731) {
            printf("Obj[65731] found in ns " + ns)
          }
          ns.maybeParent match {
            case None =>
            case Some(ns2) =>
              assertPresent(ns2, obj)
          }
        }
        assertPresent(oldNs.asInstanceOf[NestedNamespace[T]], cand)
Kunshan Wang's avatar
Kunshan Wang committed
83 84 85 86
      } catch {
        case e: NameConflictException =>
          throw new IllegalRedefinitionException(
            "Redefinition of type, function signature, constant or" +
Kunshan Wang's avatar
Kunshan Wang committed
87
              " global cell is not allowed: %s".format(cand.repr), e);
88 89 90
      }
    }
  }
91

Kunshan Wang's avatar
Kunshan Wang committed
92 93 94 95 96
  private def redefineFunctions(newNs: Namespace[FuncVer]) {
    for (fv <- newNs.all) {
      fv.func.versions = fv :: fv.func.versions
    }
  }
Kunshan Wang's avatar
Kunshan Wang committed
97 98 99 100 101 102
  
  private def mergeLocalNamespaces(newBundle: TrantientBundle) {
    for (fv <- newBundle.funcVerNs.all) {
      fv.bbNs.reparent(allNs)
      for (bb <- fv.bbs) {
        bb.localVarNs.reparent(allNs)
Kunshan Wang's avatar
Kunshan Wang committed
103
        bb.localInstNs.reparent(allNs)
Kunshan Wang's avatar
Kunshan Wang committed
104 105 106
      }
    }
  }
Kunshan Wang's avatar
Kunshan Wang committed
107 108

  def merge(newBundle: TrantientBundle) {
Kunshan Wang's avatar
Kunshan Wang committed
109
    // Only merge leaves
110 111
    simpleMerge(typeNs, newBundle.typeNs)
    simpleMerge(funcSigNs, newBundle.funcSigNs)
112
    simpleMerge(funcVerNs, newBundle.funcVerNs)
Kunshan Wang's avatar
Kunshan Wang committed
113 114
    simpleMerge(constantNs, newBundle.constantNs)
    simpleMerge(globalCellNs, newBundle.globalCellNs)
Kunshan Wang's avatar
Kunshan Wang committed
115
    simpleMerge(funcNs, newBundle.funcNs)
116
    simpleMerge(expFuncNs, newBundle.expFuncNs)
Kunshan Wang's avatar
Kunshan Wang committed
117
    simpleMerge(instNs, newBundle.instNs)
Kunshan Wang's avatar
Kunshan Wang committed
118 119

    redefineFunctions(newBundle.funcVerNs)
Kunshan Wang's avatar
Kunshan Wang committed
120 121
    
    mergeLocalNamespaces(newBundle)
122
  }
Kunshan Wang's avatar
Kunshan Wang committed
123 124

}