compiler/backend/cgir

  Source   Edit

Implements an IR for representing code in the code-generators. It's currently a slightly adjusted version of PNode, but the idea is to simplify and evolve it, meaning that everything here is subject to change.

Types

BlockId = distinct uint32
Identifies a block within another block -- the IDs are not unique within a Body. An outermost block has ID 0, a block within the block ID 1, etc.   Source   Edit
Body = object
  locals*: Store[LocalId, Local] ## all locals belonging to the body
  code*: CgNode
A self-contained CG IR fragment. This is usually the full body of a procedure.   Source   Edit
CgNode {.acyclic.} = ref object
  info*: TLineInfo
  typ*: PType
  case kind*: CgNodeKind
  of cnkInvalid, cnkEmpty, cnkType, cnkNilLit, cnkResume:
      nil

  of cnkIntLit, cnkUIntLit:
      intVal*: BiggestInt

  of cnkFloatLit:
    floatVal*: BiggestFloat
  of cnkStrLit:
    strVal*: StringId
  of cnkAstLit:
    astLit*: PNode
  of cnkField:
    field*: PSym
  of cnkProc:
    prc*: ProcedureId
  of cnkConst:
    cnst*: ConstId
  of cnkGlobal:
    global*: GlobalId
  of cnkMagic:
    magic*: TMagic
  of cnkLabel:
    label*: BlockId
  of cnkLocal:
    local*: LocalId
  of cnkWithOperand:
    operand*: CgNode
  of cnkWithItems:
      kids*: seq[CgNode]

  
A node in the tree structure representing code during the code generation stage. The "CG" prefix is short for "code generation".   Source   Edit
CgNodeKind = enum
  cnkInvalid,               ## the node is uninitialized
  cnkEmpty, ## represents the absence of something. The meaning depends
             ## on the context
  cnkType,                  ## a literal type
  cnkIntLit, cnkUIntLit, cnkFloatLit, cnkStrLit, cnkNilLit, ## the nil literal
  cnkAstLit,                ## a ``NimNode`` literal
  cnkField,                 ## reference to an object field's symbol
  cnkLabel,                 ## name of a block
  cnkProc,                  ## name of a procedure
  cnkConst,                 ## reference to a named, global constant
  cnkGlobal,                ## reference to a global location
  cnkLocal,                 ## reference to a local
  cnkMagic, ## name of a magic procedure. Only valid in the callee
             ## slot of ``cnkCall`` and ``cnkCheckedCall`` nodes
  cnkResume,                ## leave the current procedure as part of exceptional
                             ## control-flow
  cnkCall, ## a procedure call. The first operand is the procedure,
            ## the following operands the arguments
  cnkCheckedCall,           ## like ``cnkCall``, but the call might raise an exception
  cnkNeg, cnkAdd, cnkSub, cnkMul, cnkDiv, cnkModI, cnkTupleConstr, ## tuple constructor
  cnkObjConstr,             ## object constructor
  cnkSetConstr,             ## set constructor
  cnkArrayConstr,           ## array constructor
  cnkClosureConstr,         ## closure constructor
  cnkRange,                 ## a range expression in a ``case``-branch or
  cnkBinding, ## special node used in ``cnkObjConstr`` to associate a
               ## field with a value
  cnkFieldAccess, cnkArrayAccess, cnkTupleAccess, cnkDeref, ## dereference 'x'
  cnkAddr,                  ## address of 'x'
  cnkHiddenAddr,            ## create an internal reference of the operand
  cnkDerefView,             ## dereference for a view
  cnkConv,                  ## a type conversion
  cnkLvalueConv, ## an lvalue-preserving conversion. The ones reaching
                  ## into the code generators are usually discarded, but
                  ## they're still required for proper typing
  cnkHiddenConv, cnkToSlice, ## slice creation. Works the same as the corresponding
                              ## MIR operation
  cnkObjDownConv,           ## down conversion between `object` or `ref` types
  cnkObjUpConv,             ## up conversion between `object` or `ref` types
  cnkCast,                  ## reinterpret the bit-pattern of the operand as a
                             ## different type
  cnkStmtList, cnkVoidStmt, ## discard the operand value (i.e., do nothing with it)
  cnkEmitStmt,              ## an ``emit`` statement
  cnkAsmStmt,               ## an ``asm`` statement
  cnkIfStmt, ## only execute the body when the condition expression
              ## evaluates to 'true'
  cnkCaseStmt,              ## a ``case`` statement
  cnkBranch,                ## the branch of a ``case`` statement
  cnkGotoStmt, cnkLoopStmt, ## jump back to a loop join point
  cnkRaiseStmt, ## raise(x) -- set the `x` as the current exception and start
                 ## exceptional control-flow. `x` can be ``cnkEmpty`` in which
                 ## case "set current exception" part is skipped
  cnkContinueStmt,          ## jump to the next target in the active jump list
  cnkJoinStmt,              ## join point for gotos
  cnkLoopJoinStmt,          ## join point for loops
  cnkEnd,                   ## marks the end of a structured control-flow block
                             ## (identified by the label)
  cnkExcept,                ## special join point, representing an exception handler
  cnkFinally, cnkDef, ## starts the lifetime of a local and optionally assigns an
                       ## initial value
  cnkAsgn,                  ## a = b
  cnkFastAsgn                ## fast assign b to a
  Source   Edit

