compiler/backend/backends

  Source   Edit

Shared processing logic used by all backends.

Types

BackendConfig = object
  tconfig*: TranslationConfig ## passed on to ``mirgen``. See ``mirgen.generateCode`` for more
                              ## details
  noImported*: bool ## if ``true``, indicates that a procedure with a body should not be
                    ## treated as imported, even if it's marked as such
  
Configuration state altering the operation of the process iterator.   Source   Edit
BackendEvent = object
  module*: FileIndex ## the module in whose context the processing happens. For actions
                     ## related to .inline procedures, this is not necessarily the module
                     ## the symbol is attached to
  case kind*: BackendEventKind
  of bekDiscovered:
      entity*: MirNode       ## a reference to the discovered entity
    
  of bekModule:
      nil

  of bekConstant:
      cnst*: ConstId         ## the ID of the constant
    
  of bekPartial, bekProcedure, bekImported:
      id*: ProcedureId       ## the ID of the procedure
      sym*: PSym             ## the symbol of the procedure the event is about
                             ## XXX: only here for convenience, remove it once feasible
      body*: MirBody

  
Progress event returned by the process iterator.   Source   Edit
BackendEventKind = enum
  bekDiscovered, ## a new entity was discovered during MIR processing. This
                  ## 
                  ## event is meant to be used for pre-processing of symbols
                  ## and 
                  ## registration with the code generators -- the
                  ## environment must not be modified during processing of
                  ## this event
  bekModule,                ## the initial set of alive entities for a module was
                             ## discovered
  bekConstant,              ## a complete constant was processed and transformed
  bekPartial, ## a fragment of a procedure that's generated incrementally
               ## became 
               ## available
  bekProcedure,             ## a complete procedure was processed and transformed
  bekImported                ## an alive runtime-imported procedure finished processing
  Source   Edit
DiscoveryData = object
  progress: EnvCheckpoint ## tracks how much of the environment was already processed (e.g.,
                          ## translated, scanned, etc.)
  libs*: seq[LibId]          ## all dynamic libraries that the alive graph depends on
  overrides: Table[ProcedureId, FileIndex] ## maps a procedure to the module it needs to be queued with.
                                           ## If not overriden, a procedure is queued with the module it's
                                           ## discovered from.
  
Bundles all data needed during the disovery of alive, backend-relevant entities.   Source   Edit

Procs

func discoverFrom(env: var MirEnv; decl: PNode) {....raises: [], tags: [].}
Updates env with all not-yet-seen entities from the list of declarative statements (decl).   Source   Edit
proc generateIR(graph: ModuleGraph; idgen: IdGenerator; env: var MirEnv;
                owner: PSym; body: sink MirBody): Body {.
    ...raises: [Exception, KeyError, ValueError, ERecoverableError],
    tags: [RootEffect, ReadDirEffect].}
Translates the MIR code provided by code into CgNode IR and, if enabled, echoes the result.   Source   Edit
proc generateMain(graph: ModuleGraph; modules: ModuleList; result: PNode) {.
    ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
Generates the program initialization code and emits it to result. The initialization logic is the code that invokes each module's init procedures.   Source   Edit
proc generateMainProcedure(graph: ModuleGraph; idgen: IdGenerator;
                           modules: ModuleList): PSym {.
    ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
Generates the procedure for initializing, running, and de-initializing the full program (modules). The procedure returns the value of the internal programResult global.   Source   Edit
proc generateTeardown(graph: ModuleGraph; modules: ModuleList; result: PNode) {.
    ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
Generates the code for de-initializing the program, and emits it to result.   Source   Edit
proc generateThreadTeardown(graph: ModuleGraph; modules: ModuleList;
                            result: PNode) {....raises: [KeyError, Exception],
    tags: [ReadDirEffect, RootEffect].}
Generates the code for de-initializing all threadvars for the program, and emits it to result. Destruction order is the same as for non- threadlocal state.   Source   Edit
func isEmpty(f: MirBody): bool {.inline, ...raises: [], tags: [].}
  Source   Edit
func isEmpty(tree: MirTree): bool {....raises: [], tags: [].}
Returns whether tree contains either no nodes or only nodes that have no meaning by themselves.   Source   Edit
func moduleId(o: PIdObj): int32 {.inline, ...raises: [], tags: [].}
Returns the ID of the module o is attached to. Do note that in the case of generic instantiations, this is not the necessarily the same module as the one indicated via the owner.   Source   Edit
proc preprocess(queue: var WorkQueue; graph: ModuleGraph; idgen: IdGenerator;
                env: MirEnv; id: ProcedureId; module: FileIndex) {.
    ...raises: [KeyError, Exception, ERecoverableError, ValueError],
    tags: [ReadDirEffect, RootEffect].}
Runs the transf pass on the body of prc and queues the steps needed for fully processing the procedure. module is the module the step was queued from: it's used as the module the next processing is queued from.   Source   Edit
func setModuleOverride(discovery: var DiscoveryData; id: ProcedureId;
                       module: FileIndex) {....raises: [], tags: [].}
Overrides which module the procedure identified by id will be reported as having been first seen with. This only works with procedures that haven't been queued for code generation yet. It's also fundamentally a workaround, try to use it as little as possible.   Source   Edit
proc translate(id: ProcedureId; body: PNode; graph: ModuleGraph;
               config: BackendConfig; idgen: IdGenerator; env: var MirEnv): MirBody {.
    ...raises: [Exception, ERecoverableError, KeyError, ValueError, IOError],
    tags: [RootEffect, ReadDirEffect, WriteIOEffect].}
Translates body to MIR code, applies all applicable MIR passes, and returns the result. id is the ID of the procedure the fragment belongs to.   Source   Edit

Iterators

iterator deps(tree: MirTree): lent MirNode {....raises: [], tags: [].}
Returns all external entities (procedures, globals, etc.) that tree references directly, in an unspecified order.   Source   Edit
iterator discover(env: var MirEnv; progress: EnvCheckpoint): tuple[s: PSym,
    n: MirNode] {....raises: [Exception, ERecoverableError, KeyError],
                  tags: [RootEffect, ReadDirEffect].}

Returns all entities - in an unspecified order - added to env since the progress checkpoint was created. Procedures referenced from constants also added to the environment and returned.

This iterator is meant for a manual implementation of the backend processing -- don't use it in conjunction with the process iterator.

  Source   Edit
iterator process(graph: ModuleGraph; modules: var ModuleList; env: var MirEnv;
                 discovery: var DiscoveryData; conf: BackendConfig): BackendEvent {.
    ...raises: [Exception, KeyError, ERecoverableError, ValueError, IOError],
    tags: [RootEffect, ReadDirEffect, WriteIOEffect].}

Implements discovery of alive entities (procedures, globals, constants, etc.) and applying the various transformations and MIR passes to the alive procedures. Progress is reported by returning an event (refer to BackendEventKind for more informations about the events).

The iterator is complex and contains multiple yield statements, so it's advised to implement BackendEvent processing with a dedicated procedure.

At the callsite, no new entities must be registered with discovery during processing of a bekDiscovered event.

  Source   Edit