internal.h (34311B)
1 #ifndef KIT_CG_INTERNAL_H 2 #define KIT_CG_INTERNAL_H 3 4 #include <kit/cg.h> 5 #include <stdarg.h> 6 #include <stdint.h> 7 #include <stdio.h> 8 #include <string.h> 9 10 #include "abi/abi.h" 11 #include "asm/asm.h" 12 #include "cg/cgtarget.h" 13 #include "cg/type.h" 14 #include "core/arena.h" 15 #include "core/heap.h" 16 #include "core/pool.h" 17 #include "core/segvec.h" 18 #include "core/slice.h" 19 #include "core/strbuf.h" 20 #include "debug/debug.h" 21 #include "obj/obj.h" 22 23 typedef uint32_t ObjSymId; 24 25 typedef enum SResidency { 26 RES_INHERENT, 27 RES_LOCAL, 28 RES_FIXED_LOCAL, 29 } SResidency; 30 31 typedef enum ApiSValueKind { 32 SV_OPERAND, 33 SV_CMP, 34 SV_ARITH, 35 } ApiSValueKind; 36 37 typedef enum ApiDelayedArithKind { 38 API_DELAYED_UNOP, 39 API_DELAYED_BINOP, 40 } ApiDelayedArithKind; 41 42 typedef struct ApiDelayedCmp { 43 Operand a; 44 Operand b; 45 CmpOp op; 46 u8 a_owned; 47 u8 b_owned; 48 u8 pad[2]; 49 } ApiDelayedCmp; 50 51 typedef struct ApiDelayedArith { 52 Operand a; 53 Operand b; 54 BinOp bin_op; 55 UnOp un_op; 56 u8 kind; 57 u8 a_owned; 58 u8 b_owned; 59 u8 pad; 60 } ApiDelayedArith; 61 62 /* The delayed cmp/arith payload of an SV_CMP / SV_ARITH value. It is held off 63 * the hot value-stack node (ApiSValue carries only an ApiDelayed*, NULL for the 64 * common SV_OPERAND case) so the node stays small and its per-push construction 65 * touches no delayed state. Payloads are pooled per function (api_delayed_alloc 66 * / _free, arena-backed with a freelist; see fold.c). `next_free` overlays the 67 * payload while it sits on the freelist. */ 68 typedef union ApiDelayed { 69 ApiDelayedCmp cmp; 70 ApiDelayedArith arith; 71 union ApiDelayed* next_free; 72 } ApiDelayed; 73 74 /* The scalar wide-class tag (ApiWideKind) and the packed per-type 75 * classification it feeds (api_type_class) live in cg/type.h, with the rest of 76 * the type-property queries. The value stack only stores the result (the 77 * one-byte tag below) and reads it back. */ 78 79 /* Bit-field geometry carried by a bit-field PLACE. `kit_cg_field` fills this 80 * from the record layout when it projects to a bit-field; a plain load/store on 81 * the carrying place then performs the extract/insert. The storage MemAccess is 82 * rebuilt from the place operand + field type at load/store time, so only the 83 * bit geometry needs to ride on the place. width == 0 means "not a bit-field". 84 * 85 * `wide_kind` (ApiWideKind) rides in this struct's trailing slack: it is the 86 * only one-byte hole in the value-stack node, and keeping it here leaves the 87 * node size unchanged (static_assert in value.c). It is node state, not bit 88 * geometry, so kit_cg_field_bits writes only the bit_* members and leaves it 89 * intact, and node copies (dup/swap/rot) carry it along with the type. */ 90 typedef struct ApiBitField { 91 u16 bit_offset; /* target-endian bit offset within the storage unit */ 92 u16 bit_width; /* 0 => the place is not a bit-field place */ 93 u32 bit_storage_size; /* storage-unit size in bytes */ 94 u8 bit_signed; /* signed extraction on load */ 95 u8 wide_kind; /* ApiWideKind, cached at api_push (node slack) */ 96 u8 pad[2]; 97 } ApiBitField; 98 99 typedef struct ApiSValue { 100 Operand op; 101 /* Pooled delayed cmp/arith payload, or NULL for the common SV_OPERAND value. 102 * A pointer (not the 64-byte union inline) keeps the node small; only the 103 * SV_CMP / SV_ARITH producers in fold.c allocate one. */ 104 ApiDelayed* delayed; 105 const void* lang_type; /* opaque frontend-owned slot fact */ 106 KitCgTypeId type; 107 KitCgLocal source_local; 108 ApiBitField bitfield; /* bit_width != 0 marks a bit-field PLACE subkind */ 109 u16 lang_flags; /* frontend-defined flags; CG only copies/clears */ 110 u16 flags; /* packed ApiSValueKind/SResidency/pinned/lvalue */ 111 } ApiSValue; 112 113 typedef struct ApiConstValue { 114 KitCgConstInt value; 115 KitCgTypeId type; 116 } ApiConstValue; 117 118 #define API_CG_STACK_INITIAL 16u 119 120 #define API_SV_KIND_SHIFT 0u 121 #define API_SV_RES_SHIFT 2u 122 #define API_SV_PINNED_SHIFT 4u 123 #define API_SV_LVALUE_SHIFT 5u 124 #define API_SV_KIND_MASK 0x3u 125 #define API_SV_RES_MASK 0x3u 126 #define API_SV_BOOL_MASK 0x1u 127 #define API_SV_PACK(kind_, res_, pinned_, lvalue_) \ 128 ((u16)((((u16)(kind_) & API_SV_KIND_MASK) << API_SV_KIND_SHIFT) | \ 129 (((u16)(res_) & API_SV_RES_MASK) << API_SV_RES_SHIFT) | \ 130 (((u16)(pinned_) & API_SV_BOOL_MASK) << API_SV_PINNED_SHIFT) | \ 131 (((u16)(lvalue_) & API_SV_BOOL_MASK) << API_SV_LVALUE_SHIFT))) 132 133 static inline ApiSValueKind api_sv_kind(const ApiSValue* sv) { 134 return (ApiSValueKind)((sv->flags >> API_SV_KIND_SHIFT) & API_SV_KIND_MASK); 135 } 136 137 static inline void api_sv_set_kind(ApiSValue* sv, ApiSValueKind kind) { 138 sv->flags = (u16)((sv->flags & ~(API_SV_KIND_MASK << API_SV_KIND_SHIFT)) | 139 (((u16)kind & API_SV_KIND_MASK) << API_SV_KIND_SHIFT)); 140 } 141 142 static inline SResidency api_sv_res(const ApiSValue* sv) { 143 return (SResidency)((sv->flags >> API_SV_RES_SHIFT) & API_SV_RES_MASK); 144 } 145 146 static inline void api_sv_set_res(ApiSValue* sv, SResidency res) { 147 sv->flags = (u16)((sv->flags & ~(API_SV_RES_MASK << API_SV_RES_SHIFT)) | 148 (((u16)res & API_SV_RES_MASK) << API_SV_RES_SHIFT)); 149 } 150 151 static inline int api_sv_pinned(const ApiSValue* sv) { 152 return (int)((sv->flags >> API_SV_PINNED_SHIFT) & API_SV_BOOL_MASK); 153 } 154 155 static inline void api_sv_set_pinned(ApiSValue* sv, int pinned) { 156 sv->flags = (u16)((sv->flags & ~(API_SV_BOOL_MASK << API_SV_PINNED_SHIFT)) | 157 (((u16)pinned & API_SV_BOOL_MASK) << API_SV_PINNED_SHIFT)); 158 } 159 160 static inline int api_sv_lvalue_flag(const ApiSValue* sv) { 161 return (int)((sv->flags >> API_SV_LVALUE_SHIFT) & API_SV_BOOL_MASK); 162 } 163 164 static inline void api_sv_set_lvalue(ApiSValue* sv, int lvalue) { 165 sv->flags = (u16)((sv->flags & ~(API_SV_BOOL_MASK << API_SV_LVALUE_SHIFT)) | 166 (((u16)lvalue & API_SV_BOOL_MASK) << API_SV_LVALUE_SHIFT)); 167 } 168 169 /* Largest scalar the codegen lowers as a native (lock-free) atomic. All 170 * current targets — aa64, x64, rv64, wasm32 — provide 8-byte (i64-width) 171 * atomics, so this is both the legality ceiling and the lock-free ceiling. 172 * Note it is NOT the pointer width: wasm32 has 4-byte pointers but 8-byte 173 * atomics. */ 174 #define CG_MAX_ATOMIC_SIZE 8u 175 176 /* Arity that fits inline in an ApiCgScope without a heap allocation. The common 177 * void/single-result scope (every C/toy statement) stays inline; a multi-value 178 * block whose param or result count exceeds this spills its carry-local vectors 179 * to one heap block (see api_scope_setup_sig), freed at scope_end. */ 180 #define API_CG_SCOPE_SIG_INLINE 4u 181 182 typedef struct ApiCgScope { 183 Label break_lbl; 184 Label continue_lbl; 185 CGScope target_scope; 186 /* The carry locals (and their resolved types) that move the scope's results 187 * across its exit edges and — for a loop — its params across back edges. A 188 * value is stored into result_locals[i] before a break/end and reloaded after 189 * the break label; loop params are snapshotted into param_locals[i] and 190 * reloaded after the continue label. The pointers target the inline buffers 191 * for small arity (no heap) or one heap block for larger; nresults<=1 and 192 * nparams==0 reproduces the old single-result path byte-for-byte. */ 193 CGLocal* result_locals; 194 KitCgTypeId* result_types; 195 const void** result_lang_types; 196 u16* result_lang_flags; 197 CGLocal* param_locals; 198 KitCgTypeId* param_types; 199 const void** param_lang_types; 200 u16* param_lang_flags; 201 u32 nresults; 202 u32 nparams; 203 CGLocal result_locals_inl[API_CG_SCOPE_SIG_INLINE]; 204 KitCgTypeId result_types_inl[API_CG_SCOPE_SIG_INLINE]; 205 const void* result_lang_types_inl[API_CG_SCOPE_SIG_INLINE]; 206 u16 result_lang_flags_inl[API_CG_SCOPE_SIG_INLINE]; 207 CGLocal param_locals_inl[API_CG_SCOPE_SIG_INLINE]; 208 KitCgTypeId param_types_inl[API_CG_SCOPE_SIG_INLINE]; 209 const void* param_lang_types_inl[API_CG_SCOPE_SIG_INLINE]; 210 u16 param_lang_flags_inl[API_CG_SCOPE_SIG_INLINE]; 211 u32* heap_block; /* non-NULL when u32 arity vectors spilled to heap */ 212 const void** heap_lang_types_block; 213 u16* heap_lang_flags_block; 214 u32 generation; 215 u8 active; 216 u8 pad[3]; 217 } ApiCgScope; 218 219 /* Upper bound on live (LIFO-nested) control scopes. This is the limit the 220 * scope handle can encode, not a preallocated size: g->scopes grows on 221 * demand (api_grow_scopes). The handle packs the 1-based scope index into 222 * its low 16 bits (api_scope_handle), so a depth of 0xffff is the most that 223 * remains addressable. Real translation units nest a few hundred deep at 224 * most; this ceiling exists only to keep the handle representable. */ 225 #define API_CG_MAX_SCOPES 0xffffu 226 227 typedef enum ApiSourceLocalKind { 228 API_SOURCE_LOCAL_AUTO, 229 API_SOURCE_LOCAL_PARAM, 230 } ApiSourceLocalKind; 231 232 typedef struct ApiSourceLocal { 233 KitCgTypeId type; 234 KitSym name; 235 KitCgLocalAttrs attrs; 236 SrcLoc loc; 237 CGLocalDesc desc; 238 CGLocal storage; 239 i64 const_value; 240 /* Intrusive link for the const-active list (KitCg.const_head; see fold.c). 241 * KIT_CG_LOCAL_NONE terminates. const_listed marks membership so a re-store 242 * does not double-link; it stays set (the entry lingers as a cleared no-op) 243 * until the next boundary drains the list. */ 244 KitCgLocal const_next; 245 u32 param_index; 246 u8 kind; 247 u8 const_valid; 248 u8 const_listed; 249 u8 pad[1]; 250 } ApiSourceLocal; 251 252 struct KitCg { 253 Compiler* c; 254 ObjBuilder* obj; 255 CgTarget* target; 256 Debug* debug; 257 KitCgUnitOptions cur_unit; 258 u32 nsource_units; 259 /* Monotonic, nonzero per source unit (set at kit_cg_begin_unit). Used to tell 260 * a same-TU re-definition (legal tentative-definition coalescing) apart from 261 * a genuine cross-TU contribution that must go through symresolve_merge. */ 262 u32 cur_unit_seq; 263 u8 unit_active; 264 u8 finished; 265 u8 lifecycle_pad[2]; 266 267 ApiSValue* stack; 268 ApiConstValue* const_stack; 269 u32 sp; 270 u32 cap; 271 u32 unevaluated_depth; 272 273 /* -O0 transient liveness. local_refs[h] = number of live value-stack entries 274 * that reference CGLocal handle h (maintained at api_push/api_pop, plus a 275 * pointer-range-guarded reseat at in-place operand changes). local_is_temp[h] 276 * marks an api_alloc_temp_local transient — the only locals the single-pass 277 * backend recycles (Fix A) or coalesces. The count is used only as a 278 * fast-reject prefilter: a transient is treated as dead solely when the count 279 * reads 0 AND a confirming stack scan (api_temp_dead) agrees, so any reseat 280 * gap costs at most a missed optimization, never a miscompile. Sized on 281 * demand by handle; cleared per function. NULL/0 until first use. */ 282 u32* local_refs; /* live value-stack reference count per handle */ 283 u32* local_temp_gen; /* == func_gen iff the handle is this function's temp */ 284 u32 local_track_cap; 285 u32 func_gen; /* bumped each function; stamps temps without O(cap) clears */ 286 u8 coalesce; /* -O0 copy/dup coalescing + finer reclaim enabled */ 287 u8 coalesce_known; /* coalesce resolved from env (once) */ 288 u8 coalesce_pad[2]; 289 290 /* Off-node pool for SV_CMP / SV_ARITH delayed payloads. The arena is reset 291 * per function (api_delayed_reset at func_begin, where the stack is also 292 * dropped); delayed_free is an intrusive freelist that reuses payloads within 293 * a function so the arena only grows to the live delayed-value working set. 294 */ 295 Arena delayed_arena; 296 ApiDelayed* delayed_free; 297 u8 delayed_arena_init; 298 u8 delayed_pad[3]; 299 300 ApiSourceLocal* locals; 301 u32 nlocals; 302 u32 locals_cap; 303 /* Head of the const-active list threaded through ApiSourceLocal.const_next: 304 * the locals that currently hold (or recently held, pending a boundary) a 305 * forwardable constant. Lets the const-tracker clear in O(#tracked) rather 306 * than scanning all nlocals on every store/call/branch/address-of. */ 307 KitCgLocal const_head; 308 309 KitCgTypeId fn_ret_type; /* KIT_CG_TYPE_NONE/void == no result */ 310 SrcLoc cur_loc; 311 312 CGFuncDesc fn_desc; 313 CGParamDesc fn_params[64]; 314 315 KitCgTypeId* sym_types; 316 KitCgDecl* sym_attrs; 317 u32 sym_cap; 318 319 DebugTypeId* debug_type_cache; /* indexed by KitCgTypeId */ 320 u8* debug_type_state; /* 0 empty, 1 building, 2 complete */ 321 u32 debug_type_cap; 322 323 /* Per-ObjSymId: the cur_unit_seq of the unit that last *defined* this symbol 324 * (0 = not defined by any unit yet). Distinct from sym_attrs, which is reset 325 * on every decl; this is written only when a definition is emitted. */ 326 u32* sym_def_seq; 327 u32 sym_def_seq_cap; 328 329 ApiCgScope* scopes; /* grows on demand; see api_grow_scopes */ 330 u32 nscopes; 331 u32 scopes_cap; 332 u32 scope_generation; 333 334 u32 rodata_counter; 335 int opt_level; 336 u8 check_only; 337 u8 function_sections; 338 u8 data_sections; 339 u8 stack_protector_mode; /* KitStackProtectorMode */ 340 u8 stack_protected; 341 u8 stack_guard_tls; 342 u8 stack_protector_pad[1]; 343 KitCgTypeId stack_guard_type; 344 KitCgLocal stack_guard_local; 345 KitCgSym stack_guard_sym; 346 KitCgSym stack_fail_sym; 347 348 ObjSecId data_sec; 349 ObjSymId data_sym; 350 u32 data_base; 351 u64 data_size; 352 u8 data_local_static_target; 353 u8 data_atomize; 354 u8 data_retain; 355 u8 data_discard; 356 u8 data_tls_collect; 357 u8 data_tls_zero_fill; 358 u8 data_tls_pad[2]; 359 u32 data_tls_align; 360 Buf data_tls_bytes; 361 ObjTlsReloc* data_tls_relocs; 362 u32 data_tls_nrelocs; 363 u32 data_tls_relocs_cap; 364 }; 365 366 /* ------------------------------------------------------------------ 367 * API-misuse / invariant checks (debug-only) 368 * 369 * The cg.h contract treats a frontend that drives the value stack, scope 370 * handles, or operand kinds incorrectly as a kit bug, not a recoverable 371 * condition. CG_REQUIRE / CG_BUG state those invariants: in a debug build they 372 * fire the same rich FATAL diagnostic + longjmp as a hand-written 373 * compiler_panic, but under NDEBUG the whole check -- condition, message, and 374 * argument evaluation -- is elided, so the release hot path pays nothing. 375 * 376 * CG_REQUIRE(g, cond, fmt, ...) assert the OK condition `cond` holds 377 * CG_BUG(g, fmt, ...) mark an unreachable else/default arm 378 * 379 * Use ONLY for invariants a correct caller can never violate. Genuine resource 380 * failures (OOM, object-emission failures), unsupported-operation guards whose 381 * elision would silently miscompile, size/truncation limits, and configuration 382 * errors stay as unconditional compiler_panic so they trap in every build. 383 * ------------------------------------------------------------------ */ 384 #ifdef NDEBUG 385 /* Elided: the sizeof keeps every operand in an unevaluated context so a value 386 * or `who`-style diagnostic argument used only by the check does not become an 387 * unused variable/parameter under -Werror, while emitting no runtime code. */ 388 #define CG_REQUIRE(g, cond, ...) ((void)sizeof((g), (cond), __VA_ARGS__, 0)) 389 #define CG_BUG(g, ...) ((void)sizeof((g), __VA_ARGS__, 0)) 390 #else 391 #define CG_REQUIRE(g, cond, ...) \ 392 ((cond) ? (void)0 : compiler_panic((g)->c, (g)->cur_loc, __VA_ARGS__)) 393 #define CG_BUG(g, ...) compiler_panic((g)->c, (g)->cur_loc, __VA_ARGS__) 394 #endif 395 396 void cg_api_fini(Compiler*); 397 398 void api_cg_binop(KitCg* g, BinOp iop, u32 flags); 399 void api_cg_unop(KitCg* g, UnOp iop, u32 flags); 400 void api_cg_cmp(KitCg* g, CmpOp cop); 401 void api_cg_convert_kind(KitCg* g, KitCgTypeId dst_type, ConvKind ck); 402 void kit_cg_int_binop(KitCg* g, KitCgIntBinOp op, uint32_t flags); 403 void kit_cg_int_unop(KitCg* g, KitCgIntUnOp op, uint32_t flags); 404 void kit_cg_int_cmp(KitCg* g, KitCgIntCmpOp op); 405 const char* api_i128_binop_helper(BinOp op); 406 int api_i128_cmp_is_unsigned(CmpOp op); 407 const char* api_f128_binop_helper(KitCgFpBinOp op); 408 int api_f128_stack_top(KitCg* g, u32 depth); 409 void api_f128_call_unary(KitCg* g, const char* name, KitCgTypeId ret, 410 KitCgTypeId param); 411 void kit_cg_fp_binop(KitCg* g, KitCgFpBinOp op, uint32_t flags); 412 void kit_cg_fp_unop(KitCg* g, KitCgFpUnOp op, uint32_t flags); 413 void kit_cg_fp_cmp(KitCg* g, KitCgFpCmpOp op); 414 void kit_cg_sext(KitCg* g, KitCgTypeId dst); 415 void kit_cg_zext(KitCg* g, KitCgTypeId dst); 416 void kit_cg_trunc(KitCg* g, KitCgTypeId dst); 417 void kit_cg_ptr_to_int(KitCg* g, KitCgTypeId dst); 418 void kit_cg_int_to_ptr(KitCg* g, KitCgTypeId dst); 419 void kit_cg_bitcast(KitCg* g, KitCgTypeId dst); 420 void kit_cg_fpext(KitCg* g, KitCgTypeId dst); 421 void kit_cg_fptrunc(KitCg* g, KitCgTypeId dst); 422 void kit_cg_sint_to_float(KitCg* g, KitCgTypeId dst, KitCgRounding rounding); 423 void kit_cg_uint_to_float(KitCg* g, KitCgTypeId dst, KitCgRounding rounding); 424 void kit_cg_float_to_sint(KitCg* g, KitCgTypeId dst, KitCgRounding rounding); 425 void kit_cg_float_to_uint(KitCg* g, KitCgTypeId dst, KitCgRounding rounding); 426 IntrinKind api_map_intrinsic(KitCg* g, KitCgIntrinsic intrin, 427 KitCgTypeId result_type); 428 int api_intrinsic_is_void(KitCgIntrinsic intrin); 429 int api_intrinsic_is_overflow(KitCgIntrinsic intrin); 430 const char* api_intrinsic_name(KitCgIntrinsic intrin); 431 void kit_cg_intrinsic(KitCg* g, KitCgIntrinsic intrin, uint32_t nargs, 432 KitCgTypeId result_type); 433 KitCgTypeId api_atomic_pointee(KitCg* g, KitCgTypeId pty, const char* who); 434 const char* api_sym_cstr(KitCg* g, KitSym sym); 435 int api_asm_parse_match_index(const char* s); 436 const char* api_asm_constraint_body(const char* s); 437 int api_asm_is_early_clobber(const char* s); 438 int api_asm_is_reg_constraint(char c); 439 void api_asm_memory_clobber_sv(KitCg* g, ApiSValue* sv, CGLocal local); 440 void kit_cg_inline_asm(KitCg* g, KitCgInlineAsm asm_block); 441 void kit_cg_file_scope_asm(KitCg* g, KitSlice asm_source); 442 MemAccess api_mem_for_atomic(KitCg* g, KitCgTypeId val_ty); 443 int kit_cg_atomic_is_legal(KitCompiler* c, KitCgMemAccess access, 444 KitCgMemOrder order); 445 int kit_cg_atomic_is_lock_free(KitCompiler* c, KitCgMemAccess access); 446 void kit_cg_atomic_load(KitCg* g, KitCgMemAccess access, KitCgMemOrder order); 447 void kit_cg_atomic_store(KitCg* g, KitCgMemAccess access, KitCgMemOrder order); 448 void kit_cg_atomic_rmw(KitCg* g, KitCgMemAccess access, KitCgAtomicOp op, 449 KitCgMemOrder order); 450 void kit_cg_atomic_cmpxchg(KitCg* g, KitCgMemAccess access, 451 KitCgMemOrder success, KitCgMemOrder failure, 452 int weak); 453 void kit_cg_atomic_fence(KitCg* g, KitCgMemOrder order); 454 CGLocal* api_alloc_call_args(KitCg* g, u32 nargs); 455 void api_pack_call_arg(KitCg* g, CGLocal* out, KitCgTypeId fty, u32 idx); 456 CGLocal api_alloc_call_result(KitCg* g, KitCgTypeId ret_ty); 457 void api_push_call_result(KitCg* g, CGLocal result, KitCgTypeId ret_ty); 458 void kit_cg_call(KitCg* g, uint32_t nargs, KitCgTypeId fn_type, 459 KitCgCallAttrs attrs); 460 void api_call_symbol_common(KitCg* g, KitCgSym sym, uint32_t nargs, 461 KitCgCallAttrs attrs); 462 void kit_cg_call_symbol(KitCg* g, KitCgSym sym, uint32_t nargs, 463 KitCgCallAttrs attrs); 464 void kit_cg_ret(KitCg* g); 465 void api_stack_protector_check(KitCg* g); 466 KitCgLabel kit_cg_label_new(KitCg* g); 467 void kit_cg_label_place(KitCg* g, KitCgLabel label); 468 void kit_cg_jump(KitCg* g, KitCgLabel label); 469 void api_branch_if(KitCg* g, ApiSValue* v, int branch_when_true, Label label); 470 void kit_cg_branch_true(KitCg* g, KitCgLabel label); 471 void kit_cg_branch_false(KitCg* g, KitCgLabel label); 472 void kit_cg_switch(KitCg* g, KitCgSwitch sw); 473 void kit_cg_push_label_addr(KitCg* g, KitCgLabel label, KitCgTypeId ptr_type); 474 void kit_cg_computed_goto(KitCg* g, const KitCgLabel* valid_targets, 475 uint32_t ntargets); 476 477 void kit_cg_field_bits(KitCg* g, uint16_t bit_offset, uint16_t bit_width, 478 uint32_t bit_storage_size, int bit_signed); 479 void kit_cg_unreachable(KitCg* g); 480 KitCgScope api_scope_handle(u32 idx, u32 generation); 481 ApiCgScope* api_scope_from_handle(KitCg* g, KitCgScope scope, int require_top, 482 const char* who); 483 int api_scope_has_result(const ApiCgScope* s); 484 void api_scope_store_results(KitCg* g, ApiCgScope* s); 485 void api_scope_push_results(KitCg* g, ApiCgScope* s); 486 KitCgScope kit_cg_scope_begin(KitCg* g); 487 KitCgScope kit_cg_scope_begin_value(KitCg* g, KitCgTypeId result_type); 488 KitCgScope kit_cg_block_begin(KitCg* g); 489 KitCgScope kit_cg_block_begin_value(KitCg* g, KitCgTypeId result_type); 490 KitCgScope kit_cg_scope_begin_sig(KitCg* g, const KitCgScopeSig* sig); 491 KitCgScope kit_cg_block_begin_sig(KitCg* g, const KitCgScopeSig* sig); 492 void kit_cg_scope_store_params(KitCg* g, KitCgScope scope); 493 void kit_cg_scope_end(KitCg* g, KitCgScope scope); 494 void kit_cg_scope_end_unreachable(KitCg* g, KitCgScope scope); 495 void kit_cg_break(KitCg* g, KitCgScope scope); 496 void kit_cg_break_true(KitCg* g, KitCgScope scope); 497 void kit_cg_break_false(KitCg* g, KitCgScope scope); 498 void kit_cg_continue(KitCg* g, KitCgScope scope); 499 void kit_cg_continue_true(KitCg* g, KitCgScope scope); 500 void kit_cg_continue_false(KitCg* g, KitCgScope scope); 501 void kit_cg_alloca(KitCg* g, uint32_t align, KitCgTypeId result_ptr_type); 502 void kit_cg_vararg_start(KitCg* g); 503 void kit_cg_vararg_next(KitCg* g, KitCgTypeId type); 504 void kit_cg_vararg_end(KitCg* g); 505 void kit_cg_vararg_copy(KitCg* g); 506 void kit_cg_memcpy(KitCg* g, uint64_t size, KitCgMemAccess dst_access, 507 KitCgMemAccess src_access); 508 void kit_cg_memmove(KitCg* g, uint64_t size, KitCgMemAccess dst_access, 509 KitCgMemAccess src_access); 510 void kit_cg_memset(KitCg* g, uint8_t val, uint64_t size, 511 KitCgMemAccess dst_access); 512 void kit_cg_data_begin(KitCg* g, KitCgSym cg_sym, KitCgDataDefAttrs attrs); 513 void kit_cg_data_common(KitCg* g, KitCgSym cg_sym, uint64_t size, 514 uint32_t align); 515 void kit_cg_data_align(KitCg* g, uint32_t align); 516 void kit_cg_data_pad(KitCg* g, uint64_t size, uint8_t value); 517 void kit_cg_data_int(KitCg* g, uint64_t value, KitCgTypeId type); 518 void kit_cg_data_float(KitCg* g, double value, KitCgTypeId type); 519 void kit_cg_data_bytes(KitCg* g, const uint8_t* data, size_t len); 520 void kit_cg_data_zero(KitCg* g, uint64_t size); 521 void api_cg_data_reloc(KitCg* g, KitCgSym target, int64_t addend, 522 uint32_t width, int pcrel); 523 void kit_cg_data_addr(KitCg* g, KitCgSym target, int64_t addend, uint32_t width, 524 uint32_t address_space); 525 void kit_cg_data_label_addr(KitCg* g, KitCgLabel target, int64_t addend, 526 uint32_t width, uint32_t address_space); 527 void kit_cg_data_pcrel(KitCg* g, KitCgSym target, int64_t addend, 528 uint32_t width); 529 void kit_cg_data_symdiff(KitCg* g, KitCgSym lhs, KitCgSym rhs, int64_t addend, 530 uint32_t width); 531 void kit_cg_data_end(KitCg* g); 532 ObjSymId api_emit_label_table(KitCg* g, const Label* labels, u32 n); 533 DebugTypeId api_debug_type(KitCg* g, KitCgDebugType debug_type, 534 KitCgTypeId fallback_type); 535 int api_local_requires_memory(KitCg* g, KitCgTypeId ty, KitCgLocalAttrs attrs); 536 KitCgLocal api_local_handle(u32 index); 537 int api_grow_locals(KitCg* g, u32 want); 538 int api_grow_scopes(KitCg* g, u32 want); 539 ApiSourceLocal* api_local_from_handle(KitCg* g, KitCgLocal local); 540 CGLocal api_frame_local_storage(KitCg* g, const CGLocalDesc* d); 541 KitCgLocal kit_cg_local(KitCg* g, KitCgTypeId type, KitCgLocalAttrs attrs); 542 KitCgLocal kit_cg_param(KitCg* g, uint32_t index, KitCgTypeId type, 543 KitCgLocalAttrs attrs); 544 void kit_cg_push_int(KitCg* g, uint64_t value, KitCgTypeId type); 545 void kit_cg_push_float(KitCg* g, double value, KitCgTypeId type); 546 void kit_cg_push_null(KitCg* g, KitCgTypeId ptr_type); 547 KitCgSym kit_cg_const_data(KitCg* g, const uint8_t* data, size_t len, 548 uint32_t align, KitCgTypeId pointee_type); 549 void api_push_local_lvalue(KitCg* g, CGLocal local, KitCgTypeId type); 550 void api_push_source_local_lvalue(KitCg* g, KitCgLocal local, CGLocal storage, 551 KitCgTypeId type); 552 void kit_cg_push_local(KitCg* g, KitCgLocal local); 553 void kit_cg_push_local_addr(KitCg* g, KitCgLocal local); 554 void kit_cg_push_symbol_addr(KitCg* g, KitCgSym sym, int64_t addend); 555 void kit_cg_load(KitCg* g, KitCgMemAccess access); 556 void kit_cg_addr(KitCg* g); 557 void kit_cg_deref(KitCg* g, int64_t offset); 558 void kit_cg_store(KitCg* g, KitCgMemAccess access); 559 void kit_cg_store_keep(KitCg* g, KitCgMemAccess access); 560 void kit_cg_field_at(KitCg* g, int64_t byte_offset, KitCgTypeId field_type); 561 void kit_cg_dup(KitCg* g); 562 void kit_cg_dup2(KitCg* g); 563 void kit_cg_swap(KitCg* g); 564 void kit_cg_drop(KitCg* g); 565 KitCgSlotInfo kit_cg_slot_info(KitCg* g, uint32_t depth_from_top); 566 KitCgTypeId kit_cg_slot_cg_type(KitCg* g, uint32_t depth_from_top); 567 const void* kit_cg_slot_lang_type(KitCg* g, uint32_t depth_from_top); 568 uint16_t kit_cg_slot_lang_flags(KitCg* g, uint32_t depth_from_top); 569 void kit_cg_retag_top(KitCg* g, const void* lang_type, uint16_t lang_flags); 570 void kit_cg_retag_at(KitCg* g, uint32_t depth_from_top, const void* lang_type, 571 uint16_t lang_flags); 572 void kit_cg_set_top_flags(KitCg* g, uint16_t set, uint16_t clear); 573 uint32_t kit_cg_stack_depth(KitCg* g); 574 int kit_cg_top_const_int(KitCg* g, int64_t* out_value); 575 void kit_cg_rot3(KitCg* g); 576 KitStatus kit_cg_new(KitCompiler* c, KitCg** cg_out); 577 KitStatus kit_cg_begin(KitCg* g, KitObjBuilder* out, 578 const KitCodeOptions* opts); 579 KitStatus kit_cg_begin_unit(KitCg* g, const KitCgUnitOptions* opts); 580 KitStatus kit_cg_end_unit(KitCg* g); 581 KitStatus kit_cg_finish(KitCg* g, const KitCgFinishOptions* opts); 582 KitStatus kit_cg_detach(KitCg* g); 583 KitStatus kit_cg_abort(KitCg* g); 584 void kit_cg_free(KitCg* g); 585 void kit_cg_set_loc(KitCg* g, KitSrcLoc loc); 586 KitCgSym kit_cg_decl(KitCg* g, KitCgDecl decl); 587 KitCgSym kit_cg_alias(KitCg* g, KitCgAlias alias); 588 void kit_cg_func_begin(KitCg* g, KitCgSym cg_sym); 589 void kit_cg_func_begin_attrs(KitCg* g, KitCgSym cg_sym, KitCgFuncAttrs attrs); 590 void kit_cg_func_end(KitCg* g); 591 SymBind api_map_bind(KitSymBind b); 592 SymVis api_map_vis(KitCgVisibility v); 593 SymKind api_decl_sym_kind(KitCgDecl decl); 594 Sym api_cg_symbol_section_name(KitCg* g, Slice base, KitSym linkage_name); 595 void api_remember_sym(KitCg* g, ObjSymId sym, KitCgTypeId ty, KitCgDecl decl); 596 KitCgTypeId api_sym_type(KitCg* g, KitCgSym sym); 597 KitCgDecl api_sym_attrs(KitCg* g, KitCgSym sym); 598 int api_sym_is_tls(KitCg* g, KitCgSym sym); 599 RelocKind api_data_reloc_kind(int pcrel, uint32_t width); 600 SrcLoc api_no_loc(void); 601 /* Type-property predicates (api_type_is_float / api_is_*_type) and the type 602 * classification (api_type_class) are declared in cg/type.h. */ 603 604 /* Delayed cmp/arith payload pool (fold.c). alloc returns a payload from the 605 * per-function freelist or the arena; free returns it for reuse; reset drops 606 * the whole pool at a function boundary. */ 607 ApiDelayed* api_delayed_alloc(KitCg* g); 608 void api_delayed_free(KitCg* g, ApiDelayed* d); 609 void api_delayed_reset(KitCg* g); 610 Operand api_op_imm(i64 v, KitCgTypeId ty); 611 Operand api_op_local(CGLocal r, KitCgTypeId ty); 612 Operand api_op_global(ObjSymId sym, i64 addend, KitCgTypeId ty); 613 Operand api_op_indirect(CGLocal base, i32 ofs, KitCgTypeId ty); 614 Operand api_op_indirect_indexed(CGLocal base, CGLocal index, u8 log2_scale, 615 i32 ofs, KitCgTypeId ty); 616 u8 api_residency_for(const Operand* o); 617 ApiSValue api_make_sv(Operand op, KitCgTypeId ty); 618 ApiSValue api_make_lv(Operand op, KitCgTypeId ty); 619 ApiSValue api_make_sv_with_local_ownership(Operand op, KitCgTypeId ty, 620 int owned); 621 KitCgTypeId api_sv_type(const ApiSValue* sv); 622 int api_operand_can_address(const Operand* o); 623 int api_sv_op_is(const ApiSValue* sv, OpKind kind); 624 int api_sv_op_is_local_or_imm(const ApiSValue* sv); 625 int api_is_lvalue_sv(const ApiSValue* sv); 626 int api_sv_is_bitfield(const ApiSValue* sv); 627 MemAccess api_mem_for_bitfield(KitCg* g, const ApiSValue* sv, 628 const Operand* storage, KitCgTypeId field_ty); 629 void api_stack_grow(KitCg* g, u32 want); 630 void api_push(KitCg* g, ApiSValue v); 631 ApiSValue api_pop(KitCg* g); 632 int api_unevaluated(KitCg* g); 633 ApiSValue api_uneval_value(KitCg* g, KitCgTypeId type); 634 ApiSValue api_uneval_place(KitCg* g, KitCgTypeId type); 635 ApiConstValue api_const_unknown(KitCgTypeId type); 636 ApiConstValue api_const_from_sv(KitCg* g, const ApiSValue* sv); 637 ApiConstValue api_const_at(KitCg* g, u32 depth); 638 void api_const_set_top(KitCg* g, ApiConstValue value); 639 void api_const_set_at(KitCg* g, u32 depth, ApiConstValue value); 640 void api_const_copy_top_from(KitCg* g, ApiConstValue value); 641 ApiConstValue api_const_for_push(KitCg* g, KitCgTypeId type, 642 const KitCgConstInt* value); 643 int api_const_fold_binop(KitCg* g, BinOp op, KitCgTypeId type, ApiConstValue a, 644 ApiConstValue b, u32 flags, ApiConstValue* out); 645 int api_const_fold_unop(KitCg* g, UnOp op, KitCgTypeId type, ApiConstValue a, 646 u32 flags, ApiConstValue* out); 647 int api_const_fold_cmp(KitCg* g, CmpOp op, ApiConstValue a, ApiConstValue b, 648 ApiConstValue* out); 649 int api_const_fold_convert(KitCg* g, ConvKind ck, KitCgTypeId src_type, 650 KitCgTypeId dst_type, ApiConstValue in, 651 ApiConstValue* out); 652 ApiConstValue api_const_int_result(KitCg* g, KitCgTypeId type, u64 lo, u64 hi, 653 int is_signed); 654 CGLocal api_local_of_sv(const ApiSValue* sv); 655 void api_set_owned_local(ApiSValue* sv, CGLocal r); 656 KitCgTypeId api_owned_local_type(KitCg* g, const ApiSValue* sv); 657 CGLocal api_alloc_temp_local(KitCg* g, KitCgTypeId ty); 658 MemAccess api_mem_for_lvalue(KitCg* g, const Operand* lv, KitCgTypeId ty); 659 MemAccess api_mem_from_access_resolved(KitCg* g, const Operand* lv, 660 KitCgMemAccess access, KitCgTypeId ty); 661 MemAccess api_mem_from_access(KitCg* g, const Operand* lv, 662 KitCgMemAccess access); 663 KitCgTypeId api_mem_access_type(KitCg* g, KitCgMemAccess access, 664 KitCgTypeId fallback, const char* who); 665 u32 api_mem_type_size_resolved(KitCg* g, KitCgTypeId ty, const char* who); 666 u32 api_mem_type_size(KitCg* g, KitCgTypeId ty, const char* who); 667 u32 api_require_scalar_mem_type_resolved(KitCg* g, const char* who, 668 KitCgTypeId ty); 669 void api_require_scalar_mem_type(KitCg* g, const char* who, KitCgTypeId ty); 670 void api_require_pointer_value(KitCg* g, const char* who, KitCgTypeId ty); 671 void api_validate_memory_value_resolved(KitCg* g, const char* who, 672 KitCgTypeId access_ty, 673 KitCgTypeId value_ty); 674 void api_validate_memory_value(KitCg* g, const char* who, KitCgTypeId access_ty, 675 KitCgTypeId value_ty); 676 int api_sv_owns_operand_local(const ApiSValue* sv, const Operand* op); 677 void api_ensure_local(KitCg* g, ApiSValue* sv); 678 Operand api_force_local(KitCg* g, ApiSValue* v, KitCgTypeId ty); 679 Operand api_force_local_unless_imm(KitCg* g, ApiSValue* v, KitCgTypeId ty); 680 void api_release(KitCg* g, ApiSValue* sv); 681 682 /* -O0 transient liveness (see KitCg.local_refs). api_coalesce_on returns 683 * whether the copy/dup coalescing + finer-reclaim mechanisms are enabled this 684 * run. api_temp_dead reports whether transient `local` is provably dead right 685 * now (no live value-stack entry references it): count==0 confirmed by a stack 686 * scan. api_reseat_{begin,end} bracket an in-place change to a stack entry's 687 * operand so its references are re-accounted. */ 688 int api_coalesce_on(KitCg* g); 689 int api_temp_dead(KitCg* g, CGLocal local); 690 /* Flag OP for the -O0 backend's eager dead-operand drop: when coalescing is on 691 * and OP names a transient that api_temp_dead confirms is dead after the 692 * consuming op, AND OP is distinct from that op's destination DST (so it is not 693 * the result being written), return OP with OPK_FLAG_KILL set; otherwise return 694 * OP unchanged. The NativeDirectTarget then drops OP's live cache register 695 * after the op (no spill, no reload) instead of leaving it resident to be 696 * flush-stored at the next barrier. Pass a non-OPK_LOCAL operand for DST (e.g. 697 * the store's memory place) when the op has no local destination — the 698 * self-guard is then a no-op. */ 699 Operand api_op_kill_if_dead(KitCg* g, Operand op, Operand dst); 700 void api_reseat_begin(KitCg* g, const ApiSValue* sv); 701 void api_reseat_end(KitCg* g, const ApiSValue* sv); 702 703 BinOp api_map_int_binop(KitCgIntBinOp op); 704 BinOp api_map_fp_binop(KitCgFpBinOp op); 705 UnOp api_map_int_unop(KitCgIntUnOp op); 706 CmpOp api_map_int_cmp(KitCgIntCmpOp op); 707 CmpOp api_map_fp_cmp(KitCgFpCmpOp op); 708 Operand api_lvalue_addr(KitCg* g, ApiSValue* v, KitCgTypeId pty); 709 CGLocal api_f128_temp_local(KitCg* g, KitCgTypeId ty); 710 u64 api_u64_from_target_bytes(KitCg* g, const u8* bytes); 711 void api_store_f128_bytes(KitCg* g, CGLocal local, KitCgTypeId ty, 712 const u8 bytes[16]); 713 void api_wide16_sext_imm_bytes(KitCg* g, i64 imm, u8 bytes[16]); 714 ApiSValue api_make_wide16_int_const(KitCg* g, i64 value, KitCgTypeId ty); 715 ApiSValue api_make_wide16_int_const_bits(KitCg* g, u64 lo, u64 hi, 716 KitCgTypeId ty); 717 void api_encode_binary128_from_double(KitCg* g, double value, u8 out[16]); 718 ApiSValue api_make_f128_const(KitCg* g, double value, KitCgTypeId ty); 719 ApiSValue api_wide16_materialize_lvalue(KitCg* g, ApiSValue* v, KitCgTypeId ty); 720 CGLocal api_wide8_temp_local(KitCg* g, KitCgTypeId ty); 721 ApiSValue api_make_wide8_const_bits(KitCg* g, u64 bits, KitCgTypeId ty); 722 ApiSValue api_make_wide8_int_const(KitCg* g, i64 value, KitCgTypeId ty); 723 Operand api_wide8_addr(KitCg* g, ApiSValue* v, KitCgTypeId ty); 724 Operand api_wide8_load_lane(KitCg* g, Operand addr, i32 off); 725 void api_wide8_store_lane(KitCg* g, Operand addr, i32 off, Operand val); 726 Operand api_wide8_or_lanes(KitCg* g, ApiSValue* v, KitCgTypeId ty); 727 KitCgSym api_runtime_helper(KitCg* g, const char* name, KitCgTypeId ret, 728 const KitCgTypeId* params, u32 nparams); 729 void api_runtime_call_values(KitCg* g, const char* name, KitCgTypeId ret, 730 const KitCgTypeId* params, u32 nparams, 731 ApiSValue* args); 732 733 /* The semantic-layer peephole optimizer: constant folding, the delayed 734 * compare/arith forms, and const-local store-to-load forwarding. Included here, 735 * after the operand and value types above, so its declarations can name 736 * ApiSValue / ApiSourceLocal / Operand. */ 737 #include "cg/fold.h" 738 739 #endif