# emit_fence_ir.ludic - the allocation fence's runtime (25.1), as IR. Generated from a # template (docs/plan 25); the tables sized by the program are emit_fence.ludic's. function emit_fence_globals() -> void { emith("@lp_site = global i32 0\n") emith("@lp_fdecl = global i32 0\n") emith("@lp_dlive = global i64 0\n") emith("@lp_mdlive = global i64 0\n") emith("@lp_sdlive = global i64 0\n") emith("@lp_ft = global i8 0\n") emith("@lp_fm = global i8 0\n") emith("@lp_fj = global i8 0\n") emith("@lp_fl = global i32 0\n") emith("@lp_tab = global ptr null\n") emith("@lp_tabmask = global i64 0\n") emith("@lp_tabn = global i64 0\n") emith("@lp_tabmax = global i64 0\n") emith("@lp_live = global i64 0\n") emith("@lp_pre = global i64 0\n") emith("@lp_made = global i64 0\n") emith("@lp_freed = global i64 0\n") emith("@lp_over = global i64 0\n") emith("@lp_overrep = global i8 0\n") emith("@lp_frame = global i64 0\n") emith("@lp_flat = global i64 0\n") emith("@lp_playf = global i64 0\n") emith("@lp_warm_max = global i64 -1\n") emith("@lp_fauto = global i8 1\n") emith("@lp_autoplay = global i64 -1\n") emith("@lp_mlive = global i64 0\n") emith("@lp_mpre = global i64 0\n") emith("@lp_mmade = global i64 0\n") emith("@lp_mfreed = global i64 0\n") emith("@lp_slive = global i64 0\n") emith("@lp_spre = global i64 0\n") emith("@lp_touch = global [512 x i32] zeroinitializer\n") emith("@lp_ntouch = global i32 0\n") emith("@lp_fkept = global i64 0\n") emith("@lp_fbad = global i64 0\n") emith("@lp_fjudged = global i64 0\n") emith("@lp_zset = global i64 0\n") emith("@lp_jset = global i64 0\n") emith("@lp_vset = global i64 0\n") emith("@lp_census = global ptr null\n") emith("declare extern_weak i64 @malloc_size(ptr)\n") emith("declare i32 @dprintf(i32, ptr, ...)\n") emith("declare i32 @_Unwind_Backtrace(ptr, ptr)\n") emith("declare i64 @_Unwind_GetIP(ptr)\n") emith("declare i32 @dladdr(ptr, ptr)\n") emith("declare ptr @dlsym(ptr, ptr)\n") emith("@.lpf_env = private unnamed_addr constant [16 x i8] c\"R3D_ALLOC_FENCE\\00\"\n") emith("@.lpf_warm = private unnamed_addr constant [15 x i8] c\"R3D_ALLOC_WARM\\00\"\n") emith("@.lpf_play = private unnamed_addr constant [15 x i8] c\"R3D_ALLOC_PLAY\\00\"\n") emith("@.lpf_tab = private unnamed_addr constant [16 x i8] c\"R3D_ALLOC_TABLE\\00\"\n") emith("@.lpf_dev = private unnamed_addr constant [8 x i8] c\"R3D_DEV\\00\"\n") emith("@.lpf_off = private unnamed_addr constant [4 x i8] c\"off\\00\"\n") emith("@.lpf_count = private unnamed_addr constant [6 x i8] c\"count\\00\"\n") emith("@.lpf_warn = private unnamed_addr constant [5 x i8] c\"warn\\00\"\n") emith("@.lpf_fail = private unnamed_addr constant [5 x i8] c\"fail\\00\"\n") emith("@.lpf_hdr = private unnamed_addr constant [62 x i8] c\"alloc-fence: frame %lld kept %+lld B (%lld made, %lld freed)\\0A\\00\"\n") emith("@.lpf_row = private unnamed_addr constant [26 x i8] c\" %+lld B %s %s:%d %s\\0A\\00\"\n") emith("@.lpf_more = private unnamed_addr constant [21 x i8] c\" ... and %lld more\\0A\\00\"\n") emith("@.lpf_full = private unnamed_addr constant [99 x i8] c\"alloc-fence: the table is full (%lld blocks) - raise R3D_ALLOC_TABLE; from here it judges nothing\\0A\\00\"\n") emith("@.lpf_failing = private unnamed_addr constant [53 x i8] c\"alloc-fence: failing the run (R3D_ALLOC_FENCE=fail)\\0A\\00\"\n") emith("@.lpf_census = private unnamed_addr constant [17 x i8] c\"R3D_ALLOC_CENSUS\\00\"\n") emith("@.lpf_warmmax = private unnamed_addr constant [19 x i8] c\"R3D_ALLOC_WARM_MAX\\00\"\n") emith("@.lpf_auto = private unnamed_addr constant [15 x i8] c\"R3D_ALLOC_AUTO\\00\"\n") emith("@.lpf_w = private unnamed_addr constant [2 x i8] c\"w\\00\"\n") emith("@.lpf_chdr = private unnamed_addr constant [76 x i8] c\"alloc-census frames %lld bad %lld kept %lld made %lld freed %lld over %lld\\0A\\00\"\n") emith("@.lpf_cnat = private unnamed_addr constant [116 x i8] c\"native %lld (the heap outside Ludic's blocks and the counted libraries, since judging began: drivers, Metal, libc)\\0A\\00\"\n") emith("@.lpf_cdecl = private unnamed_addr constant [58 x i8] c\"declared %lld (kept under @alloc_ok since judging began)\\0A\\00\"\n") emith("@.lpf_cjolt = private unnamed_addr constant [68 x i8] c\"jolt %lld peak %lld (since judging began, and its high-water mark)\\0A\\00\"\n") emith("@.lpf_cvk = private unnamed_addr constant [83 x i8] c\"vulkan %lld peak %lld (host memory through VkAllocationCallbacks, R3D_ALLOC_VK=1)\\0A\\00\"\n") emith("@.lpf_jb = private unnamed_addr constant [15 x i8] c\"jph_heap_bytes\\00\"\n") emith("@.lpf_jp = private unnamed_addr constant [14 x i8] c\"jph_heap_peak\\00\"\n") emith("@.lpf_vb = private unnamed_addr constant [13 x i8] c\"lvk_ac_bytes\\00\"\n") emith("@.lpf_vp = private unnamed_addr constant [12 x i8] c\"lvk_ac_peak\\00\"\n") emith("@.lpf_crow = private unnamed_addr constant [23 x i8] c\"site %lld %s %s:%d %s\\0A\\00\"\n") emith("@.lpf_from = private unnamed_addr constant [15 x i8] c\" from %s\\0A\\00\"\n") emith("@.lpf_cfrom = private unnamed_addr constant [11 x i8] c\" from %s\\0A\\00\"\n") emith("@.lpf_lp = private unnamed_addr constant [4 x i8] c\"lp_\\00\"\n") } function emit_fence_entry() -> void { emith("define ptr @lp_malloc(i64 %n) {\n") emith("entry:\n") emith(" %t = load i8, ptr @lp_ft\n") emith(" %on = icmp ne i8 %t, 0\n") emith(" br i1 %on, label %slow, label %fast\n") emith("fast:\n") emith(" %p = tail call ptr @malloc(i64 %n)\n") emith(" ret ptr %p\n") emith("slow:\n") emith(" %q = call ptr @malloc(i64 %n)\n") emith(" call void @lp_fadd(ptr %q, i64 %n)\n") emith(" ret ptr %q\n") emith("}\n") emith("define ptr @lp_calloc(i64 %n, i64 %s) {\n") emith("entry:\n") emith(" %t = load i8, ptr @lp_ft\n") emith(" %on = icmp ne i8 %t, 0\n") emith(" br i1 %on, label %slow, label %fast\n") emith("fast:\n") emith(" %p = tail call ptr @calloc(i64 %n, i64 %s)\n") emith(" ret ptr %p\n") emith("slow:\n") emith(" %q = call ptr @calloc(i64 %n, i64 %s)\n") emith(" %b = mul i64 %n, %s\n") emith(" call void @lp_fadd(ptr %q, i64 %b)\n") emith(" ret ptr %q\n") emith("}\n") emith("define ptr @lp_realloc(ptr %o, i64 %n) {\n") emith("entry:\n") emith(" %t = load i8, ptr @lp_ft\n") emith(" %on = icmp ne i8 %t, 0\n") emith(" br i1 %on, label %slow, label %fast\n") emith("fast:\n") emith(" %p = tail call ptr @realloc(ptr %o, i64 %n)\n") emith(" ret ptr %p\n") emith("slow:\n") emith(" call void @lp_fdel(ptr %o)\n") emith(" %q = call ptr @realloc(ptr %o, i64 %n)\n") emith(" call void @lp_fadd(ptr %q, i64 %n)\n") emith(" ret ptr %q\n") emith("}\n") emith("define void @lp_free(ptr %o) {\n") emith("entry:\n") emith(" %t = load i8, ptr @lp_ft\n") emith(" %on = icmp ne i8 %t, 0\n") emith(" br i1 %on, label %slow, label %fast\n") emith("fast:\n") emith(" tail call void @free(ptr %o)\n") emith(" ret void\n") emith("slow:\n") emith(" call void @lp_fdel(ptr %o)\n") emith(" call void @free(ptr %o)\n") emith(" ret void\n") emith("}\n") } function emit_fence_table() -> void { emith("define internal void @lp_flock() {\n") emith("entry:\n") emith(" br label %spin\n") emith("spin:\n") emith(" %o = atomicrmw xchg ptr @lp_fl, i32 1 acquire\n") emith(" %b = icmp eq i32 %o, 0\n") emith(" br i1 %b, label %done, label %spin\n") emith("done:\n") emith(" ret void\n") emith("}\n") emith("define internal void @lp_funlock() {\n") emith("entry:\n") emith(" store atomic i32 0, ptr @lp_fl release, align 4\n") emith(" ret void\n") emith("}\n") emith("define internal i64 @lp_fhash(i64 %k) {\n") emith("entry:\n") emith(" %a = lshr i64 %k, 4\n") emith(" %b = mul i64 %a, -7046029254386353131\n") emith(" %c = lshr i64 %b, 29\n") emith(" %d = xor i64 %b, %c\n") emith(" ret i64 %d\n") emith("}\n") emith("define internal void @lp_ftouch(i64 %s) {\n") emith("entry:\n") emith(" %sp = getelementptr inbounds i64, ptr @lp_site_stamp, i64 %s\n") emith(" %st = load i64, ptr %sp\n") emith(" %f = load i64, ptr @lp_frame\n") emith(" %f1 = add i64 %f, 1\n") emith(" %seen = icmp eq i64 %st, %f1\n") emith(" br i1 %seen, label %out, label %mark\n") emith("mark:\n") emith(" store i64 %f1, ptr %sp\n") emith(" %n = load i32, ptr @lp_ntouch\n") emith(" %room = icmp ult i32 %n, 512\n") emith(" %n1 = add i32 %n, 1\n") emith(" store i32 %n1, ptr @lp_ntouch\n") emith(" br i1 %room, label %put, label %out\n") emith("put:\n") emith(" %tp = getelementptr inbounds [512 x i32], ptr @lp_touch, i32 0, i32 %n\n") emith(" %s32 = trunc i64 %s to i32\n") emith(" store i32 %s32, ptr %tp\n") emith(" br label %out\n") emith("out:\n") emith(" ret void\n") emith("}\n") emith("define internal void @lp_fsite_add(i64 %s, i64 %n) {\n") emith("entry:\n") emith(" %sp = getelementptr inbounds i64, ptr @lp_site_live, i64 %s\n") emith(" %v = load i64, ptr %sp\n") emith(" %v1 = add i64 %v, %n\n") emith(" store i64 %v1, ptr %sp\n") emith(" %lv = load i64, ptr @lp_live\n") emith(" %lv1 = add i64 %lv, %n\n") emith(" store i64 %lv1, ptr @lp_live\n") emith(" call void @lp_ftouch(i64 %s)\n") emith(" ret void\n") emith("}\n") emith("; the last six return addresses above an allocation of site s, from the unwinder (the emitted\n") emith("; functions keep no frame-pointer chain), taken only once judging has begun: what is made then is\n") emith("; what a report names, and it is rare\n") emith("define internal i32 @lp_funw(ptr %ctx, ptr %st) {\n") emith("entry:\n") emith(" %n = load i64, ptr %st\n") emith(" %full = icmp uge i64 %n, 6\n") emith(" br i1 %full, label %stop, label %take\n") emith("take:\n") emith(" %ip = call i64 @_Unwind_GetIP(ptr %ctx)\n") emith(" %bp = getelementptr inbounds i64, ptr %st, i64 1\n") emith(" %base = load i64, ptr %bp\n") emith(" %slot = add i64 %base, %n\n") emith(" %dst = getelementptr inbounds i64, ptr @lp_site_ra, i64 %slot\n") emith(" store i64 %ip, ptr %dst\n") emith(" %n1 = add i64 %n, 1\n") emith(" store i64 %n1, ptr %st\n") emith(" ret i32 0\n") emith("stop:\n") emith(" ret i32 5\n") emith("}\n") emith("define internal void @lp_fcallers(i64 %s) noinline {\n") emith("entry:\n") emith(" %j = load i8, ptr @lp_fj\n") emith(" %judging = icmp ne i8 %j, 0\n") emith(" br i1 %judging, label %walk, label %out\n") emith("walk:\n") emith(" %st = alloca [2 x i64], align 8\n") emith(" store i64 0, ptr %st\n") emith(" %bp = getelementptr inbounds i64, ptr %st, i64 1\n") emith(" %base = mul i64 %s, 6\n") emith(" store i64 %base, ptr %bp\n") emith(" %z = getelementptr inbounds i64, ptr @lp_site_ra, i64 %base\n") emith(" call ptr @memset(ptr %z, i32 0, i64 48)\n") emith(" call i32 @_Unwind_Backtrace(ptr @lp_funw, ptr %st)\n") emith(" br label %out\n") emith("out:\n") emith(" ret void\n") emith("}\n") emith("; the Ludic functions a site was last reached from: its callers' names, those of the fence and of\n") emith("; the site's own function left out\n") emith("define internal void @lp_fsite_from(ptr %fp, i32 %s, ptr %own) {\n") emith("entry:\n") emith(" %info = alloca [4 x ptr], align 8\n") emith(" %s64 = sext i32 %s to i64\n") emith(" %base = mul i64 %s64, 6\n") emith(" br label %loop\n") emith("loop:\n") emith(" %i = phi i64 [ 0, %entry ], [ %i1, %next ]\n") emith(" %shown = phi i32 [ 0, %entry ], [ %shown1, %next ]\n") emith(" %more = icmp ult i64 %i, 6\n") emith(" %room = icmp ult i32 %shown, 3\n") emith(" %go = and i1 %more, %room\n") emith(" br i1 %go, label %body, label %out\n") emith("body:\n") emith(" %slot = add i64 %base, %i\n") emith(" %rp = getelementptr inbounds ptr, ptr @lp_site_ra, i64 %slot\n") emith(" %ra0 = load ptr, ptr %rp\n") emith(" %ra = getelementptr i8, ptr %ra0, i64 -1\n") emith(" %nul = icmp eq ptr %ra0, null\n") emith(" br i1 %nul, label %skip, label %look\n") emith("look:\n") emith(" %ok = call i32 @dladdr(ptr %ra, ptr %info)\n") emith(" %okq = icmp ne i32 %ok, 0\n") emith(" br i1 %okq, label %named, label %skip\n") emith("named:\n") emith(" %snp = getelementptr inbounds [4 x ptr], ptr %info, i32 0, i32 2\n") emith(" %sn = load ptr, ptr %snp\n") emith(" %snnul = icmp eq ptr %sn, null\n") emith(" br i1 %snnul, label %skip, label %filter\n") emith("filter:\n") emith(" %c1 = call i32 @strncmp(ptr %sn, ptr @.lpf_lp, i64 3)\n") emith(" %islp = icmp eq i32 %c1, 0\n") emith(" %own3 = getelementptr inbounds i8, ptr %sn, i64 3\n") emith(" %c2 = call i32 @strcmp(ptr %own3, ptr %own)\n") emith(" %isown = icmp eq i32 %c2, 0\n") emith(" %drop = or i1 %islp, %isown\n") emith(" br i1 %drop, label %skip, label %print\n") emith("print:\n") emith(" %tofile = icmp ne ptr %fp, null\n") emith(" br i1 %tofile, label %pf, label %pe\n") emith("pf:\n") emith(" call i32 (ptr, ptr, ...) @fprintf(ptr %fp, ptr @.lpf_cfrom, ptr %sn)\n") emith(" br label %counted\n") emith("pe:\n") emith(" call i32 (i32, ptr, ...) @dprintf(i32 2, ptr @.lpf_from, ptr %sn)\n") emith(" br label %counted\n") emith("counted:\n") emith(" br label %next\n") emith("skip:\n") emith(" br label %next\n") emith("next:\n") emith(" %add = phi i32 [ 1, %counted ], [ 0, %skip ]\n") emith(" %shown1 = add i32 %shown, %add\n") emith(" %i1 = add i64 %i, 1\n") emith(" br label %loop\n") emith("out:\n") emith(" ret void\n") emith("}\n") emith("define internal void @lp_fadd(ptr %p, i64 %asked) {\n") emith("entry:\n") emith(" %isnull = icmp eq ptr %p, null\n") emith(" br i1 %isnull, label %out, label %size\n") emith("size:\n") emith(" %hasms = icmp ne ptr @malloc_size, null\n") emith(" br i1 %hasms, label %real, label %go\n") emith("real:\n") emith(" %ms = call i64 @malloc_size(ptr %p)\n") emith(" br label %go\n") emith("go:\n") emith(" %n = phi i64 [ %asked, %size ], [ %ms, %real ]\n") emith(" call void @lp_flock()\n") emith(" %cnt = load i64, ptr @lp_tabn\n") emith(" %max = load i64, ptr @lp_tabmax\n") emith(" %full = icmp sge i64 %cnt, %max\n") emith(" br i1 %full, label %over, label %ins\n") emith("over:\n") emith(" %ov = load i64, ptr @lp_over\n") emith(" %ov1 = add i64 %ov, 1\n") emith(" store i64 %ov1, ptr @lp_over\n") emith(" br label %unlock\n") emith("ins:\n") emith(" %s0 = load i32, ptr @lp_site\n") emith(" %sn = load i32, ptr @lp_site_n\n") emith(" %sok = icmp ult i32 %s0, %sn\n") emith(" %s = select i1 %sok, i32 %s0, i32 0\n") emith(" %s64 = zext i32 %s to i64\n") emith(" %k = ptrtoint ptr %p to i64\n") emith(" %h = call i64 @lp_fhash(i64 %k)\n") emith(" %mask = load i64, ptr @lp_tabmask\n") emith(" %tab = load ptr, ptr @lp_tab\n") emith(" br label %probe\n") emith("probe:\n") emith(" %i = phi i64 [ %h, %ins ], [ %i1, %next ]\n") emith(" %im = and i64 %i, %mask\n") emith(" %e = getelementptr inbounds [2 x i64], ptr %tab, i64 %im\n") emith(" %ek = load i64, ptr %e\n") emith(" %empty = icmp eq i64 %ek, 0\n") emith(" br i1 %empty, label %put, label %chk\n") emith("chk:\n") emith(" %same = icmp eq i64 %ek, %k\n") emith(" br i1 %same, label %dup, label %next\n") emith("next:\n") emith(" %i1 = add i64 %im, 1\n") emith(" br label %probe\n") emith("dup:\n") emith(" %dv = getelementptr inbounds i64, ptr %e, i64 1\n") emith(" %dold = load i64, ptr %dv\n") emith(" %dn = and i64 %dold, 549755813887\n") emith(" %ds = lshr i64 %dold, 40\n") emith(" %dneg = sub i64 0, %dn\n") emith(" call void @lp_fsite_add(i64 %ds, i64 %dneg)\n") emith(" %dwd = and i64 %dold, 549755813888\n") emith(" %dwas = icmp ne i64 %dwd, 0\n") emith(" %ddl = load i64, ptr @lp_dlive\n") emith(" %ddsub = select i1 %dwas, i64 %dn, i64 0\n") emith(" %ddl1 = sub i64 %ddl, %ddsub\n") emith(" store i64 %ddl1, ptr @lp_dlive\n") emith(" %dtn = load i64, ptr @lp_tabn\n") emith(" %dtn1 = sub i64 %dtn, 1\n") emith(" store i64 %dtn1, ptr @lp_tabn\n") emith(" %dfr = load i64, ptr @lp_freed\n") emith(" %dfr1 = add i64 %dfr, 1\n") emith(" store i64 %dfr1, ptr @lp_freed\n") emith(" br label %put\n") emith("put:\n") emith(" store i64 %k, ptr %e\n") emith(" %ev = getelementptr inbounds i64, ptr %e, i64 1\n") emith(" %sh = shl i64 %s64, 40\n") emith(" %v0 = or i64 %sh, %n\n") emith(" %dc = load i32, ptr @lp_fdecl\n") emith(" %isdecl = icmp sgt i32 %dc, 0\n") emith(" %dbit = select i1 %isdecl, i64 549755813888, i64 0\n") emith(" %v = or i64 %v0, %dbit\n") emith(" store i64 %v, ptr %ev\n") emith(" %dl = load i64, ptr @lp_dlive\n") emith(" %dadd = select i1 %isdecl, i64 %n, i64 0\n") emith(" %dl1 = add i64 %dl, %dadd\n") emith(" store i64 %dl1, ptr @lp_dlive\n") emith(" %tn = load i64, ptr @lp_tabn\n") emith(" %tn1 = add i64 %tn, 1\n") emith(" store i64 %tn1, ptr @lp_tabn\n") emith(" %md = load i64, ptr @lp_made\n") emith(" %md1 = add i64 %md, 1\n") emith(" store i64 %md1, ptr @lp_made\n") emith(" call void @lp_fsite_add(i64 %s64, i64 %n)\n") emith(" call void @lp_fcallers(i64 %s64)\n") emith(" br label %unlock\n") emith("unlock:\n") emith(" call void @lp_funlock()\n") emith(" br label %out\n") emith("out:\n") emith(" ret void\n") emith("}\n") emith("define internal void @lp_fdel(ptr %p) {\n") emith("entry:\n") emith(" %isnull = icmp eq ptr %p, null\n") emith(" br i1 %isnull, label %out, label %go\n") emith("go:\n") emith(" call void @lp_flock()\n") emith(" %k = ptrtoint ptr %p to i64\n") emith(" %h = call i64 @lp_fhash(i64 %k)\n") emith(" %mask = load i64, ptr @lp_tabmask\n") emith(" %tab = load ptr, ptr @lp_tab\n") emith(" br label %probe\n") emith("probe:\n") emith(" %i = phi i64 [ %h, %go ], [ %i1, %next ]\n") emith(" %im = and i64 %i, %mask\n") emith(" %e = getelementptr inbounds [2 x i64], ptr %tab, i64 %im\n") emith(" %ek = load i64, ptr %e\n") emith(" %empty = icmp eq i64 %ek, 0\n") emith(" br i1 %empty, label %miss, label %cmp\n") emith("cmp:\n") emith(" %hit = icmp eq i64 %ek, %k\n") emith(" br i1 %hit, label %found, label %next\n") emith("next:\n") emith(" %i1 = add i64 %im, 1\n") emith(" br label %probe\n") emith("miss:\n") emith(" %has = icmp ne ptr @malloc_size, null\n") emith(" br i1 %has, label %msz, label %unlock\n") emith("msz:\n") emith(" %ms = call i64 @malloc_size(ptr %p)\n") emith(" %pr = load i64, ptr @lp_pre\n") emith(" %pr1 = add i64 %pr, %ms\n") emith(" store i64 %pr1, ptr @lp_pre\n") emith(" br label %unlock\n") emith("found:\n") emith(" %ev = getelementptr inbounds i64, ptr %e, i64 1\n") emith(" %v = load i64, ptr %ev\n") emith(" %n = and i64 %v, 549755813887\n") emith(" %s = lshr i64 %v, 40\n") emith(" %neg = sub i64 0, %n\n") emith(" call void @lp_fsite_add(i64 %s, i64 %neg)\n") emith(" %wd = and i64 %v, 549755813888\n") emith(" %wasdecl = icmp ne i64 %wd, 0\n") emith(" %dl = load i64, ptr @lp_dlive\n") emith(" %dsub = select i1 %wasdecl, i64 %n, i64 0\n") emith(" %dl1 = sub i64 %dl, %dsub\n") emith(" store i64 %dl1, ptr @lp_dlive\n") emith(" %fr = load i64, ptr @lp_freed\n") emith(" %fr1 = add i64 %fr, 1\n") emith(" store i64 %fr1, ptr @lp_freed\n") emith(" %tn = load i64, ptr @lp_tabn\n") emith(" %tn1 = sub i64 %tn, 1\n") emith(" store i64 %tn1, ptr @lp_tabn\n") emith(" br label %sh\n") emith("sh:\n") emith(" %hole = phi i64 [ %im, %found ], [ %hole, %sh_skip ], [ %j, %sh_move ]\n") emith(" %jp = phi i64 [ %im, %found ], [ %j, %sh_skip ], [ %j, %sh_move ]\n") emith(" %j0 = add i64 %jp, 1\n") emith(" %j = and i64 %j0, %mask\n") emith(" %ej = getelementptr inbounds [2 x i64], ptr %tab, i64 %j\n") emith(" %kj = load i64, ptr %ej\n") emith(" %endq = icmp eq i64 %kj, 0\n") emith(" br i1 %endq, label %sh_end, label %sh_test\n") emith("sh_test:\n") emith(" %hj = call i64 @lp_fhash(i64 %kj)\n") emith(" %home = and i64 %hj, %mask\n") emith(" %jgt = icmp ugt i64 %j, %hole\n") emith(" %a1 = icmp ugt i64 %home, %hole\n") emith(" %a2 = icmp ule i64 %home, %j\n") emith(" %in1 = and i1 %a1, %a2\n") emith(" %in2 = or i1 %a1, %a2\n") emith(" %in = select i1 %jgt, i1 %in1, i1 %in2\n") emith(" br i1 %in, label %sh_skip, label %sh_move\n") emith("sh_skip:\n") emith(" br label %sh\n") emith("sh_move:\n") emith(" %eh = getelementptr inbounds [2 x i64], ptr %tab, i64 %hole\n") emith(" store i64 %kj, ptr %eh\n") emith(" %ejv = getelementptr inbounds i64, ptr %ej, i64 1\n") emith(" %vj = load i64, ptr %ejv\n") emith(" %ehv = getelementptr inbounds i64, ptr %eh, i64 1\n") emith(" store i64 %vj, ptr %ehv\n") emith(" br label %sh\n") emith("sh_end:\n") emith(" %ehe = getelementptr inbounds [2 x i64], ptr %tab, i64 %hole\n") emith(" store i64 0, ptr %ehe\n") emith(" br label %unlock\n") emith("unlock:\n") emith(" call void @lp_funlock()\n") emith(" br label %out\n") emith("out:\n") emith(" ret void\n") emith("}\n") } function emit_fence_control() -> void { emith("define internal i64 @lp_fenv(ptr %name, i64 %dflt) {\n") emith("entry:\n") emith(" %e = call ptr @getenv(ptr %name)\n") emith(" %has = icmp ne ptr %e, null\n") emith(" br i1 %has, label %read, label %none\n") emith("read:\n") emith(" %v = call i32 @atoi(ptr %e)\n") emith(" %v64 = sext i32 %v to i64\n") emith(" ret i64 %v64\n") emith("none:\n") emith(" ret i64 %dflt\n") emith("}\n") emith("define internal void @lp_finit() {\n") emith("entry:\n") emith(" %m0 = load i8, ptr @lp_fm\n") emith(" %done = icmp ne i8 %m0, 0\n") emith(" br i1 %done, label %out, label %go\n") emith("go:\n") emith(" %e = call ptr @getenv(ptr @.lpf_env)\n") emith(" %has = icmp ne ptr %e, null\n") emith(" br i1 %has, label %parse, label %dflt\n") emith("parse:\n") emith(" %c1 = call i32 @strcmp(ptr %e, ptr @.lpf_off)\n") emith(" %is1 = icmp eq i32 %c1, 0\n") emith(" %c2 = call i32 @strcmp(ptr %e, ptr @.lpf_count)\n") emith(" %is2 = icmp eq i32 %c2, 0\n") emith(" %c3 = call i32 @strcmp(ptr %e, ptr @.lpf_warn)\n") emith(" %is3 = icmp eq i32 %c3, 0\n") emith(" %ma = select i1 %is3, i8 3, i8 4\n") emith(" %mb = select i1 %is2, i8 2, i8 %ma\n") emith(" %mc = select i1 %is1, i8 1, i8 %mb\n") emith(" br label %set\n") emith("dflt:\n") emith(" %d = load i8, ptr @lp_fdef\n") emith(" %dz = icmp eq i8 %d, 0\n") emith(" br i1 %dz, label %dev, label %set\n") emith("dev:\n") emith(" %dv = call ptr @getenv(ptr @.lpf_dev)\n") emith(" %hd = icmp ne ptr %dv, null\n") emith(" %md = select i1 %hd, i8 4, i8 1\n") emith(" br label %set\n") emith("set:\n") emith(" %mode = phi i8 [ %mc, %parse ], [ %d, %dflt ], [ %md, %dev ]\n") emith(" store i8 %mode, ptr @lp_fm\n") emith(" %wd = load i64, ptr @lp_warm\n") emith(" %w = call i64 @lp_fenv(ptr @.lpf_warm, i64 %wd)\n") emith(" store i64 %w, ptr @lp_warm\n") emith(" %wx5 = mul i64 %w, 5\n") emith(" %wm = call i64 @lp_fenv(ptr @.lpf_warmmax, i64 %wx5)\n") emith(" store i64 %wm, ptr @lp_warm_max\n") emith(" %au = call i64 @lp_fenv(ptr @.lpf_auto, i64 1)\n") emith(" %au8 = trunc i64 %au to i8\n") emith(" store i8 %au8, ptr @lp_fauto\n") emith(" %pl = call i64 @lp_fenv(ptr @.lpf_play, i64 -1)\n") emith(" store i64 %pl, ptr @lp_autoplay\n") emith(" %want = call i64 @lp_fenv(ptr @.lpf_tab, i64 4194304)\n") emith(" br label %cap\n") emith("cap:\n") emith(" %c = phi i64 [ 1024, %set ], [ %c2x, %grow ]\n") emith(" %big = icmp sge i64 %c, %want\n") emith(" br i1 %big, label %capped, label %grow\n") emith("grow:\n") emith(" %c2x = shl i64 %c, 1\n") emith(" br label %cap\n") emith("capped:\n") emith(" %mask = sub i64 %c, 1\n") emith(" store i64 %mask, ptr @lp_tabmask\n") emith(" %q = lshr i64 %c, 2\n") emith(" %max = mul i64 %q, 3\n") emith(" store i64 %max, ptr @lp_tabmax\n") emith(" br label %out\n") emith("out:\n") emith(" ret void\n") emith("}\n") emith("define internal void @lp_fsnap() {\n") emith("entry:\n") emith(" %lv = load i64, ptr @lp_live\n") emith(" store i64 %lv, ptr @lp_mlive\n") emith(" %dlm = load i64, ptr @lp_dlive\n") emith(" store i64 %dlm, ptr @lp_mdlive\n") emith(" %pr = load i64, ptr @lp_pre\n") emith(" store i64 %pr, ptr @lp_mpre\n") emith(" %md = load i64, ptr @lp_made\n") emith(" store i64 %md, ptr @lp_mmade\n") emith(" %fr = load i64, ptr @lp_freed\n") emith(" store i64 %fr, ptr @lp_mfreed\n") emith(" store i32 0, ptr @lp_ntouch\n") emith(" ret void\n") emith("}\n") emith("define internal void @lp_fsnap_all() {\n") emith("entry:\n") emith(" %n = load i32, ptr @lp_site_n\n") emith(" %n64 = zext i32 %n to i64\n") emith(" %b = shl i64 %n64, 3\n") emith(" call ptr @memcpy(ptr @lp_site_mark, ptr @lp_site_live, i64 %b)\n") emith(" call void @lp_fsnap()\n") emith(" ret void\n") emith("}\n") emith("define void @lp_mem_play() {\n") emith("entry:\n") emith(" call void @lp_finit()\n") emith(" %m = load i8, ptr @lp_fm\n") emith(" %off = icmp ule i8 %m, 1\n") emith(" br i1 %off, label %out, label %chk\n") emith("chk:\n") emith(" %f = load i64, ptr @lp_frame\n") emith(" %t = load i8, ptr @lp_ft\n") emith(" %on = icmp ne i8 %t, 0\n") emith(" br i1 %on, label %rewarm, label %start\n") emith("rewarm:\n") emith(" call void @lp_flock()\n") emith(" store i8 0, ptr @lp_fj\n") emith(" store i64 0, ptr @lp_flat\n") emith(" store i64 %f, ptr @lp_playf\n") emith(" call void @lp_funlock()\n") emith(" br label %out\n") emith("start:\n") emith(" %tab = load ptr, ptr @lp_tab\n") emith(" %none = icmp eq ptr %tab, null\n") emith(" br i1 %none, label %make, label %arm\n") emith("make:\n") emith(" %mask = load i64, ptr @lp_tabmask\n") emith(" %c = add i64 %mask, 1\n") emith(" %p = call ptr @calloc(i64 %c, i64 16)\n") emith(" store ptr %p, ptr @lp_tab\n") emith(" br label %arm\n") emith("arm:\n") emith(" store i64 %f, ptr @lp_playf\n") emith(" store i64 0, ptr @lp_flat\n") emith(" %cp0 = call ptr @getenv(ptr @.lpf_census)\n") emith(" %cpd = load ptr, ptr @lp_census_def\n") emith(" %hasenv = icmp ne ptr %cp0, null\n") emith(" %cp = select i1 %hasenv, ptr %cp0, ptr %cpd\n") emith(" store ptr %cp, ptr @lp_census\n") emith(" %hascp = icmp ne ptr %cp, null\n") emith(" br i1 %hascp, label %reg, label %go\n") emith("reg:\n") emith(" call i32 @atexit(ptr @lp_fcensus)\n") emith(" br label %go\n") emith("go:\n") emith(" call void @lp_fsnap_all()\n") emith(" store i8 1, ptr @lp_ft\n") emith(" br label %out\n") emith("out:\n") emith(" ret void\n") emith("}\n") emith("define void @lp_mem_settled() {\n") emith("entry:\n") emith(" %t = load i8, ptr @lp_ft\n") emith(" %on = icmp ne i8 %t, 0\n") emith(" br i1 %on, label %chk, label %out\n") emith("chk:\n") emith(" %j = load i8, ptr @lp_fj\n") emith(" %already = icmp ne i8 %j, 0\n") emith(" br i1 %already, label %out, label %go\n") emith("go:\n") emith(" call void @lp_flock()\n") emith(" call void @lp_fsnap_all()\n") emith(" call void @lp_fsettle_locked()\n") emith(" call void @lp_funlock()\n") emith(" br label %out\n") emith("out:\n") emith(" ret void\n") emith("}\n") emith("define i64 @lp_mem_kept() {\n") emith("entry:\n") emith(" %j = load i8, ptr @lp_fj\n") emith(" %on = icmp ne i8 %j, 0\n") emith(" br i1 %on, label %read, label %none\n") emith("none:\n") emith(" ret i64 0\n") emith("read:\n") emith(" call void @lp_flock()\n") emith(" %lv = load i64, ptr @lp_live\n") emith(" %sl = load i64, ptr @lp_slive\n") emith(" %pr = load i64, ptr @lp_pre\n") emith(" %sp = load i64, ptr @lp_spre\n") emith(" %a0 = sub i64 %lv, %sl\n") emith(" %dlk = load i64, ptr @lp_dlive\n") emith(" %sdl = load i64, ptr @lp_sdlive\n") emith(" %ddk = sub i64 %dlk, %sdl\n") emith(" %a = sub i64 %a0, %ddk\n") emith(" %b = sub i64 %pr, %sp\n") emith(" %k = sub i64 %a, %b\n") emith(" call void @lp_funlock()\n") emith(" ret i64 %k\n") emith("}\n") emith("define i64 @lp_mem_bad_frames() {\n") emith("entry:\n") emith(" %b = load i64, ptr @lp_fbad\n") emith(" ret i64 %b\n") emith("}\n") } function emit_fence_report() -> void { emith("define internal i64 @lp_fdelta(i32 %s, ptr %base) {\n") emith("entry:\n") emith(" %sp = getelementptr inbounds i64, ptr @lp_site_live, i32 %s\n") emith(" %v = load i64, ptr %sp\n") emith(" %mp = getelementptr inbounds i64, ptr %base, i32 %s\n") emith(" %m = load i64, ptr %mp\n") emith(" %d = sub i64 %v, %m\n") emith(" ret i64 %d\n") emith("}\n") emith("define internal i32 @lp_fsite_at(i32 %i, i1 %all) {\n") emith("entry:\n") emith(" br i1 %all, label %every, label %touched\n") emith("every:\n") emith(" ret i32 %i\n") emith("touched:\n") emith(" %tp = getelementptr inbounds [512 x i32], ptr @lp_touch, i32 0, i32 %i\n") emith(" %s = load i32, ptr %tp\n") emith(" ret i32 %s\n") emith("}\n") emith("define internal { i64, i32 } @lp_fpick(ptr %base, i1 %all, i32 %cnt, i64 %pb, i32 %ps) {\n") emith("entry:\n") emith(" br label %loop\n") emith("loop:\n") emith(" %i = phi i32 [ 0, %entry ], [ %i1, %body ]\n") emith(" %bb0 = phi i64 [ 0, %entry ], [ %bb1, %body ]\n") emith(" %bs0 = phi i32 [ -1, %entry ], [ %bs1, %body ]\n") emith(" %go = icmp ult i32 %i, %cnt\n") emith(" br i1 %go, label %body, label %done\n") emith("body:\n") emith(" %s = call i32 @lp_fsite_at(i32 %i, i1 %all)\n") emith(" %d = call i64 @lp_fdelta(i32 %s, ptr %base)\n") emith(" %pos = icmp sgt i64 %d, 0\n") emith(" %lt = icmp slt i64 %d, %pb\n") emith(" %eqb = icmp eq i64 %d, %pb\n") emith(" %gts = icmp sgt i32 %s, %ps\n") emith(" %tie = and i1 %eqb, %gts\n") emith(" %below = or i1 %lt, %tie\n") emith(" %gtb = icmp sgt i64 %d, %bb0\n") emith(" %eqbb = icmp eq i64 %d, %bb0\n") emith(" %lts = icmp slt i32 %s, %bs0\n") emith(" %tie2 = and i1 %eqbb, %lts\n") emith(" %better = or i1 %gtb, %tie2\n") emith(" %c1 = and i1 %pos, %below\n") emith(" %take = and i1 %c1, %better\n") emith(" %bb1 = select i1 %take, i64 %d, i64 %bb0\n") emith(" %bs1 = select i1 %take, i32 %s, i32 %bs0\n") emith(" %i1 = add i32 %i, 1\n") emith(" br label %loop\n") emith("done:\n") emith(" %r0 = insertvalue { i64, i32 } undef, i64 %bb0, 0\n") emith(" %r1 = insertvalue { i64, i32 } %r0, i32 %bs0, 1\n") emith(" ret { i64, i32 } %r1\n") emith("}\n") emith("define internal void @lp_fsite_row(ptr %fp, i32 %fd, i64 %bytes, i32 %s) {\n") emith("entry:\n") emith(" %fnp = getelementptr inbounds ptr, ptr @lp_site_fn, i32 %s\n") emith(" %fn = load ptr, ptr %fnp\n") emith(" %flp = getelementptr inbounds ptr, ptr @lp_site_file, i32 %s\n") emith(" %fl = load ptr, ptr %flp\n") emith(" %lnp = getelementptr inbounds i32, ptr @lp_site_line, i32 %s\n") emith(" %ln = load i32, ptr %lnp\n") emith(" %kdp = getelementptr inbounds ptr, ptr @lp_site_kind, i32 %s\n") emith(" %kd = load ptr, ptr %kdp\n") emith(" %tofile = icmp ne ptr %fp, null\n") emith(" br i1 %tofile, label %file, label %err\n") emith("file:\n") emith(" call i32 (ptr, ptr, ...) @fprintf(ptr %fp, ptr @.lpf_crow, i64 %bytes, ptr %fn, ptr %fl, i32 %ln, ptr %kd)\n") emith(" br label %from\n") emith("err:\n") emith(" call i32 (i32, ptr, ...) @dprintf(i32 %fd, ptr @.lpf_row, i64 %bytes, ptr %fn, ptr %fl, i32 %ln, ptr %kd)\n") emith(" br label %from\n") emith("from:\n") emith(" call void @lp_fsite_from(ptr %fp, i32 %s, ptr %fn)\n") emith(" ret void\n") emith("}\n") emith("; the largest `rows` sites by what they hold over `base`, largest first\n") emith("define internal void @lp_franked(ptr %fp, ptr %base, i1 %all, i32 %cnt, i32 %rows) {\n") emith("entry:\n") emith(" br label %pass\n") emith("pass:\n") emith(" %row = phi i32 [ 0, %entry ], [ %row1, %show ]\n") emith(" %pb = phi i64 [ 9223372036854775807, %entry ], [ %bb, %show ]\n") emith(" %ps = phi i32 [ -1, %entry ], [ %bs, %show ]\n") emith(" %more = icmp ult i32 %row, %rows\n") emith(" br i1 %more, label %scan, label %tail\n") emith("scan:\n") emith(" %r = call { i64, i32 } @lp_fpick(ptr %base, i1 %all, i32 %cnt, i64 %pb, i32 %ps)\n") emith(" %bb = extractvalue { i64, i32 } %r, 0\n") emith(" %bs = extractvalue { i64, i32 } %r, 1\n") emith(" %found = icmp sge i32 %bs, 0\n") emith(" br i1 %found, label %show, label %tail\n") emith("show:\n") emith(" call void @lp_fsite_row(ptr %fp, i32 2, i64 %bb, i32 %bs)\n") emith(" %row1 = add i32 %row, 1\n") emith(" br label %pass\n") emith("tail:\n") emith(" ret void\n") emith("}\n") emith("define internal void @lp_freport(i64 %f, i64 %kept) {\n") emith("entry:\n") emith(" %md = load i64, ptr @lp_made\n") emith(" %mm = load i64, ptr @lp_mmade\n") emith(" %made = sub i64 %md, %mm\n") emith(" %fr = load i64, ptr @lp_freed\n") emith(" %mf = load i64, ptr @lp_mfreed\n") emith(" %freed = sub i64 %fr, %mf\n") emith(" call i32 (i32, ptr, ...) @dprintf(i32 2, ptr @.lpf_hdr, i64 %f, i64 %kept, i64 %made, i64 %freed)\n") emith(" %nt = load i32, ptr @lp_ntouch\n") emith(" %all = icmp ugt i32 %nt, 512\n") emith(" %sn = load i32, ptr @lp_site_n\n") emith(" %cnt = select i1 %all, i32 %sn, i32 %nt\n") emith(" call void @lp_franked(ptr null, ptr @lp_site_mark, i1 %all, i32 %cnt, i32 12)\n") emith(" ret void\n") emith("}\n") emith("; R3D_ALLOC_CENSUS=, written at exit: the run's totals since play settled, and every site\n") emith("; that holds more than it did then, largest first\n") emith("define void @lp_fcensus() {\n") emith("entry:\n") emith(" %path = load ptr, ptr @lp_census\n") emith(" %none = icmp eq ptr %path, null\n") emith(" br i1 %none, label %out, label %open\n") emith("open:\n") emith(" %zn = call i64 @lp_fzone()\n") emith(" %jn = call i64 @lp_fnat(ptr @.lpf_jb)\n") emith(" %jpk = call i64 @lp_fnat(ptr @.lpf_jp)\n") emith(" %vn = call i64 @lp_fnat(ptr @.lpf_vb)\n") emith(" %vpk = call i64 @lp_fnat(ptr @.lpf_vp)\n") emith(" %fp = call ptr @fopen(ptr %path, ptr @.lpf_w)\n") emith(" %bad = icmp eq ptr %fp, null\n") emith(" br i1 %bad, label %out, label %write\n") emith("write:\n") emith(" store i8 0, ptr @lp_ft\n") emith(" %j = load i64, ptr @lp_fjudged\n") emith(" %b = load i64, ptr @lp_fbad\n") emith(" %k = call i64 @lp_mem_kept()\n") emith(" %md = load i64, ptr @lp_made\n") emith(" %fr = load i64, ptr @lp_freed\n") emith(" %ov = load i64, ptr @lp_over\n") emith(" call i32 (ptr, ptr, ...) @fprintf(ptr %fp, ptr @.lpf_chdr, i64 %j, i64 %b, i64 %k, i64 %md, i64 %fr, i64 %ov)\n") emith(" %jq = icmp ne i64 %j, 0\n") emith(" %zs = load i64, ptr @lp_zset\n") emith(" %zd = sub i64 %zn, %zs\n") emith(" %js = load i64, ptr @lp_jset\n") emith(" %jd = sub i64 %jn, %js\n") emith(" %vs = load i64, ptr @lp_vset\n") emith(" %vd = sub i64 %vn, %vs\n") emith(" %dnw = load i64, ptr @lp_dlive\n") emith(" %dst = load i64, ptr @lp_sdlive\n") emith(" %dgr = sub i64 %dnw, %dst\n") emith(" %nat0 = sub i64 %zd, %k\n") emith(" %nat = sub i64 %nat0, %dgr\n") emith(" %nat2 = sub i64 %nat, %jd\n") emith(" %nat3 = sub i64 %nat2, %vd\n") emith(" %nat1 = select i1 %jq, i64 %nat3, i64 0\n") emith(" call i32 (ptr, ptr, ...) @fprintf(ptr %fp, ptr @.lpf_cnat, i64 %nat1)\n") emith(" %dnow = load i64, ptr @lp_dlive\n") emith(" %dset = load i64, ptr @lp_sdlive\n") emith(" %ddc = sub i64 %dnow, %dset\n") emith(" %ddc1 = select i1 %jq, i64 %ddc, i64 0\n") emith(" call i32 (ptr, ptr, ...) @fprintf(ptr %fp, ptr @.lpf_cdecl, i64 %ddc1)\n") emith(" %jd1 = select i1 %jq, i64 %jd, i64 0\n") emith(" call i32 (ptr, ptr, ...) @fprintf(ptr %fp, ptr @.lpf_cjolt, i64 %jd1, i64 %jpk)\n") emith(" %vd1 = select i1 %jq, i64 %vd, i64 0\n") emith(" call i32 (ptr, ptr, ...) @fprintf(ptr %fp, ptr @.lpf_cvk, i64 %vd1, i64 %vpk)\n") emith(" %sn = load i32, ptr @lp_site_n\n") emith(" call void @lp_franked(ptr %fp, ptr @lp_site_base, i1 1, i32 %sn, i32 40)\n") emith(" call i32 @fclose(ptr %fp)\n") emith(" br label %out\n") emith("out:\n") emith(" ret void\n") emith("}\n") } function emit_fence_frame() -> void { emith("define internal void @lp_fmark_touched() {\n") emith("entry:\n") emith(" %nt = load i32, ptr @lp_ntouch\n") emith(" %all = icmp ugt i32 %nt, 512\n") emith(" br i1 %all, label %every, label %some\n") emith("every:\n") emith(" call void @lp_fsnap_all()\n") emith(" ret void\n") emith("some:\n") emith(" br label %loop\n") emith("loop:\n") emith(" %i = phi i32 [ 0, %some ], [ %i1, %body ]\n") emith(" %go = icmp ult i32 %i, %nt\n") emith(" br i1 %go, label %body, label %done\n") emith("body:\n") emith(" %tp = getelementptr inbounds [512 x i32], ptr @lp_touch, i32 0, i32 %i\n") emith(" %s = load i32, ptr %tp\n") emith(" %sp = getelementptr inbounds i64, ptr @lp_site_live, i32 %s\n") emith(" %v = load i64, ptr %sp\n") emith(" %mp = getelementptr inbounds i64, ptr @lp_site_mark, i32 %s\n") emith(" store i64 %v, ptr %mp\n") emith(" %i1 = add i32 %i, 1\n") emith(" br label %loop\n") emith("done:\n") emith(" call void @lp_fsnap()\n") emith(" ret void\n") emith("}\n") emith("; malloc's live bytes over every zone (0 where there is no malloc_zone_statistics)\n") emith("define internal i64 @lp_fzone() {\n") emith("entry:\n") emith(" %has = icmp ne ptr @malloc_zone_statistics, null\n") emith(" br i1 %has, label %read, label %none\n") emith("none:\n") emith(" ret i64 0\n") emith("read:\n") emith(" %st = alloca [4 x i64], align 8\n") emith(" call void @malloc_zone_statistics(ptr null, ptr %st)\n") emith(" %p = getelementptr [4 x i64], ptr %st, i32 0, i32 1\n") emith(" %n = load i64, ptr %p\n") emith(" ret i64 %n\n") emith("}\n") emith("; a counted native library's number, found by name (ludic.physics' jph_heap_*, the Vulkan runtime's\n") emith("; lvk_ac_*): 0 when the program does not carry it, and nothing is declared that the package declares\n") emith("define internal i64 @lp_fnat(ptr %name) {\n") emith("entry:\n") emith(" %rtld_default = inttoptr i64 -2 to ptr\n") emith(" %f = call ptr @dlsym(ptr %rtld_default, ptr %name)\n") emith(" %none = icmp eq ptr %f, null\n") emith(" br i1 %none, label %zero, label %call\n") emith("zero:\n") emith(" ret i64 0\n") emith("call:\n") emith(" %v = call i64 %f()\n") emith(" ret i64 %v\n") emith("}\n") emith("define internal void @lp_fsettle_locked() {\n") emith("entry:\n") emith(" %n = load i32, ptr @lp_site_n\n") emith(" %n64 = zext i32 %n to i64\n") emith(" %nb = shl i64 %n64, 3\n") emith(" call ptr @memcpy(ptr @lp_site_base, ptr @lp_site_live, i64 %nb)\n") emith(" %lv = load i64, ptr @lp_live\n") emith(" store i64 %lv, ptr @lp_slive\n") emith(" %dls = load i64, ptr @lp_dlive\n") emith(" store i64 %dls, ptr @lp_sdlive\n") emith(" %pr = load i64, ptr @lp_pre\n") emith(" store i64 %pr, ptr @lp_spre\n") emith(" %jb = call i64 @lp_fnat(ptr @.lpf_jb)\n") emith(" store i64 %jb, ptr @lp_jset\n") emith(" %vb = call i64 @lp_fnat(ptr @.lpf_vb)\n") emith(" store i64 %vb, ptr @lp_vset\n") emith(" %z = call i64 @lp_fzone()\n") emith(" store i64 %z, ptr @lp_zset\n") emith(" store i8 1, ptr @lp_fj\n") emith(" ret void\n") emith("}\n") emith("; the frame's mark. Tracking starts at the first one (R3D_ALLOC_AUTO=0: at Mem.play() or\n") emith("; R3D_ALLOC_PLAY=); judging starts once R3D_ALLOC_WARM frames in a row kept nothing, or\n") emith("; R3D_ALLOC_WARM_MAX frames after tracking (re)started, whichever is first\n") emith("define void @lp_mem_frame() {\n") emith("entry:\n") emith(" call void @lp_finit()\n") emith(" %f = load i64, ptr @lp_frame\n") emith(" %f1 = add i64 %f, 1\n") emith(" %m = load i8, ptr @lp_fm\n") emith(" %off = icmp ule i8 %m, 1\n") emith(" br i1 %off, label %tick, label %live\n") emith("live:\n") emith(" %t = load i8, ptr @lp_ft\n") emith(" %on = icmp ne i8 %t, 0\n") emith(" br i1 %on, label %tracking, label %maybe_play\n") emith("maybe_play:\n") emith(" %au = load i8, ptr @lp_fauto\n") emith(" %auq = icmp ne i8 %au, 0\n") emith(" %ap = load i64, ptr @lp_autoplay\n") emith(" %apset = icmp sge i64 %ap, 0\n") emith(" %apdue = icmp sge i64 %f1, %ap\n") emith(" %apgo = and i1 %apset, %apdue\n") emith(" %go = or i1 %auq, %apgo\n") emith(" br i1 %go, label %play, label %tick\n") emith("play:\n") emith(" call void @lp_mem_play()\n") emith(" br label %tick\n") emith("tracking:\n") emith(" call void @lp_flock()\n") emith(" %ov = load i64, ptr @lp_over\n") emith(" %ovq = icmp sgt i64 %ov, 0\n") emith(" %rep = load i8, ptr @lp_overrep\n") emith(" %repq = icmp eq i8 %rep, 0\n") emith(" %fullnew = and i1 %ovq, %repq\n") emith(" br i1 %fullnew, label %full, label %weigh\n") emith("full:\n") emith(" %tn = load i64, ptr @lp_tabn\n") emith(" call i32 (i32, ptr, ...) @dprintf(i32 2, ptr @.lpf_full, i64 %tn)\n") emith(" store i8 1, ptr @lp_overrep\n") emith(" store i8 0, ptr @lp_fj\n") emith(" br label %unlock\n") emith("weigh:\n") emith(" %lv = load i64, ptr @lp_live\n") emith(" %ml = load i64, ptr @lp_mlive\n") emith(" %pr = load i64, ptr @lp_pre\n") emith(" %mp = load i64, ptr @lp_mpre\n") emith(" %a0 = sub i64 %lv, %ml\n") emith(" %dln = load i64, ptr @lp_dlive\n") emith(" %dlmk = load i64, ptr @lp_mdlive\n") emith(" %dd = sub i64 %dln, %dlmk\n") emith(" %a = sub i64 %a0, %dd\n") emith(" %b = sub i64 %pr, %mp\n") emith(" %kept = sub i64 %a, %b\n") emith(" %bad = icmp sgt i64 %kept, 0\n") emith(" %j = load i8, ptr @lp_fj\n") emith(" %judging = icmp ne i8 %j, 0\n") emith(" br i1 %judging, label %judge, label %warming\n") emith("warming:\n") emith(" %fl = load i64, ptr @lp_flat\n") emith(" %fl1 = add i64 %fl, 1\n") emith(" %fl2 = select i1 %bad, i64 0, i64 %fl1\n") emith(" store i64 %fl2, ptr @lp_flat\n") emith(" %w = load i64, ptr @lp_warm\n") emith(" %wset = icmp sge i64 %w, 0\n") emith(" %wdone = icmp sge i64 %fl2, %w\n") emith(" %byflat = and i1 %wset, %wdone\n") emith(" %pf = load i64, ptr @lp_playf\n") emith(" %since = sub i64 %f1, %pf\n") emith(" %wm = load i64, ptr @lp_warm_max\n") emith(" %wmset = icmp sge i64 %wm, 0\n") emith(" %wmdone = icmp sge i64 %since, %wm\n") emith(" %bycap = and i1 %wmset, %wmdone\n") emith(" %settle = or i1 %byflat, %bycap\n") emith(" br i1 %settle, label %settle_now, label %mark\n") emith("settle_now:\n") emith(" call void @lp_fsettle_locked()\n") emith(" br label %mark\n") emith("judge:\n") emith(" %jd = load i64, ptr @lp_fjudged\n") emith(" %jd1 = add i64 %jd, 1\n") emith(" store i64 %jd1, ptr @lp_fjudged\n") emith(" br i1 %bad, label %kept_some, label %mark\n") emith("kept_some:\n") emith(" %fk = load i64, ptr @lp_fkept\n") emith(" %fk1 = add i64 %fk, %kept\n") emith(" store i64 %fk1, ptr @lp_fkept\n") emith(" %fb = load i64, ptr @lp_fbad\n") emith(" %fb1 = add i64 %fb, 1\n") emith(" store i64 %fb1, ptr @lp_fbad\n") emith(" %say = icmp uge i8 %m, 3\n") emith(" br i1 %say, label %say_it, label %mark\n") emith("say_it:\n") emith(" call void @lp_freport(i64 %f, i64 %kept)\n") emith(" %fail = icmp eq i8 %m, 4\n") emith(" br i1 %fail, label %die, label %mark\n") emith("die:\n") emith(" call i32 (i32, ptr, ...) @dprintf(i32 2, ptr @.lpf_failing)\n") emith(" store i8 0, ptr @lp_ft\n") emith(" call void @lp_funlock()\n") emith(" call void @exit(i32 86)\n") emith(" unreachable\n") emith("mark:\n") emith(" call void @lp_fmark_touched()\n") emith(" br label %unlock\n") emith("unlock:\n") emith(" call void @lp_funlock()\n") emith(" br label %tick\n") emith("tick:\n") emith(" store i64 %f1, ptr @lp_frame\n") emith(" ret void\n") emith("}\n") } function emit_fence_win() -> void { emith("@lp_site = global i32 0\n") emith("@lp_fdecl = global i32 0\n") emith("define ptr @lp_malloc(i64 %n) {\n") emith("entry:\n") emith(" %p = tail call ptr @malloc(i64 %n)\n") emith(" ret ptr %p\n") emith("}\n") emith("define ptr @lp_calloc(i64 %n, i64 %s) {\n") emith("entry:\n") emith(" %p = tail call ptr @calloc(i64 %n, i64 %s)\n") emith(" ret ptr %p\n") emith("}\n") emith("define ptr @lp_realloc(ptr %o, i64 %n) {\n") emith("entry:\n") emith(" %p = tail call ptr @realloc(ptr %o, i64 %n)\n") emith(" ret ptr %p\n") emith("}\n") emith("define void @lp_free(ptr %o) {\n") emith("entry:\n") emith(" tail call void @free(ptr %o)\n") emith(" ret void\n") emith("}\n") emith("define void @lp_mem_play() {\n") emith("entry:\n") emith(" ret void\n") emith("}\n") emith("define void @lp_mem_settled() {\n") emith("entry:\n") emith(" ret void\n") emith("}\n") emith("define void @lp_mem_frame() {\n") emith("entry:\n") emith(" ret void\n") emith("}\n") emith("define i64 @lp_mem_kept() {\n") emith("entry:\n") emith(" ret i64 0\n") emith("}\n") emith("define i64 @lp_mem_bad_frames() {\n") emith("entry:\n") emith(" ret i64 0\n") emith("}\n") }