kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

compile_engine.c (8198B)


      1 #include "compile_engine.h"
      2 
      3 #include <kit/asm_emit.h>
      4 #include <kit/cg.h>
      5 #include <string.h>
      6 
      7 static KitStatus driver_compile_cg_run(KitCompiler* compiler,
      8                                        const KitCodeOptions* code,
      9                                        const KitDiagnosticOptions* diagnostics,
     10                                        const DriverCompileSource* src,
     11                                        KitCg* cg) {
     12   KitCompileSessionOptions sopts;
     13   KitCompileSession* session = NULL;
     14   KitSourceInput sin;
     15   KitStatus st;
     16 
     17   if (!compiler || !code || !diagnostics || !src || !cg) return KIT_INVALID;
     18   memset(&sopts, 0, sizeof(sopts));
     19   sopts.lang = src->lang;
     20   sopts.compile.code = *code;
     21   sopts.compile.diagnostics = *diagnostics;
     22   if (src->pp) sopts.compile.preprocess = *src->pp;
     23   sopts.compile.language_options = src->lang_extra;
     24 
     25   memset(&sin, 0, sizeof(sin));
     26   sin.name = src->name;
     27   sin.bytes = src->bytes;
     28   sin.lang = src->lang;
     29 
     30   st = kit_compile_session_new(compiler, &sopts, &session);
     31   if (st == KIT_OK) st = kit_compile_session_compile_cg(session, &sin, cg);
     32   kit_compile_session_free(session);
     33   return st;
     34 }
     35 
     36 KitStatus driver_compile_run(KitCompiler* compiler, KitLanguage lang,
     37                              const KitCodeOptions* code,
     38                              const KitDiagnosticOptions* diagnostics,
     39                              const KitPreprocessOptions* pp,
     40                              const void* lang_extra, KitSlice name,
     41                              const KitSlice* bytes, KitWriter* emit_out,
     42                              KitObjBuilder** obj_out) {
     43   KitCompileSessionOptions sopts;
     44   KitCompileSession* session = NULL;
     45   KitSourceInput sin;
     46   KitObjBuilder* ob = NULL;
     47   KitCodeOptions code_copy = *code;
     48   KitStatus st;
     49 
     50   if (obj_out) *obj_out = NULL;
     51 
     52   /* For the in-CG emit modes the output writer is consumed during codegen, so
     53    * wire it onto the code options before the session runs. */
     54   if (emit_out && code_copy.emit_c_source) code_copy.c_source_writer = emit_out;
     55   if (emit_out && code_copy.emit_ir) code_copy.ir_dump_writer = emit_out;
     56 
     57   memset(&sopts, 0, sizeof(sopts));
     58   sopts.lang = lang;
     59   sopts.compile.code = code_copy;
     60   sopts.compile.diagnostics = *diagnostics;
     61   if (pp) sopts.compile.preprocess = *pp;
     62   sopts.compile.language_options = lang_extra;
     63 
     64   memset(&sin, 0, sizeof(sin));
     65   sin.name = name;
     66   sin.bytes = *bytes;
     67   sin.lang = lang;
     68 
     69   st = kit_compile_session_new(compiler, &sopts, &session);
     70   if (st == KIT_OK) st = kit_compile_session_compile(session, &sin, &ob);
     71   kit_compile_session_free(session);
     72   if (st != KIT_OK) return st;
     73 
     74   if (obj_out) {
     75     *obj_out = ob;
     76     return KIT_OK;
     77   }
     78 
     79   /* emit_out path: serialize by output mode. The in-CG modes already wrote
     80    * through the wired writer above. */
     81   if (code_copy.emit_c_source || code_copy.emit_ir) {
     82     /* nothing to serialize here */
     83   } else if (code_copy.emit_asm_source) {
     84     st = kit_obj_builder_emit_asm(ob, emit_out);
     85   } else {
     86     st = kit_obj_builder_emit(ob, emit_out);
     87   }
     88   kit_obj_builder_free(ob);
     89   return st;
     90 }
     91 
     92 static int driver_compile_lto_enabled(const KitCodeOptions* code) {
     93   return code && code->lto && !code->check_only && !code->emit_c_source &&
     94          !code->emit_ir && !code->emit_asm_source;
     95 }
     96 
     97 static KitStatus driver_compile_start_lto(KitCompiler* compiler,
     98                                           const KitCodeOptions* code,
     99                                           KitObjBuilder** ob_out,
    100                                           KitCg** cg_out) {
    101   KitObjBuilder* ob = NULL;
    102   KitCg* cg = NULL;
    103   KitStatus st;
    104 
    105   if (ob_out) *ob_out = NULL;
    106   if (cg_out) *cg_out = NULL;
    107   if (!compiler || !code || !ob_out || !cg_out) return KIT_INVALID;
    108   st = kit_obj_builder_new(compiler, &ob);
    109   if (st == KIT_OK) st = kit_cg_new(compiler, &cg);
    110   if (st == KIT_OK) st = kit_cg_begin(cg, ob, code);
    111   if (st != KIT_OK) {
    112     kit_cg_free(cg);
    113     kit_obj_builder_free(ob);
    114     return st;
    115   }
    116   *ob_out = ob;
    117   *cg_out = cg;
    118   return KIT_OK;
    119 }
    120 
    121 KitStatus driver_compile_pending_lto_finish(
    122     DriverCompilePendingLto* pending, const DriverCompileBatchOptions* batch,
    123     const KitCgSym* preserved_symbols, uint32_t npreserved_symbols) {
    124   KitCgFinishOptions finish;
    125   KitStatus st;
    126 
    127   if (!pending || !pending->active) return KIT_OK;
    128   if (!pending->obj || !pending->cg) {
    129     driver_compile_pending_lto_abort(pending);
    130     return KIT_INVALID;
    131   }
    132 
    133   memset(&finish, 0, sizeof finish);
    134   finish.output_kind = batch ? batch->output_kind : KIT_CG_OUTPUT_RELOCATABLE;
    135   finish.interposition_policy =
    136       batch ? batch->interposition_policy : KIT_CG_INTERPOSITION_DEFAULT;
    137   finish.preserved_symbols = preserved_symbols;
    138   finish.npreserved_symbols = npreserved_symbols;
    139 
    140   st = kit_cg_finish(pending->cg, &finish);
    141   if (st == KIT_OK) st = kit_cg_detach(pending->cg);
    142   if (st == KIT_OK) st = kit_obj_builder_finalize(pending->obj);
    143 
    144   kit_cg_free(pending->cg);
    145   pending->cg = NULL;
    146   pending->active = 0;
    147   return st;
    148 }
    149 
    150 void driver_compile_pending_lto_abort(DriverCompilePendingLto* pending) {
    151   if (!pending || !pending->active) return;
    152   kit_cg_free(pending->cg);
    153   pending->cg = NULL;
    154   pending->active = 0;
    155 }
    156 
    157 KitStatus driver_compile_sources_run(KitCompiler* compiler,
    158                                      const KitCodeOptions* code,
    159                                      const KitDiagnosticOptions* diagnostics,
    160                                      const DriverCompileSource* sources,
    161                                      uint32_t nsources,
    162                                      const DriverCompileBatchOptions* batch,
    163                                      DriverCompileObjects* out) {
    164   DriverCompilePendingLto pending_lto;
    165   int lto_order_emitted = 0;
    166   int lto_enabled = driver_compile_lto_enabled(code);
    167   KitStatus st = KIT_OK;
    168 
    169   if (!compiler || !code || !diagnostics || (!sources && nsources) || !out ||
    170       !out->objs || !out->source_obj_index || !out->source_order_keep) {
    171     return KIT_INVALID;
    172   }
    173   memset(&pending_lto, 0, sizeof pending_lto);
    174   out->nobjs = 0;
    175   if (out->pending_lto) memset(out->pending_lto, 0, sizeof(*out->pending_lto));
    176   for (uint32_t i = 0; i < nsources; ++i) {
    177     out->source_obj_index[i] = (uint32_t)-1;
    178     out->source_order_keep[i] = 0;
    179   }
    180 
    181   for (uint32_t i = 0; i < nsources; ++i) {
    182     const DriverCompileSource* src = &sources[i];
    183     KitFrontendCaps caps;
    184     int stage_cg = 0;
    185 
    186     memset(&caps, 0, sizeof caps);
    187     if (lto_enabled) {
    188       st = kit_frontend_caps(compiler, src->lang, &caps);
    189       if (st != KIT_OK) goto out;
    190       stage_cg = caps.lto_mode == KIT_FRONTEND_LTO_CG;
    191     }
    192 
    193     if (stage_cg) {
    194       if (!pending_lto.active) {
    195         st = driver_compile_start_lto(compiler, code, &pending_lto.obj,
    196                                       &pending_lto.cg);
    197         if (st != KIT_OK) goto out;
    198         pending_lto.obj_index = out->nobjs;
    199         pending_lto.active = 1;
    200         out->objs[out->nobjs++] = pending_lto.obj;
    201       }
    202       out->source_obj_index[i] = pending_lto.obj_index;
    203       if (!lto_order_emitted) {
    204         out->source_order_keep[i] = 1;
    205         lto_order_emitted = 1;
    206       }
    207       st = driver_compile_cg_run(compiler, code, diagnostics, src,
    208                                  pending_lto.cg);
    209       if (st != KIT_OK) goto out;
    210       continue;
    211     }
    212 
    213     {
    214       KitObjBuilder* ob = NULL;
    215       st = driver_compile_run(compiler, src->lang, code, diagnostics, src->pp,
    216                               src->lang_extra, src->name, &src->bytes, NULL,
    217                               &ob);
    218       if (st != KIT_OK) goto out;
    219       out->source_obj_index[i] = out->nobjs;
    220       out->source_order_keep[i] = 1;
    221       out->objs[out->nobjs++] = ob;
    222     }
    223   }
    224 
    225   if (pending_lto.active) {
    226     if (batch && batch->defer_lto_finish) {
    227       if (!out->pending_lto) {
    228         st = KIT_INVALID;
    229         goto out;
    230       }
    231       *out->pending_lto = pending_lto;
    232       memset(&pending_lto, 0, sizeof pending_lto);
    233     } else {
    234       st = driver_compile_pending_lto_finish(&pending_lto, batch, NULL, 0);
    235       if (st != KIT_OK) goto out;
    236     }
    237   }
    238 
    239 out:
    240   if (pending_lto.active) driver_compile_pending_lto_abort(&pending_lto);
    241   return st;
    242 }