kit

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

ir.c (9908B)


      1 #include "cg/ir.h"
      2 
      3 #include <string.h>
      4 
      5 static _Noreturn void ir_panic(Compiler* c, SrcLoc loc, const char* what) {
      6   compiler_panic(c, loc, "cg ir: %s", what);
      7 }
      8 
      9 static void* ir_zalloc_or_panic(Compiler* c, Arena* a, size_t size,
     10                                 size_t align) {
     11   void* p = arena_zalloc(a, size, align);
     12   if (!p) ir_panic(c, (SrcLoc){0, 0, 0}, "out of memory");
     13   return p;
     14 }
     15 
     16 char* cg_ir_dup_cstr(Arena* a, const char* s) {
     17   size_t n;
     18   if (!s) return NULL;
     19   n = strlen(s);
     20   return arena_strdup(a, s, n);
     21 }
     22 
     23 static void module_grow(CgIrModule* m, u32 want) {
     24   CgIrFunc** next;
     25   u32 cap;
     26   if (m->funcs_cap >= want) return;
     27   cap = m->funcs_cap ? m->funcs_cap : 8u;
     28   while (cap < want) cap *= 2u;
     29   next = ir_zalloc_or_panic(m->c, m->arena, sizeof(*next) * cap,
     30                             _Alignof(CgIrFunc*));
     31   if (m->funcs) memcpy(next, m->funcs, sizeof(*next) * m->nfuncs);
     32   m->funcs = next;
     33   m->funcs_cap = cap;
     34 }
     35 
     36 static void module_alias_grow(CgIrModule* m, u32 want) {
     37   CgIrAlias* next;
     38   u32 cap;
     39   if (m->aliases_cap >= want) return;
     40   cap = m->aliases_cap ? m->aliases_cap : 8u;
     41   while (cap < want) cap *= 2u;
     42   next = ir_zalloc_or_panic(m->c, m->arena, sizeof(*next) * cap,
     43                             _Alignof(CgIrAlias));
     44   if (m->aliases) memcpy(next, m->aliases, sizeof(*next) * m->naliases);
     45   m->aliases = next;
     46   m->aliases_cap = cap;
     47 }
     48 
     49 static void module_file_scope_asm_grow(CgIrModule* m, u32 want) {
     50   CgIrFileScopeAsm* next;
     51   u32 cap;
     52   if (m->file_scope_asms_cap >= want) return;
     53   cap = m->file_scope_asms_cap ? m->file_scope_asms_cap : 4u;
     54   while (cap < want) cap *= 2u;
     55   next = ir_zalloc_or_panic(m->c, m->arena, sizeof(*next) * cap,
     56                             _Alignof(CgIrFileScopeAsm));
     57   if (m->file_scope_asms)
     58     memcpy(next, m->file_scope_asms, sizeof(*next) * m->nfile_scope_asms);
     59   m->file_scope_asms = next;
     60   m->file_scope_asms_cap = cap;
     61 }
     62 
     63 CgIrModule* cg_ir_module_new(Compiler* c) {
     64   CgIrModule* m = arena_znew(c->tu, CgIrModule);
     65   if (!m) return NULL;
     66   m->arena = c->tu;
     67   m->c = c;
     68   return m;
     69 }
     70 
     71 void cg_ir_symset_init_lazy(Compiler* c, ObjSymSet* s) {
     72   if (!s || s->heap) return;
     73   ObjSymSet_init_cap(s, c ? c->ctx->heap : NULL, 0);
     74 }
     75 
     76 void cg_ir_symset_add(Compiler* c, ObjSymSet* s, ObjSymId sym) {
     77   if (!s || sym == OBJ_SYM_NONE) return;
     78   cg_ir_symset_init_lazy(c, s);
     79   if (!s->heap) return;
     80   (void)ObjSymSet_set(s, sym, 1);
     81 }
     82 
     83 int cg_ir_symset_contains(const ObjSymSet* s, ObjSymId sym) {
     84   return s && ObjSymSet_get(s, sym) != NULL;
     85 }
     86 
     87 void cg_ir_symset_fini(ObjSymSet* s) {
     88   if (s && s->heap) ObjSymSet_fini(s);
     89 }
     90 
     91 void cg_ir_module_refsets_fini(CgIrModule* m) {
     92   if (!m) return;
     93   for (u32 i = 0; i < m->nfuncs; ++i) {
     94     CgIrFunc* f = m->funcs[i];
     95     if (!f) continue;
     96     cg_ir_symset_fini(&f->call_refs);
     97     cg_ir_symset_fini(&f->global_refs);
     98   }
     99 }
    100 
    101 void cg_ir_module_add_func(CgIrModule* m, CgIrFunc* f) {
    102   if (!m || !f) return;
    103   module_grow(m, m->nfuncs + 1u);
    104   m->funcs[m->nfuncs++] = f;
    105 }
    106 
    107 void cg_ir_module_add_alias(CgIrModule* m, ObjSymId alias_sym,
    108                             ObjSymId target_sym, KitCgTypeId type) {
    109   CgIrAlias* a;
    110   if (!m || alias_sym == OBJ_SYM_NONE || target_sym == OBJ_SYM_NONE) return;
    111   module_alias_grow(m, m->naliases + 1u);
    112   a = &m->aliases[m->naliases++];
    113   memset(a, 0, sizeof *a);
    114   a->alias_sym = alias_sym;
    115   a->target_sym = target_sym;
    116   a->type = type;
    117 }
    118 
    119 void cg_ir_module_add_file_scope_asm(CgIrModule* m, const char* src,
    120                                      size_t len) {
    121   CgIrFileScopeAsm* e;
    122   if (!m || !src) return;
    123   module_file_scope_asm_grow(m, m->nfile_scope_asms + 1u);
    124   e = &m->file_scope_asms[m->nfile_scope_asms++];
    125   /* Copy the source: the parser's buffer does not outlive recording, but the
    126    * block is replayed at finalize. */
    127   e->src = arena_strdup(m->arena, src, len);
    128   e->len = len;
    129 }
    130 
    131 static CGFuncDesc dup_func_desc(Arena* a, const CGFuncDesc* in) {
    132   CGFuncDesc out = *in;
    133   if (in->nparams) {
    134     CGParamDesc* p = arena_array(a, CGParamDesc, in->nparams);
    135     memcpy(p, in->params, sizeof(*p) * in->nparams);
    136     out.params = p;
    137   }
    138   return out;
    139 }
    140 
    141 CgIrFunc* cg_ir_func_new(Compiler* c, const CGFuncDesc* desc) {
    142   CgIrFunc* f = arena_znew(c->tu, CgIrFunc);
    143   if (!f) return NULL;
    144   f->arena = c->tu;
    145   f->c = c;
    146   f->desc = dup_func_desc(f->arena, desc);
    147   f->next_inst_id = 1;
    148   return f;
    149 }
    150 
    151 static void inst_grow(CgIrFunc* f, u32 want) {
    152   CgIrInst* next;
    153   u32 cap;
    154   if (f->insts_cap >= want) return;
    155   cap = f->insts_cap ? f->insts_cap : 32u;
    156   while (cap < want) cap *= 2u;
    157   next = ir_zalloc_or_panic(f->c, f->arena, sizeof(*next) * cap,
    158                             _Alignof(CgIrInst));
    159   if (f->insts) memcpy(next, f->insts, sizeof(*next) * f->ninsts);
    160   f->insts = next;
    161   f->insts_cap = cap;
    162 }
    163 
    164 CgIrInst* cg_ir_emit(CgIrFunc* f, CgIrOp op, SrcLoc loc) {
    165   CgIrInst* in;
    166   inst_grow(f, f->ninsts + 1u);
    167   in = &f->insts[f->ninsts++];
    168   memset(in, 0, sizeof *in);
    169   in->id = f->next_inst_id++;
    170   in->op = (u16)op;
    171   in->loc = loc;
    172   return in;
    173 }
    174 
    175 static void local_grow(CgIrFunc* f, u32 want) {
    176   CgIrLocal* next;
    177   u32 cap;
    178   if (f->locals_cap >= want) return;
    179   cap = f->locals_cap ? f->locals_cap : 32u;
    180   while (cap < want) cap *= 2u;
    181   next = ir_zalloc_or_panic(f->c, f->arena, sizeof(*next) * cap,
    182                             _Alignof(CgIrLocal));
    183   if (f->locals) memcpy(next, f->locals, sizeof(*next) * f->nlocals);
    184   f->locals = next;
    185   f->locals_cap = cap;
    186 }
    187 
    188 CGLocal cg_ir_func_add_local(CgIrFunc* f, const CGLocalDesc* desc, int is_param,
    189                              u32 param_index) {
    190   CGLocal id;
    191   CgIrLocal* l;
    192   local_grow(f, f->nlocals + 1u);
    193   id = f->nlocals + 1u;
    194   l = &f->locals[f->nlocals++];
    195   memset(l, 0, sizeof *l);
    196   l->id = id;
    197   l->desc = *desc;
    198   l->is_param = is_param ? 1u : 0u;
    199   l->param_index = param_index;
    200   l->address_taken = (desc->flags & CG_LOCAL_ADDR_TAKEN) != 0;
    201   return id;
    202 }
    203 
    204 void cg_ir_func_mark_local_address_taken(CgIrFunc* f, CGLocal id) {
    205   CgIrLocal* l;
    206   if (!f || id == CG_LOCAL_NONE || id > f->nlocals) return;
    207   l = &f->locals[id - 1u];
    208   l->address_taken = 1;
    209   l->desc.flags |= CG_LOCAL_ADDR_TAKEN;
    210 }
    211 
    212 static void param_grow(CgIrFunc* f, u32 want) {
    213   CgIrParam* next;
    214   u32 cap;
    215   if (f->params_cap >= want) return;
    216   cap = f->params_cap ? f->params_cap : 8u;
    217   while (cap < want) cap *= 2u;
    218   next = ir_zalloc_or_panic(f->c, f->arena, sizeof(*next) * cap,
    219                             _Alignof(CgIrParam));
    220   if (f->params) memcpy(next, f->params, sizeof(*next) * f->nparams);
    221   f->params = next;
    222   f->params_cap = cap;
    223 }
    224 
    225 void cg_ir_func_add_param(CgIrFunc* f, CGLocal local, const CGParamDesc* desc) {
    226   CgIrParam* p;
    227   param_grow(f, f->nparams + 1u);
    228   p = &f->params[f->nparams++];
    229   memset(p, 0, sizeof *p);
    230   p->local = local;
    231   p->desc = *desc;
    232 }
    233 
    234 static void label_grow(CgIrFunc* f, u32 want) {
    235   CgIrLabel* next;
    236   u32 cap;
    237   if (f->labels_cap >= want) return;
    238   cap = f->labels_cap ? f->labels_cap : 16u;
    239   while (cap < want) cap *= 2u;
    240   next = ir_zalloc_or_panic(f->c, f->arena, sizeof(*next) * cap,
    241                             _Alignof(CgIrLabel));
    242   if (f->labels) memcpy(next, f->labels, sizeof(*next) * f->nlabels);
    243   f->labels = next;
    244   f->labels_cap = cap;
    245 }
    246 
    247 Label cg_ir_func_add_label(CgIrFunc* f) {
    248   Label id;
    249   CgIrLabel* l;
    250   label_grow(f, f->nlabels + 1u);
    251   id = f->nlabels + 1u;
    252   l = &f->labels[f->nlabels++];
    253   memset(l, 0, sizeof *l);
    254   l->id = id;
    255   return id;
    256 }
    257 
    258 void cg_ir_func_note_label_place(CgIrFunc* f, Label id, SrcLoc loc) {
    259   CgIrLabel* l;
    260   if (!f || id == LABEL_NONE || id > f->nlabels) return;
    261   l = &f->labels[id - 1u];
    262   if (!l->nplaces) l->first_place_loc = loc;
    263   ++l->nplaces;
    264 }
    265 
    266 static void scope_grow(CgIrFunc* f, u32 want) {
    267   CgIrScope* next;
    268   u32 cap;
    269   if (f->scopes_cap >= want) return;
    270   cap = f->scopes_cap ? f->scopes_cap : 16u;
    271   while (cap < want) cap *= 2u;
    272   next = ir_zalloc_or_panic(f->c, f->arena, sizeof(*next) * cap,
    273                             _Alignof(CgIrScope));
    274   if (f->scopes) memcpy(next, f->scopes, sizeof(*next) * f->nscopes);
    275   f->scopes = next;
    276   f->scopes_cap = cap;
    277 }
    278 
    279 CGScope cg_ir_func_add_scope(CgIrFunc* f, const CGScopeDesc* desc) {
    280   CGScope id;
    281   CgIrScope* s;
    282   scope_grow(f, f->nscopes + 1u);
    283   id = f->nscopes + 1u;
    284   s = &f->scopes[f->nscopes++];
    285   memset(s, 0, sizeof *s);
    286   s->id = id;
    287   s->desc = *desc;
    288   return id;
    289 }
    290 
    291 Operand* cg_ir_dup_operands(Arena* a, const Operand* src, u32 n) {
    292   Operand* out;
    293   if (!n) return NULL;
    294   out = arena_array(a, Operand, n);
    295   memcpy(out, src, sizeof(*out) * n);
    296   return out;
    297 }
    298 
    299 CGLocal* cg_ir_dup_locals(Arena* a, const CGLocal* src, u32 n) {
    300   CGLocal* out;
    301   if (!n) return NULL;
    302   out = arena_array(a, CGLocal, n);
    303   memcpy(out, src, sizeof(*out) * n);
    304   return out;
    305 }
    306 
    307 Label* cg_ir_dup_labels(Arena* a, const Label* src, u32 n) {
    308   Label* out;
    309   if (!n) return NULL;
    310   out = arena_array(a, Label, n);
    311   memcpy(out, src, sizeof(*out) * n);
    312   return out;
    313 }
    314 
    315 CGSwitchCase* cg_ir_dup_switch_cases(Arena* a, const CGSwitchCase* src, u32 n) {
    316   CGSwitchCase* out;
    317   if (!n) return NULL;
    318   out = arena_array(a, CGSwitchCase, n);
    319   memcpy(out, src, sizeof(*out) * n);
    320   return out;
    321 }
    322 
    323 ConstBytes cg_ir_dup_const_bytes(Arena* a, ConstBytes in) {
    324   ConstBytes out = in;
    325   if (in.size) {
    326     u8* bytes = arena_array(a, u8, in.size);
    327     memcpy(bytes, in.bytes, in.size);
    328     out.bytes = bytes;
    329   }
    330   return out;
    331 }
    332 
    333 CGCallDesc cg_ir_dup_call_desc(Arena* a, const CGCallDesc* in) {
    334   CGCallDesc out = *in;
    335   out.args = cg_ir_dup_locals(a, in->args, in->nargs);
    336   return out;
    337 }
    338 
    339 AsmConstraint* cg_ir_dup_asm_constraints(Arena* a, const AsmConstraint* src,
    340                                          u32 n) {
    341   AsmConstraint* out;
    342   if (!n) return NULL;
    343   out = arena_array(a, AsmConstraint, n);
    344   memcpy(out, src, sizeof(*out) * n);
    345   for (u32 i = 0; i < n; ++i) out[i].str = cg_ir_dup_cstr(a, src[i].str);
    346   return out;
    347 }