Consts

cnkAtoms = {cnkInvalid..cnkResume}
node kinds that denote leafs   Source   Edit
cnkLiterals = {cnkIntLit, cnkUIntLit, cnkFloatLit, cnkStrLit}
  Source   Edit
cnkWithItems = {cnkCall..cnkTupleAccess, cnkToSlice, cnkStmtList..cnkFastAsgn}
node kinds for which the items iterator is available   Source   Edit
cnkWithOperand = {cnkConv, cnkHiddenConv, cnkDeref, cnkAddr, cnkHiddenAddr,
                  cnkDerefView, cnkObjDownConv, cnkObjUpConv, cnkCast,
                  cnkLvalueConv}
  Source   Edit

Procs

proc `==`(x, y: BlockId): bool {.borrow, ...raises: [], tags: [].}
  Source   Edit
func len(n: CgNode): int {.inline, ...raises: [], tags: [].}
  Source   Edit
proc merge(dest: var Body; source: Body): CgNode {....raises: [], tags: [].}
Merges source into dest by appending the former to the latter. Returns the node representing the code from source after it was merged.   Source   Edit
proc newExpr(kind: CgNodeKind; info: TLineInfo; typ: PType;
             kids: varargs[CgNode]): CgNode {....raises: [], tags: [].}
  Source   Edit
func newLocalRef(id: LocalId; info: TLineInfo; typ: PType): CgNode {....raises: [],
    tags: [].}
  Source   Edit
proc newNode(kind: CgNodeKind; info = unknownLineInfo; typ = PType(nil)): CgNode {.
    ...raises: [], tags: [].}
  Source   Edit
proc newOp(kind: CgNodeKind; info: TLineInfo; typ: PType; opr: sink CgNode): CgNode {.
    ...raises: [], tags: [].}
  Source   Edit
proc newStmt(kind: CgNodeKind; info: TLineInfo; kids: varargs[CgNode]): CgNode {.
    ...raises: [], tags: [].}
  Source   Edit

Iterators

iterator items(n: CgNode): CgNode {....raises: [], tags: [].}
  Source   Edit
iterator pairs(n: CgNode): (int, CgNode) {....raises: [], tags: [].}
  Source   Edit
iterator sliceIt[T](x: seq[T]; lo, hi: Natural): (int, lent T)
  Source   Edit

Templates

template `[]`(b: Body; id: LocalId): Local
Convenience shortcut.   Source   Edit
template `[]`(n: CgNode; i: BackwardsIndex): CgNode
  Source   Edit
template `[]`(n: CgNode; i: Natural): CgNode
  Source   Edit