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 }