fence: declared but unbounded, and a rewarm that keeps the warm-up's deadline
Two blind spots from the windowed walk, where the heap grew about 1 MB a minute and the census read `frames 0 bad 0 kept 0`: - @alloc_ok memory was never held to its reason. Every R3D_ALLOC_DWIN judged frames (600) each site's declared bytes are set against their high-water mark: a new high adds to a streak, a flat window takes one off, a fall ends it. R3D_ALLOC_DRISE (6) is "declared but unbounded", said once per site with its line; fail mode exits 86. The census adds `unbounded N` and a `dsite` row per declared site by its growth since judging began. A list pushed forever grows by doubling, rising too seldom to make a streak; a record or text made every time (a re-mount's defaults) is what it catches. - Mem.play() (every screen opened) restarted the warm-up, so memory kept every frame was never flat, the cap never came, and nothing was ever judged. A rewarm now keeps the first deadline, and past it has R3D_ALLOC_REWARM frames (120) of grace. Goldens: alloc_fence_unbounded (a record a frame under @alloc_ok: exit 86, named, census unbounded 1); alloc_fence_rewarm (kept every frame, Mem.play() every 360: judged and failed at frame 3000 - the toolchain before this runs all 6000 frames and exits 0). alloc_fence_leak, _declared, _auto, alloc_ok_private and the four arena goldens unchanged; the game's frame ratchets 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
de6d78bef5
commit
0f04b63516
7 changed files with 65568 additions and 64828 deletions
|
|
@ -251,6 +251,9 @@ function emit_fence_runtime() -> void {
|
|||
emith(`@lp_site_base = global [{sn} x i64] zeroinitializer\n`)
|
||||
emith(`@lp_site_scan = global [{sn} x i64] zeroinitializer\n`)
|
||||
emith(`@lp_site_dlive = global [{sn} x i64] zeroinitializer\n`)
|
||||
emith(`@lp_site_dbase = global [{sn} x i64] zeroinitializer\n`) # declared bytes when judging began
|
||||
emith(`@lp_site_dhw = global [{sn} x i64] zeroinitializer\n`) # ... their high-water mark, window to window
|
||||
emith(`@lp_site_drise = global [{sn} x i64] zeroinitializer\n`) # ... how long they have kept rising (-1: said)
|
||||
let owns = new []pointer
|
||||
var w = 0
|
||||
while w < n { push(owns, itoa(g_site_owner[w])); w += 1 }
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ function emit_fence_globals() -> void {
|
|||
emith("@lp_dlive = global i64 0\n")
|
||||
emith("@lp_mdlive = global i64 0\n")
|
||||
emith("@lp_sdlive = global i64 0\n")
|
||||
emith("@lp_dwin = global i64 600\n")
|
||||
emith("@lp_drise = global i64 6\n")
|
||||
emith("@lp_dunb = 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")
|
||||
|
|
@ -116,6 +119,12 @@ function emit_fence_globals() -> void {
|
|||
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")
|
||||
emith("@.lpf_dwin = private unnamed_addr constant [15 x i8] c\"R3D_ALLOC_DWIN\\00\"\n")
|
||||
emith("@.lpf_rewarm = private unnamed_addr constant [17 x i8] c\"R3D_ALLOC_REWARM\\00\"\n")
|
||||
emith("@.lpf_drise = private unnamed_addr constant [16 x i8] c\"R3D_ALLOC_DRISE\\00\"\n")
|
||||
emith("@.lpf_dunb = private unnamed_addr constant [159 x i8] c\"alloc-fence: frame %lld: declared but unbounded - @alloc_ok memory still rising after %lld windows of %lld frames (the reason says bounded; this site is not)\\0A\\00\"\n")
|
||||
emith("@.lpf_cdunb = private unnamed_addr constant [107 x i8] c\"unbounded %lld (declared sites whose bytes kept rising: R3D_ALLOC_DRISE windows of R3D_ALLOC_DWIN frames)\\0A\\00\"\n")
|
||||
emith("@.lpf_cdrow = private unnamed_addr constant [24 x i8] c\"dsite %lld %s %s:%d %s\\0A\\00\"\n")
|
||||
}
|
||||
function emit_fence_entry() -> void {
|
||||
emith("; the four entry points. Off: one load of the fence and the scratch request, one branch, then libc.\n")
|
||||
|
|
@ -807,6 +816,10 @@ function emit_fence_control() -> void {
|
|||
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(" %dwv = call i64 @lp_fenv(ptr @.lpf_dwin, i64 600)\n")
|
||||
emith(" store i64 %dwv, ptr @lp_dwin\n")
|
||||
emith(" %drv = call i64 @lp_fenv(ptr @.lpf_drise, i64 6)\n")
|
||||
emith(" store i64 %drv, ptr @lp_drise\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")
|
||||
|
|
@ -867,10 +880,19 @@ function emit_fence_control() -> void {
|
|||
emith(" %on = icmp ne i8 %t, 0\n")
|
||||
emith(" br i1 %on, label %rewarm, label %start\n")
|
||||
emith("rewarm:\n")
|
||||
emith(" ; a screen opened: warm again, but the cap keeps its first deadline - growth that never stops must\n")
|
||||
emith(" ; not keep the fence from judging - and past it a rewarm has R3D_ALLOC_REWARM frames of grace\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(" %rw = call i64 @lp_fenv(ptr @.lpf_rewarm, i64 120)\n")
|
||||
emith(" %wmx = load i64, ptr @lp_warm_max\n")
|
||||
emith(" %pf0 = load i64, ptr @lp_playf\n")
|
||||
emith(" %fr = add i64 %f, %rw\n")
|
||||
emith(" %pfg = sub i64 %fr, %wmx\n")
|
||||
emith(" %later = icmp sgt i64 %pfg, %pf0\n")
|
||||
emith(" %pf1 = select i1 %later, i64 %pfg, i64 %pf0\n")
|
||||
emith(" store i64 %pf1, ptr @lp_playf\n")
|
||||
emith(" call void @lp_funlock()\n")
|
||||
emith(" br label %out\n")
|
||||
emith("start:\n")
|
||||
|
|
@ -954,9 +976,9 @@ function emit_fence_control() -> void {
|
|||
emith("}\n")
|
||||
}
|
||||
function emit_fence_report() -> void {
|
||||
emith("define internal i64 @lp_fdelta(i32 %s, ptr %base) {\n")
|
||||
emith("define internal i64 @lp_fdelta(i32 %s, ptr %cur, ptr %base) {\n")
|
||||
emith("entry:\n")
|
||||
emith(" %sp = getelementptr inbounds i64, ptr @lp_site_live, i32 %s\n")
|
||||
emith(" %sp = getelementptr inbounds i64, ptr %cur, 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")
|
||||
|
|
@ -973,7 +995,7 @@ function emit_fence_report() -> void {
|
|||
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("define internal { i64, i32 } @lp_fpick(ptr %cur, ptr %base, i1 %all, i32 %cnt, i64 %pb, i32 %ps) {\n")
|
||||
emith("entry:\n")
|
||||
emith(" br label %loop\n")
|
||||
emith("loop:\n")
|
||||
|
|
@ -984,7 +1006,7 @@ function emit_fence_report() -> void {
|
|||
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(" %d = call i64 @lp_fdelta(i32 %s, ptr %cur, 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")
|
||||
|
|
@ -1007,7 +1029,7 @@ function emit_fence_report() -> void {
|
|||
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("define internal void @lp_fsite_row(ptr %fp, i32 %fd, i64 %bytes, i32 %s, ptr %cfmt) {\n")
|
||||
emith("entry:\n")
|
||||
emith(" %fnp = getelementptr inbounds ptr, ptr @lp_site_fn, i32 %s\n")
|
||||
emith(" %fn = load ptr, ptr %fnp\n")
|
||||
|
|
@ -1020,7 +1042,7 @@ function emit_fence_report() -> void {
|
|||
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(" call i32 (ptr, ptr, ...) @fprintf(ptr %fp, ptr %cfmt, 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")
|
||||
|
|
@ -1030,7 +1052,7 @@ function emit_fence_report() -> void {
|
|||
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("define internal void @lp_franked(ptr %fp, ptr %cur, ptr %base, ptr %cfmt, i1 %all, i32 %cnt, i32 %rows) {\n")
|
||||
emith("entry:\n")
|
||||
emith(" br label %pass\n")
|
||||
emith("pass:\n")
|
||||
|
|
@ -1040,13 +1062,13 @@ function emit_fence_report() -> void {
|
|||
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(" %r = call { i64, i32 } @lp_fpick(ptr %cur, 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(" call void @lp_fsite_row(ptr %fp, i32 2, i64 %bb, i32 %bs, ptr %cfmt)\n")
|
||||
emith(" %row1 = add i32 %row, 1\n")
|
||||
emith(" br label %pass\n")
|
||||
emith("tail:\n")
|
||||
|
|
@ -1065,7 +1087,7 @@ function emit_fence_report() -> void {
|
|||
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(" call void @lp_franked(ptr null, ptr @lp_site_live, ptr @lp_site_mark, ptr @.lpf_crow, i1 %all, i32 %cnt, i32 12)\n")
|
||||
emith(" ret void\n")
|
||||
emith("}\n")
|
||||
emith("; R3D_ALLOC_CENSUS=<file>, written at exit: the run's totals since play settled, and every site\n")
|
||||
|
|
@ -1124,7 +1146,10 @@ function emit_fence_report() -> void {
|
|||
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(" %dun = load i64, ptr @lp_dunb\n")
|
||||
emith(" call i32 (ptr, ptr, ...) @fprintf(ptr %fp, ptr @.lpf_cdunb, i64 %dun)\n")
|
||||
emith(" call void @lp_franked(ptr %fp, ptr @lp_site_live, ptr @lp_site_base, ptr @.lpf_crow, i1 1, i32 %sn, i32 40)\n")
|
||||
emith(" call void @lp_franked(ptr %fp, ptr @lp_site_dlive, ptr @lp_site_dbase, ptr @.lpf_cdrow, i1 1, i32 %sn, i32 40)\n")
|
||||
emith(" call void @lp_fowners(ptr %fp)\n")
|
||||
emith(" call i32 @fclose(ptr %fp)\n")
|
||||
emith(" br label %out\n")
|
||||
|
|
@ -1562,7 +1587,7 @@ function emit_fence_frame() -> void {
|
|||
emith(" %found = icmp sge i32 %bs0, 0\n")
|
||||
emith(" br i1 %found, label %show, label %tail\n")
|
||||
emith("show:\n")
|
||||
emith(" call void @lp_fsite_row(ptr null, i32 2, i64 %bb0, i32 %bs0)\n")
|
||||
emith(" call void @lp_fsite_row(ptr null, i32 2, i64 %bb0, i32 %bs0, ptr @.lpf_crow)\n")
|
||||
emith(" %row1 = add i32 %row, 1\n")
|
||||
emith(" br label %pass\n")
|
||||
emith("tail:\n")
|
||||
|
|
@ -1578,6 +1603,9 @@ function emit_fence_frame() -> void {
|
|||
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(" call ptr @memcpy(ptr @lp_site_dbase, ptr @lp_site_dlive, i64 %nb)\n")
|
||||
emith(" call ptr @memcpy(ptr @lp_site_dhw, ptr @lp_site_dlive, i64 %nb)\n")
|
||||
emith(" call ptr @memset(ptr @lp_site_drise, i32 0, i64 %nb)\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")
|
||||
|
|
@ -1589,6 +1617,67 @@ function emit_fence_frame() -> void {
|
|||
emith(" store i8 1, ptr @lp_fj\n")
|
||||
emith(" ret void\n")
|
||||
emith("}\n")
|
||||
emith(";; every R3D_ALLOC_DWIN judged frames: a site whose declared bytes set a new high adds to its streak,\n")
|
||||
emith("; a flat window takes one off, a fall ends it; R3D_ALLOC_DRISE of them is \"declared but unbounded\",\n")
|
||||
emith("; said once per site (its callers were not recorded: a declared site is not judged per frame)\n")
|
||||
emith("define internal i64 @lp_fdwindow(i64 %f, i8 %m) {\n")
|
||||
emith("entry:\n")
|
||||
emith(" %n = load i32, ptr @lp_site_n\n")
|
||||
emith(" %need = load i64, ptr @lp_drise\n")
|
||||
emith(" %dw = load i64, ptr @lp_dwin\n")
|
||||
emith(" %say = icmp uge i8 %m, 3\n")
|
||||
emith(" br label %loop\n")
|
||||
emith("loop:\n")
|
||||
emith(" %i = phi i32 [ 0, %entry ], [ %i1, %next ]\n")
|
||||
emith(" %hits = phi i64 [ 0, %entry ], [ %hits1, %next ]\n")
|
||||
emith(" %go = icmp ult i32 %i, %n\n")
|
||||
emith(" br i1 %go, label %body, label %done\n")
|
||||
emith("body:\n")
|
||||
emith(" %lp = getelementptr inbounds i64, ptr @lp_site_dlive, i32 %i\n")
|
||||
emith(" %dl = load i64, ptr %lp\n")
|
||||
emith(" %hp = getelementptr inbounds i64, ptr @lp_site_dhw, i32 %i\n")
|
||||
emith(" %hw = load i64, ptr %hp\n")
|
||||
emith(" %rp = getelementptr inbounds i64, ptr @lp_site_drise, i32 %i\n")
|
||||
emith(" %r = load i64, ptr %rp\n")
|
||||
emith(" %up = icmp sgt i64 %dl, %hw\n")
|
||||
emith(" %fell = icmp slt i64 %dl, %hw\n")
|
||||
emith(" %rpos = icmp sgt i64 %r, 0\n")
|
||||
emith(" %rdec = sub i64 %r, 1\n")
|
||||
emith(" %rflat = select i1 %rpos, i64 %rdec, i64 0\n")
|
||||
emith(" %rup = add i64 %r, 1\n")
|
||||
emith(" %r0 = select i1 %fell, i64 0, i64 %rflat\n")
|
||||
emith(" %rn = select i1 %up, i64 %rup, i64 %r0\n")
|
||||
emith(" %sent = icmp slt i64 %r, 0\n")
|
||||
emith(" %rs = select i1 %sent, i64 %r, i64 %rn\n")
|
||||
emith(" store i64 %rs, ptr %rp\n")
|
||||
emith(" %hw1 = select i1 %up, i64 %dl, i64 %hw\n")
|
||||
emith(" store i64 %hw1, ptr %hp\n")
|
||||
emith(" %hit0 = icmp sge i64 %rs, %need\n")
|
||||
emith(" %hit = and i1 %hit0, %up\n")
|
||||
emith(" br i1 %hit, label %report, label %next0\n")
|
||||
emith("report:\n")
|
||||
emith(" store i64 -1, ptr %rp\n")
|
||||
emith(" %du = load i64, ptr @lp_dunb\n")
|
||||
emith(" %du1 = add i64 %du, 1\n")
|
||||
emith(" store i64 %du1, ptr @lp_dunb\n")
|
||||
emith(" br i1 %say, label %tell, label %next0\n")
|
||||
emith("tell:\n")
|
||||
emith(" call i32 (i32, ptr, ...) @dprintf(i32 2, ptr @.lpf_dunb, i64 %f, i64 %need, i64 %dw)\n")
|
||||
emith(" %bp = getelementptr inbounds i64, ptr @lp_site_dbase, i32 %i\n")
|
||||
emith(" %bs = load i64, ptr %bp\n")
|
||||
emith(" %grew = sub i64 %dl, %bs\n")
|
||||
emith(" call void @lp_fsite_row(ptr null, i32 2, i64 %grew, i32 %i, ptr @.lpf_crow)\n")
|
||||
emith(" br label %next0\n")
|
||||
emith("next0:\n")
|
||||
emith(" %got = phi i64 [ 0, %body ], [ 1, %report ], [ 1, %tell ]\n")
|
||||
emith(" br label %next\n")
|
||||
emith("next:\n")
|
||||
emith(" %hits1 = add i64 %hits, %got\n")
|
||||
emith(" %i1 = add i32 %i, 1\n")
|
||||
emith(" br label %loop\n")
|
||||
emith("done:\n")
|
||||
emith(" ret i64 %hits\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=<frame>); 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")
|
||||
|
|
@ -1667,6 +1756,20 @@ function emit_fence_frame() -> void {
|
|||
emith(" %jd = load i64, ptr @lp_fjudged\n")
|
||||
emith(" %jd1 = add i64 %jd, 1\n")
|
||||
emith(" store i64 %jd1, ptr @lp_fjudged\n")
|
||||
emith(" %dw = load i64, ptr @lp_dwin\n")
|
||||
emith(" %dwon = icmp sgt i64 %dw, 0\n")
|
||||
emith(" %dws = select i1 %dwon, i64 %dw, i64 1\n")
|
||||
emith(" %dwr = urem i64 %jd1, %dws\n")
|
||||
emith(" %dwz = icmp eq i64 %dwr, 0\n")
|
||||
emith(" %dwdue = and i1 %dwon, %dwz\n")
|
||||
emith(" br i1 %dwdue, label %dwindow, label %verdict\n")
|
||||
emith("dwindow:\n")
|
||||
emith(" %nun = call i64 @lp_fdwindow(i64 %f, i8 %m)\n")
|
||||
emith(" %nunq = icmp sgt i64 %nun, 0\n")
|
||||
emith(" %dfail = icmp eq i8 %m, 4\n")
|
||||
emith(" %ddie = and i1 %nunq, %dfail\n")
|
||||
emith(" br i1 %ddie, label %die, label %verdict\n")
|
||||
emith("verdict:\n")
|
||||
emith(" br i1 %bad, label %kept_some, label %mark\n")
|
||||
emith("kept_some:\n")
|
||||
emith(" %fk = load i64, ptr @lp_fkept\n")
|
||||
|
|
|
|||
65181
selfhost/ludicc.seed.ll
65181
selfhost/ludicc.seed.ll
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue