From 1a45b588d58bcbd5fda122adb09247bcdc97ae0f Mon Sep 17 00:00:00 2001 From: Edward Amsden Date: Tue, 16 Jul 2024 09:26:38 -0500 Subject: [PATCH] wip: nouncode linearizer --- hoon/codegen/lib/line.hoon | 1475 +++++------------------------------- hoon/codegen/sur/gene.hoon | 58 +- 2 files changed, 209 insertions(+), 1324 deletions(-) diff --git a/hoon/codegen/lib/line.hoon b/hoon/codegen/lib/line.hoon index b073213..31cafd4 100644 --- a/hoon/codegen/lib/line.hoon +++ b/hoon/codegen/lib/line.hoon @@ -1,136 +1,86 @@ -/- gene +/- gen |. => $:gene -:: XX -:: - generate ipb tests at 0/10 sites (done) -:: - make copy pessimize %this/%both case (not %both/%this) (done) -:: - do not ipb at mean entry/exit (done) -:: - no crash-immediate instructions, they could incorrectly skip over -:: other crashes (done) -:: - we don't actually need to track sick registers (done) -!: -=* sack +3 +%zero +=* skan +3 =* moan moan.sack =* cole cole.sack -=| =hill -=| rots=shed +=| =fuji => |% -:: work +:: get analysis result by bell :: -:: new: set of bells in moan, not in hill (require codegen) -:: old: set of bells in hill, not in moan (should be dropped from hill) -++ peck - =| miel=(list bell) - =/ foam ~(tap by moan) - |- ^- [new=(set bell) old=(set bell)] - ?^ foam - ?^ q.i.foam - $(q.i.foam t.q.i.foam, miel [[soot.i.q.i.foam p.i.foam] miel]) - $(foam t.foam) - =/ jell ~(key by hill) - =/ mell (~(gas in *(set bell)) miel) - [(~(dif in mell) jell) (~(dif in jell) mell)] :: want mif-in -:: -:: new bells -++ noob - ^- (set bell) - =/ new new:peck - new -:: -:: bells to drop -++ dead - ^- (set bell) - old:peck -:: -:: look up analysis -:: -:: look up an arm in the moan face of the sack core ++ puck - |= =bell - ^- (unit hone) - =/ hose (~(get ja moan) form.bell) + |= b=bell + => [b=b m=moan ja=ja hone=hone] + ~+ + =/ h (~(get ja m) form.b) |- ^- (unit hone) - ?^ hose - ?: =(text.bell soot.i.hose) `i.hose - $(hose t.hose) - ~ -:: worklist + ?< ?=(h ~) + ?: =(text.b soot.i.h) `h + $(h t.h) +:: compute which analysis results are not linearized and return in +:: toposorted order :: -:: sort all of the un-linearized arms in `moan` topologically by the -:: reverse call DAG (so terminal arms come first). This ensures that we -:: only have to "redo" recursive callsites. ++ work - ^- (list bell) - =/ news noob - ?: =(~ news) ~ + =/ mell + %- ~(rep by moan) + |= [[f=* l=(list hone)] mell=(set bell)] + (roll l |:([h=*hone mell=mell] (~(put in mell) [soot.h f]))) + =/ novo (~(dif in mell) ~(key by peal.fuji)) =/ sire=(jug bell bell) - %- ~(rep in news) + %- ~(rep in novo) |= [b=bell sire=(jug bell bell)] =/ hues (puck b) ?< ?=(~ hues) =/ team (~(gas in *(set bell)) ~(val by ices.norm.u.hues)) =. team (~(dif in team) loop.norm.u.hues) - =. team (~(int in team) news) + =. team (~(int in team) novo) %- ~(rep in team) |: [k=*bell s=sire] (~(put ju s) k b) =< tack.s - %- ~(rep in news) + %+ roll novo |= [v=bell s=[done=(set bell) tack=(list bell)]] =* dfs $ ^- _s - ?: (~(has in done.s) v) s - =. done.s (~(put in done.s) v) + ?: (~(has in done.s v) s + =. done.s (~(put in done.s) v =/ e=(set bell) (~(get ju sire) v) - =. e (~(dif in e) done.s) =. s %- ~(rep in e) |: [n=*bell s=s] ^- _s dfs(v n, s s) - s(tack [v tack.s]) -:: -:: internal state -:: -:: redo: arms called without knowing registerization -:: will: code table -:: sans: next SSA register -:: sick: registers which should be checked for crashing at next mean -:: boundary -+$ gen [redo=(list bile) will=(map bile blob) sans=@uvre] -:: codegen -:: -:: door containing core codegen operations + s(tack [v tack.s]) ++$ gen [redo=(list [t=bell b=@uwoo]) =fuji sans=@uvre chan=@uwoo] ++ jean - =/ fax 1 - =/ =goal [%done ~] - |_ [=bell =gen like=(map bell need)] - :: codegen loop - :: - :: traverse nomm RLN and emit linearized code + |_ =gen + :: core DDCG linearizer + :: ++ cuts - =+ =/ huns (puck bell) - ?> ?=(^ huns) - norm.u.huns - |- ^- [next _gen] - ?- -.nomm + =/ =goal [%done ~] + |= =bell + =/ h (puck bell) + =* n nomm.norm.h + |- ^- [_goal _gen] + ?- -.n %par ?- -.goal %done =^ last gen rain - =^ loch gen (emit %loch ~ ~ %don last) + =^ loch gen (emit ~ ~ %don last) $(goal [%next [%this last] loch]) :: %pick (mine sass.goal zero.goal) :: %next - =^ [bill=bile left=need rite=need] gen (lyse goal) + =^ [bill=@uwoo left=need rite=need] gen (lyse goal) =^ tale gen - $(nomm rite.nomm, goal [%next rite bill], fax (peg fax 3)) + $(nomm rite.nomm, goal [%next rite bill]) =^ hale gen - $(nomm left.nomm, goal [%next left then.tale], fax (peg fax 2)) + $(nomm left.nomm, goal [%next then.tale]) (copy hale what.tale) == :: @@ -139,15 +89,15 @@ ?- -.goal %done =^ last gen rain - =^ dear gen (emit %dear ~ ~ %don last) + =^ dear gen (emit ~ ~ %don last) $(goal [%next [%this last] dear]) :: %pick =^ cove gen rain - =^ cozy gen (emit %cozy ~ ~ %brn cove [zero once]:goal) + =^ cozy gen (emit ~ ~ %brn cove [zero once]:goal) $(goal [%next [%this cove] cozy]) :: - %next + %next (from here.nomm goal) == :: @@ -155,8 +105,7 @@ ?- -.goal %done =^ last gen rain - =^ rime gen (emit %rime ~ [%imm moan.nomm last]~ %don last) - [[%next [%none ~] rime] gen] + =^ rime gen (emit ~ [%imm moan.nomm last]~ %don last) :: %pick ?: =(0 moan.nomm) @@ -170,64 +119,66 @@ [[%next [%none ~] bill] gen] == :: - %two - ?: ?=(%pick -.goal) + %two ~| %todo-two !! + ?: ?=(pick -.goal) =^ flip gen rain - =^ bird gen (emit %bird ~ ~ %brn flip [zero once]:goal) + =^ bird gen (emit ~ ~ %brn flip [zero once]:goal) $(goal [%next [%this flip] bird]) - =/ bull (~(get by ices) rail.nomm) + =/ bull (~(get by ices.norm.h) rail.n) ?~ bull + :: indirect call ?- -.goal %done =^ s gen rain =^ f gen rain - =^ tide gen (emit %tide ~ ~ %lnt s f) - =^ corn gen $(nomm corn.nomm, fax (peg fax 7), goal [%next [%this f] tide]) - =^ cost gen $(nomm cost.nomm, fax (peg fax 6), goal [%next [%this s] then.corn]) + =^ tide gen (emit ~ ~ %lnt s f) + =^ corn gen $(nomm corn.nomm, goal [%next [%this f] tide]) + =^ cost gen $(nomm cost.nomm, goal [%next [%this s] then.corn]) (copy cost what.corn) :: %next - =^ [post=bile salt=@uvre] gen (kerf %post goal) + =^ [post=@uwoo salt=@uvre] gen (kerf %post goal) =^ s gen rain =^ f gen rain - =^ dine gen (emit %dine ~ ~ %lnk s f salt post) - =^ corn gen $(nomm corn.nomm, fax (peg fax 7), goal [%next [%this f] dine]) - =^ cost gen $(nomm cost.nomm, fax (peg fax 6), goal [%next [%this s] then.corn]) + =^ dine gen (emit ~ ~ %lnk s f salt post) + =^ corn gen $(nomm corn.nomm, goal [%next [%this f] dine]) + =^ cost gen $(nomm cost.nomm, goal [%next [%this s] then.corn]) (copy cost what.corn) == + :: direct call + :: XX we need a placeholder for the @uwoo for a recursive call =/ hope (~(get by call.cole) u.bull) =^ a gen (args u.bull) + =/ wool + ?. r.a (~(got by peal.fuji.gen) u.bull) + 0 ?- -.goal %done - =^ [dire=bile seed=need] gen + =^ [dire=@uwoo seed=need] gen ?~ hope - =^ dike gen (emit %dike ~ ~ %jmp u.bull v.a) - =? redo.gen r.a [dike redo.gen] + =^ dike gen (emit ~ ~ %jmp wool v.a) + =? redo.gen r.a [[u.bull dike] redo.gen] [[dike n.a] gen] =^ s gen rain - ~! u.hope - =^ dial gen (emit %dial ~ ~ %jmf u.bull v.a s u.hope) - =? redo.gen r.a [dial redo.gen] - =^ nest gen (copy [%next n.a dial] [%this s]) + =^ dial gen (emit ~ ~ %jmf wool v.a s u.hope) + =? redo.gen r.a [[u.bull dial] redo.gen] + =^ next gen (copy [%next n.a dial] [%this s]) [[then.nest what.nest] gen] - =^ corn gen $(nomm corn.nomm, fax (peg fax 7), goal [%next [%none ~] dire]) - =^ cost gen $(nomm cost.nomm, fax (peg fax 6), goal [%next seed then.corn]) - (copy cost what.corn) :: %next - =^ [post=bile salt=@uvre] gen (kerf %post goal) - =^ [dire=bile seed=need] gen + =^ [post=@uwoo salt=@uvre] gen (kerf %post goal) + =^ [dire=@uwoo seed=need] gen ?~ hope - =^ dine gen (emit %dine ~ ~ %cal u.bull v.a salt post) - =? redo.gen r.a [dine redo.gen] + =^ dine gen (emit ~ ~ %cal wool v.a salt post) + =? redo.gen r.a [[u.bull dine] redo.gen] [[dine n.a] gen] =^ s gen rain - =^ dime gen (emit %dime ~ ~ %caf u.bull v.a salt post s u.hope) - =? redo.gen r.a [dime redo.gen] + =^ dime gen (emit ~ ~ %caf wool v.a salt post s u.hope) + =? redo.gen r.a [[u.bull dime] redo.gen] =^ nest gen (copy [%next n.a dime] [%this s]) [[then.nest what.nest] gen] - =^ corn gen $(nomm corn.nomm, fax (peg fax 7), goal [%next [%none ~] dire]) - =^ cost gen $(nomm cost.nomm, fax (peg fax 6), goal [%next seed then.corn]) + =^ corn gen $(nomm corn.nomm, goal [%next [%none ~] dire]) + =^ cost gen $(nomm cost.nomm, goal [%next seed then.corn]) (copy cost what.corn) == :: @@ -237,40 +188,39 @@ =^ last gen rain =^ hasp gen rain =^ barf gen rain - =^ tear gen (emit %tear ~ [%imm 0 last]~ %don last) - =^ fear gen (emit %fear ~ [%imm 1 hasp]~ %don hasp) + =^ tear gen (emit ~ [%imm 0 last]~ %don last) + =^ fear gen (emit ~ [%imm 1 hasp]~ %don hasp) $(goal [%pick barf tear fear]) :: %next ?: ?=(%both -.what.goal) (mine sass.what.goal then.goal) + :: no need for check if result unused ?: ?=(%none -.what.goal) - =^ barf gen rain - $(goal [%pick barf then.goal then.goal]) + $(nomm pell.nom) =^ tare gen rain - =/ tile (vial %tile) + =^ tile gen vial =^ fare gen rain - =/ file (vial %file) + =^ file gen vial =^ thin gen %: emit - %thin - %: ~(put by *(map @uvre (map bile @uvre))) - sass.what.goal - (~(gas by *(map bile @uvre)) ~[[tile tare] [file fare]]) - == - ~ - %hop then.goal + %: ~(put by *(map @uvre (map @uwoo @uvre))) + sass.what.goal + (~(gas by *(map @uwoo @uvre)) ~[[tile tare] [file fare]]) + == + ~ + %hop then.goal == =^ tear gen (come tile thin) =^ fear gen (come file thin) - =^ celt gen (emit %celt ~ [%imm 0 tare]~ %hop tear) - =^ felt gen (emit %felt ~ [%imm 1 fare]~ %hop fear) + =^ celt gen (emit ~ [%imm 0 tare]~ %hop tear) + =^ felt gen (emit ~ [%imm 1 fare]~ %hop fear) =^ barf gen rain $(goal [%pick barf celt felt]) :: %pick =^ coat gen rain - =^ pith gen (emit %pith ~ ~ %clq coat [zero once]:goal) - $(nomm pell.nomm, goal [%next [%this coat] pith], fax (peg fax 3)) + =^ pith gen (emit ~ ~ %clq coat [zero once]:goal) + $(nomm pell.nomm, goall [%next [%this coat] pith]) == :: %for @@ -278,26 +228,25 @@ %done =^ rink gen rain =^ pink gen rain - =^ tike gen (emit %tike ~ [%inc pink rink]~ %don rink) - $(nomm mall.nomm, goal [%next [%this pink] tike], fax (peg fax 3)) + =^ tike gen (emit ~ [%inc pink rink]~ %don rink) + $(nomm mall.nomm, goal [%next [%this pink] tike]) :: - %pick + %pick =^ rink gen rain =^ pink gen rain =^ pike gen (emit %pike ~ [%inc pink rink]~ %brn rink [zero once]:goal) - $(nomm mall.nomm, goal [%next [%this pink] pike], fax (peg fax 3)) + $(nomm mall.nomm, goal [%next [%this pink] pike]) :: - %next + %next ?: ?=(%both -.what.goal) (mine sass.what.goal then.goal) =^ rink gen ?: ?=(%none -.what.goal) rain [sass.what.goal gen] =^ pink gen rain - =^ bike gen - (emit %bike ~ [%inc pink rink]~ %hop then.goal) - $(nomm mall.nomm, goal [%next [%this pink] bike], fax (peg fax 3)) + =^ bike gen (emit ~ [%inc pink rin]~ %hop then.goal) + $(nomm mall.nomm, goal [%next [%this pink] bike]) == :: %ivy @@ -305,1241 +254,171 @@ %done =^ last gen rain =^ hasp gen rain - =^ reek gen (emit %reek ~ [%imm 0 last]~ %don last) - =^ riff gen (emit %riff ~ [%imm 1 hasp]~ %don hasp) + =^ reek gen (emit ~ [%imm 0 last]~ %don last) + =^ riff gen (emit ~ [%imm 1 hasp]~ %don hasp) =^ crap gen rain $(goal [%pick crap reek riff]) :: %next ?: ?=(%both -.what.goal) (mine sass.what.goal then.goal) ?: ?=(%none -.what.goal) - =^ than gen $(nomm that.nomm, fax (peg fax 7)) - =^ thin gen - $(nomm this.nomm, fax (peg fax 6), then.goal then.than) + =^ than gen $(nomm that.nomm) + =^ thin gen $(nomm this.nomm, then.goal then.than) (copy thin what.than) =^ tare gen rain - =/ till (vial %till) + =^ till gen vial =^ fare gen rain - =/ fill (vial %fill) + =^ fill gen vial =^ ward gen %: emit - %ward - %: ~(put by *(map @uvre (map bile @uvre))) - sass.what.goal - (~(gas by *(map bile @uvre)) ~[[till tare] [fill fare]]) - == - ~ - %hop - then.goal + %: ~(put by *(map @uvre (map @uwoo @uvre))) + sass.what.goal + (~(gas by *(map @uwoo @uvre)) ~[[till tare] [fill fare]]) + == + ~ + %hop + then.goal == - =^ weir gen (come till ward) + =^ weir gen (come till ward) =^ mere gen (come fill ward) - =^ ware gen (emit %ware ~ [%imm 0 tare]~ %hop weir) - =^ mare gen (emit %mare ~ [%imm 1 fare]~ %hop mere) + =^ ware gen (emit ~ [%imm 0 tare]~ %hop weir) + =^ mare gen (emit ~ [%imm 1 tare]~ %hop mere) =^ crap gen rain $(goal [%pick crap ware mare]) :: %pick =^ tire gen rain =^ tear gen rain - =^ pare gen (emit %pare ~ ~ %eqq tire tear [zero once]:goal) - =^ than gen - $(nomm that.nomm, goal [%next [%this tear] pare], fax (peg fax 7)) - =^ thin gen - $(nomm this.nomm, goal [%next [%this tire] then.than], fax (peg fax 6)) + =^ pare gen (emit ~ ~ %eqq tire tear [zero once]:goal) + =^ than gen $(nomm that.nomm, goal [%next [%this tear] pare]) + =^ thin gen $(nomm this.nomm, goal [%next [%this tire] then.than]) (copy thin what.than) == :: %six ?: ?=(%next -.goal) =^ [teal=next feel=next] gen (phil goal) - =^ fest gen - $(nomm else.nomm, fax (peg fax 15), goal feel) - =^ zest gen - $(nomm then.nomm, fax (peg fax 14), goal teal) - =^ [bead=need tile=bile file=bile] gen (sect zest fest) + =^ fest gen $(nomm else.nomm, goal feel) + =^ zest gen $(nomm then.nomm, goal teal) + =^ [bead=need tile=@uwoo file=@uwoo] gen (sect zest fest) =^ lead gen rain - =^ cond gen - $(nomm what.nomm, fax (peg fax 6), goal [%pick lead tile file]) + =^ cond gen $(nomm what.nomm, goal [%pick lead tile file]) (copy cond bead) - =^ fest gen - $(nomm else.nomm, fax (peg fax 15)) - =^ zest gen - $(nomm then.nomm, fax (peg fax 14)) - =^ [bead=need tile=bile file=bile] gen (sect zest fest) + =^ fest gen $(nomm else.nomm) + =^ zest gen $(nomm then.nomm) + =^ [bead=need tile=@uwoo file=@uwoo] gen (sect zest fest) =^ barf gen rain - =^ tool gen (emit %tool ~ [%ipb ~[barf]]~ %hop tile) + =^ tool gen (emit ~ [%ipb ~[barf]]~ %hop tile) =^ cond gen - $(nomm what.nomm, fax (peg fax 6), goal [%pick barf tool file]) + $(nomm what.nomm, goal [%pick barf tool file]) (copy cond bead) :: %eve - =^ thin gen $(nomm then.nomm, fax (peg fax 7)) - $(nomm once.nomm, goal thin, fax (peg fax 6)) + =^ thin gen $(nomm then.nomm) + $(nomm once.nomm, goal thin) :: %ten ?- -.goal %done =^ last gen rain - =^ dead gen (emit %dead ~ ~ %don last) + =^ dead gen (emit ~ ~ %don last) $(goal [%next [%this last] dead]) :: %pick ?. =(here.nomm 1) (mine sass.goal zero.goal) =^ flip gen rain - =^ deep gen (emit %deep ~ ~ %brn flip [zero once]:goal) + =^ deep gen (emit ~ ~ %brn flip [zero once]:goal) $(goal [%next [%this flip] deep]) :: %next - =^ [twig=need tree=need then=bile] gen (into here.nomm goal) - =^ nest gen - $(nomm tree.nomm, fax (peg fax 15), goal [%next tree then]) - =^ eggs gen - $(nomm twig.nomm, fax (peg fax 14), goal [%next twig then.nest]) + =^ [twig=need tree=need then=@uwoo] gen (into here.nomm goal) + =^ nest gen $(nomm tree.nomm, goal [%next tree then]) + =^ eggs gen $(nomm twig.nomm, goal [%next twig then.nest]) (copy eggs what.nest) == :: %sip - ?+ hint.nomm $(nomm then.nomm, fax (peg fax 7)) + ?+ hint.nomm $(nomm then.nomm) %bout ?- -.goal %done =^ last gen rain - =^ dime gen (emit %dime ~ ~ %don last) - $(goal [%next [%this last] dime]) + =^ dime gen (emit ~ ~ %don last) + $(goal [%next [%this last] dime) :: %pick - =^ tome gen (emit %tome ~ [%tom ~]~ %hop zero.goal) - =^ foam gen (emit %foam ~ [%tom ~]~ %hop once.goal) - =^ race gen - $(nomm then.nomm, fax (peg fax 7), goal [%pick sass.goal tome foam]) - =^ tick gen (emit %tick ~ [%tim ~]~ %hop then.race) + =^ tome gen (emit ~ [%tom ~]~ %hop zero.goal) + =^ foam gen (emit ~ [%tom ~]~ %hop once.goal) + =^ race gen $(nomm then.nomm, goal [%pick sass.goal tome foam]) + =^ tick gen (emit ~ [%tim ~]~ %hop then.race) [race(then tick) gen] :: %next - =^ stop gen (emit %stop ~ [%tom ~]~ %hop then.goal) - =^ race gen - $(nomm then.nomm, fax (peg fax 7), then.goal stop) + =^ stop gen (emit ~ [%tom ~]~ %hop then.goal) + =^ race gen $(nomm then.nomm, then.goal stop) =^ goes gen (emit %goes ~ [%tim ~]~ %hop then.race) [race(then goes) gen] == :: %meme - =^ raft gen $(nomm then.nomm, fax (peg fax 7)) - =^ meme gen (emit %meme ~ [%mem ~]~ %hop then.raft) + =^ raft gen $(nomm then.nomm) + =^ meme gen (emit ~ [%mem ~]~ %hop then.raft) [raft(then meme) gen] == :: %tip - ?+ hint.nomm - =^ thin gen $(nomm then.nomm, fax (peg fax 7)) - =^ fake gen - $(nomm vice.nomm, fax (peg fax 13), goal [%next [%none ~] then.thin]) + ?+ hint.nomm + =^ thin gen $(nomm then.nomm) + =^ fake gen $(nomm vice.nomm, goal [%next [%none ~] then.thin]) (copy fake what.thin) :: ?(%hunk %hand %lose %mean %spot) =^ mane gen rain ?- -.goal %done - =^ real gen $(nomm then.nomm, fax (peg fax 7)) - =^ dint gen - (emit %dint ~ [%men hint.nomm mane]~ %hop then.real) - =^ fake gen - $(nomm vice.nomm, fax (peg fax 14), goal [%next [%this mane] dint]) + =^ real gen $(nomm then.nomm) + =^ dint gen (emit ~ [%men hint.nomm mane]~ %hop then.real) + =^ fake gen $(nomm vice.nomm, goal [%next [%this maine] dint]) (copy fake what.real) :: %pick - =^ tame gen (emit %tame ~ [%man ~]~ %hop zero.goal) - =^ fame gen (emit %fame ~ [%man ~]~ %hop once.goal) - =^ real gen - $(nomm then.nomm, fax (peg fax 7), goal [%pick sass.goal tame fame]) - =^ dint gen - (emit %dint ~ [%men hint.nomm mane]~ %hop then.real) - =^ fake gen - $(nomm vice.nomm, fax (peg fax 13), goal [%next [%this mane] dint]) + =^ tame gen (emit ~ [%man ~]~ %hop zero.goal) + =^ fame gen (emit ~ [%man ~]~ %hop once.goal) + =^ real gen $(nomm then.nomm, goal [%pick sass.goal tame fame]) + =^ dint gen (emit ~ [%men hint.nomm mane]~ %hop then.real) + =^ fake gen $(nomm vice.nomm, goal [%next [%this mane] dint]) (copy fake what.real) :: %next - =^ rugs gen (emit %rugs ~ [%man ~]~ %hop then.goal) - =^ real gen - $(nomm then.nomm, fax (peg fax 7), then.goal rugs) - =^ dint gen - (emit %dint ~ [%men hint.nomm mane]~ %hop then.real) - =^ fake gen - $(nomm vice.nomm, fax (peg fax 13), goal [%next [%this mane] dint]) + =^ rugs gen (emit ~ [%man ~]~ %hop then.goal) + =^ real gen $(nomm then.nomm, then.goal rugs) + =^ dint gen (emit ~ [%men hint.nomm mane]~ %hop then.real) + =^ fake gen $(nomm vice.nomm, goal [%next [%this mane] dint]) (copy fake what.real) == - :: - ?(%live %slog) - =^ clue gen rain - =^ real gen $(nomm then.nomm, fax (peg fax 7)) - =^ wave gen - ?: ?=(%live hint.nomm) - (emit %live ~ [%hit clue]~ %hop then.real) - (emit %slog ~ [%slg clue]~ %hop then.real) - =^ fake gen - $(nomm vice.nomm, fax (peg fax 13), goal [%next [%this clue] wave]) - (copy fake what.real) - :: - %memo - =/ fork (~(got by fizz) hare.nomm) - =^ funk gen rain - =^ sunk gen rain - =^ gunk gen rain - =/ body=(list pole) ~[[%imm 0 gunk] [%imm fork funk]] - ?- -.goal - %done - =^ salt gen rain - =^ mode gen (emit %mode ~ ~ %don salt) - $(goal [%next [%this salt] mode]) - :: - %pick - =^ mere gen rain - =^ chit gen (emit %chit ~ ~ %brn mere zero.goal once.goal) - =^ loot gen rain - =^ root gen rain - =^ loam gen (emit %loam ~ ~[[%imm 0 loot] [%mew gunk sunk funk loot]] %hop zero.goal) - =^ rome gen (emit %rome ~ ~[[%imm 1 root] [%mew gunk sunk funk root]] %hop once.goal) - =^ moog gen $(nomm then.nomm, fax (peg fax 7), zero.goal loam, once.goal rome) - =^ cast gen (emit %cast ~ body %mer gunk sunk funk mere chit then.moog) - =^ fake gen $(nomm vice.nomm, fax (peg fax 13), goal [%next [%none ~] cast]) - =^ fear gen (copy fake what.moog) - (copy fear [%this sunk]) - :: - %next - =^ [chit=next miss=next] gen (phil goal) - =^ [chin=bile mere=@uvre] gen (kerf %chin chit) - =^ [misc=bile salt=@uvre] gen (kerf %salt miss) - =^ meow gen (emit %meow ~ [%mew gunk sunk funk salt]~ %hop misc) - =^ real gen $(nomm then.nomm, fax (peg fax 7), goal [%next [%this salt] meow]) - =^ cake gen (emit %cake ~ body %mer gunk sunk funk mere chin misc) - =^ fake gen $(nomm vice.nomm, fax (peg fax 13), goal [%next [%none ~] cake]) - =^ cope gen (copy fake what.real) - (copy cope [%this sunk]) - == - :: - %bout ~| %todo !! - == - :: - %elf - ?- -.goal - %done - =^ last gen rain - =^ deft gen (emit %deft ~ ~ %don last) - $(goal [%next [%this last] deft]) - :: - %pick - =^ flip gen rain - =^ heft gen (emit %heft ~ ~ %brn flip [zero once]:goal) - $(goal [%next [%this flip] heft]) - :: - %next - =^ [weft=bile good=@uvre] gen (kerf %weft goal) - =^ home gen rain - =^ path gen rain - =^ show gen (emit %show ~ ~ %spy home path good weft) - =^ trot gen - $(nomm walk.nomm, fax (peg fax 7), goal [%next [%this path] show]) - =^ paid gen - $(nomm rent.nomm, fax (peg fax 6), goal [%next [%this home] then.trot]) - (copy paid what.trot) + :: XX TODO %live %slog %memo %bout == == - :: - :: redo callsite registerization - :: - :: given recursion, we may not know the registerization for an arm - :: when we generate a direct call to it. Thus, once we have generated - :: code for all arms in the call tree and know their - :: registerizations, we return to callsites and generate - :: properly-registerized calls, without changing the registerization - :: of the calling arm. - ++ redo - |= =bile - ^- _gen - =. fax axe.bile - =/ blob (~(got by will.gen) bile) - ?+ -.bend.blob ~| %redo-cant !! - %cal - ?> ?=(^ v.bend.blob) - ?> ?=(~ t.v.bend.blob) - ?> (~(has by like) a.bend.blob) - =^ urge gen (args a.bend.blob) - =^ reed gen (emit %reed ~ ~ bend.blob(v v.urge)) - =^ [rush=_bile i=@uvre] gen (kerf %rush [%next n.urge reed]) - =. will.gen (~(del by will.gen) bile) - (emir bile ~ [%mov i.v.bend.blob i]~ %hop rush) - :: - %caf - ?> ?=(^ v.bend.blob) - ?> ?=(~ t.v.bend.blob) - ?> (~(has by like) a.bend.blob) - =^ urge gen (args a.bend.blob) - =^ reed gen (emit %reed ~ ~ bend.blob(v v.urge)) - =^ [rush=_bile i=@uvre] gen (kerf %rush [%next n.urge reed]) - =. will.gen (~(del by will.gen) bile) - (emir bile ~ [%mov i.v.bend.blob i]~ %hop rush) - :: - %jmp - ?> ?=(^ v.bend.blob) - ?> ?=(~ t.v.bend.blob) - ?> (~(has by like) a.bend.blob) - =^ urge gen (args a.bend.blob) - =^ reed gen (emit %reed ~ ~ bend.blob(v v.urge)) - =^ [rush=_bile i=@uvre] gen (kerf %rush [%next n.urge reed]) - =. will.gen (~(del by will.gen) bile) - (emir bile ~ [%mov i.v.bend.blob i]~ %hop rush) - :: - %jmf - ?> ?=(^ v.bend.blob) - ?> ?=(~ t.v.bend.blob) - ?> (~(has by like) a.bend.blob) - =^ urge gen (args a.bend.blob) - =^ reed gen (emit %reed ~ ~ bend.blob(v v.urge)) - =^ [rush=_bile i=@uvre] gen (kerf %rush [%next n.urge reed]) - =. will.gen (~(del by will.gen) bile) - (emir bile ~ [%mov i.v.bend.blob i]~ %hop rush) - == - :: split register to need - :: - :: given a destination, generate code which splits a noun in one - :: register to the registers described by the $need, and return the - :: one register and a label for the splitting code - ++ kerf - |= [thus=@tas =next] - ^- [[bile @uvre] _gen] - =^ ir gen (kern ~ what.next) - ?~ pose.ir - [[then.next out.ir] gen] - =^ thin gen (emit thus ~ (flop pose.ir) %hop then.next) - [[thin out.ir] gen] - :: split register to need (instruction list) - :: - :: like +kerf but return (reversed) instruction list instead of emitting basic block - ++ kern - |= [pose=(list pole) =need] - ^- [[pose=(list pole) out=@uvre] _gen] - =/ tack=(list _need) ~[need] - =/ ui (sass need) - ?~ ui - =^ crap gen rain - [[~ crap] gen] - |- ^- [[pose=(list pole) out=@uvre] _gen] - ?~ tack - [[pose u.ui] gen] - =* n i.tack - ?: ?=(%both -.n) - =/ lure (sass left.n) - =/ rule (sass rite.n) - =? pose ?=(^ lure) - [[%hed sass.n u.lure] pose] - =? pose ?=(^ rule) - [[%tal sass.n u.rule] pose] - $(tack [left.n rite.n t.tack]) - $(tack t.tack) - :: emit basic block - :: - :: given a fixed label and a basic block, - :: add the basic block to the code table - ++ emit - |= [thus=@tas =blob] - ^- [bile _gen] - =/ bill [%bile fax thus bell] - [bill (emir bill blob)] - :: emit basic block (raw label) - :: - :: given a raw bile and a basic block, add the basic block to the code - :: tabel at that label. - ++ emir - |= [=bile =blob] - ^- _gen - gen(will (~(put by will.gen) bile blob)) - :: - :: generate a register - :: - :: return the current next SSA register and increment the next SSA - :: register in the codegen state - ++ rain - ^- [@uvre _gen] - [sans.gen gen(sans .+(sans.gen))] - :: - :: split need - :: - :: split a need into two, generating cons instruction if necessary - ++ lyse - |= =next - ^- [[bile need need] _gen] - ?- -.what.next - %both :: discards sick flag which is OK since we know we will fulfill the need - [[then.next left.what.next rite.what.next] gen] - :: - %none - [[then.next [%none ~] %none ~] gen] - :: - %this - =^ l gen rain - =^ r gen rain - =^ lizz gen (emit %lyse ~ [%con l r sass.what.next]~ %hop then.next) - [[lizz [%this l] [%this r]] gen] - == - :: - :: outermost register - :: - :: get the outermost register of a need (or ~ if the need is %none): - :: used for noun-splitting code - ++ sass - |= =need - ^- (unit @uvre) - ?- -.need - %both `sass.need - %this `sass.need - %none ~ - == - :: intersect needs - :: - :: match needs from branching control flow, generating noun-splitting - :: code for each branch as necessary - :: - :: this generates the maximally common split of registers between - :: both branches. If one branch expects a cell at an axis but the other does - :: not, then we must expect that axis in a register so we do not - :: crash when the more permissive branch would be taken - ++ sect - |= [zero=next once=next] - =| lose=(list pole) - =| rose=(list pole) - =/ tack=(list (each r=@uvre [z=need o=need])) [%| what.zero what.once]~ - =| salt=(list need) - |- ^- [[need bile bile] _gen] - ?~ tack - ?> ?=(^ salt) - ?> ?=(~ t.salt) - =^ loan gen (emit %loan ~ (flop lose) %hop then.zero) - =^ roan gen (emit %roan ~ (flop rose) %hop then.once) - [[i.salt loan roan] gen] - ?- -.i.tack - %& - ?> ?=(^ salt) - ?> ?=(^ t.salt) - $(tack t.tack, salt [[%both p.i.tack i.t.salt i.salt] t.t.salt]) - :: - %| - ?: ?=(%none -.z.p.i.tack) - :: z side has no requirements - :: so we should do no splitting outside conditional - ?: ?=(%none -.o.p.i.tack) - $(tack t.tack, salt [[%none ~] salt]) - =^ rr gen (kern rose o.p.i.tack) - =. rose pose.rr - $(tack t.tack, salt [[%this out.rr] salt]) - ?: ?=(%none -.o.p.i.tack) - :: o side has no requirements - :: so we should do no splitting outside conditional - =^ lr gen (kern lose z.p.i.tack) - =. lose pose.lr - $(tack t.tack, salt [[%this out.lr] salt]) - ?: ?=(%both -.z.p.i.tack) - :: z side splits - ?: ?=(%both -.o.p.i.tack) - :: both sides split, recursively build need - %= $ - tack - :* [%| left.z.p.i.tack left.o.p.i.tack] - [%| rite.z.p.i.tack rite.o.p.i.tack] - [%& sass.z.p.i.tack] - t.tack - == - :: - rose [[%mov sass.z.p.i.tack sass.o.p.i.tack] rose] - == - :: z side splits, o side this - =^ lr gen (kern ~ z.p.i.tack) - =. lose [[%mov sass.o.p.i.tack out.lr] lose] - =. lose (weld pose.lr lose) - $(tack t.tack, salt [o.p.i.tack salt]) - ?: ?=(%both -.o.p.i.tack) - :: z side this, o side splits - =^ rr gen (kern ~ o.p.i.tack) - =. rose [[%mov sass.z.p.i.tack out.rr] rose] - =. rose (weld pose.rr rose) - $(tack t.tack, salt [z.p.i.tack salt]) - :: both sides this - =. rose [[%mov sass.z.p.i.tack sass.o.p.i.tack] rose] - $(tack t.tack, salt [z.p.i.tack salt]) - == - :: - :: union needs - :: - :: generate a need split as far as either input need is split, - :: generating cons code for less-split need. This is used when two - :: sequential subformulas read from the same subject - :: - :: for correctness in crash handling it is vital that the needs are - :: ordered by the evaluation order of the computations, so that the - :: first need is from the first computation and the second need from - :: the second. - ++ copy - |= [feed=next seed=need] - =| pose=(list pole) - =/ tack=(list (each @uvre [l=need r=need])) [%| what.feed seed]~ - =| rack=(list need) - |- ^- [next _gen] - ?~ tack - ?> ?=(^ rack) - ?> ?=(~ t.rack) - =^ cody gen (emit %copy ~ pose %hop then.feed) - [[%next i.rack cody] gen] - ?: ?=(%& -.i.tack) - ?> ?=(^ rack) - ?> ?=(^ t.rack) - $(rack [[%both p.i.tack i.t.rack i.rack] t.t.rack], tack t.tack) - ?: ?=(%none -.l.p.i.tack) $(rack [r.p.i.tack rack], tack t.tack) - ?: ?=(%none -.r.p.i.tack) $(rack [l.p.i.tack rack], tack t.tack) - ?: ?=(%this -.l.p.i.tack) - ?: ?=(%this -.r.p.i.tack) - :: both this - =? pose ?! .= sass.l.p.i.tack sass.r.p.i.tack - [[%mov sass.l.p.i.tack sass.r.p.i.tack] pose] - $(rack [l.p.i.tack rack], tack t.tack) - :: left this, right both - :: - :: this case must be handled this way in case the code that needs - :: l.p.i.tack will crash explicitly in some way. - =^ rr gen (kern ~ r.p.i.tack) - =. pose (weld (flop pose.rr) pose) - =? pose ?!(=(sass.l.p.i.tack out.rr)) - [[%mov sass.l.p.i.tack out.rr] pose] - $(tack t.tack, rack [[%this sass.l.p.i.tack] rack]) - ?: ?=(%both -.r.p.i.tack) - :: both both - %= $ - pose [[%mov sass.l.p.i.tack sass.r.p.i.tack] pose] - tack - :* [%| left.l.p.i.tack left.r.p.i.tack] - [%| rite.l.p.i.tack rite.r.p.i.tack] - [%& sass.l.p.i.tack] - t.tack - == - == - :: left both, right this - =/ lu (sass left.l.p.i.tack) - =/ ru (sass rite.l.p.i.tack) - =^ l gen ?~(lu rain [u.lu gen]) - =^ r gen ?~(ru rain [u.ru gen]) - %= $ - pose [[%con l r sass.r.p.i.tack] pose] - tack - :* [%| left.l.p.i.tack %this l] - [%| rite.l.p.i.tack %this r] - [%& sass.l.p.i.tack] - t.tack - == - == - :: - :: crash - :: - :: generate unconditional crashing code - ++ bomb - =^ b gen boom - [[%next [%none ~] b] gen] - :: - :: crash - :: - :: like +bomb, but return only the label and not the need - ++ boom - (emit %boom ~ ~ %bom ~) - :: - :: Defer crash - :: - :: Unconditionally poison the register. - :: - :: This used when a value is known to not match the expectation of a - :: need - ++ mine - |= [r=@uvre t=bile] - ^- [next _gen] - =^ mile gen (emit %mine ~ [%poi r]~ %hop t) - [[%next [%none ~] t] gen] - :: - :: create label - :: - :: emit a label with the given fixed name in the current context - ++ vial - |= t=@tas - [%bile fax t bell] - :: - :: label come-from - :: - :: emit an instruction which explicitly records the jump origin - :: useful for evaluating phi instructions in the jump destination - ++ come - |= [f=bile t=bile] - :- f - %= gen - will - %+ ~(put by will.gen) f - ^- blob [~ ~ %hip f t] - == - :: - :: emit phi node - :: - :: given a destination common to two branches, generate a phi node - :: and come-from blocks - ++ phil - |= =next - =/ tack=(list (each [zp=@uvre op=@uvre] need)) [%| what.next]~ - =| salt=(list [z=need o=need]) - =| biff=(map @uvre (map bile @uvre)) - =/ zb (vial %zebu) - =/ ob (vial %oboe) - |- ^- [[_next _next] _gen] - ?~ tack - ?> ?=(^ salt) - ?> ?=(~ t.salt) - =^ fill gen (emit %phil biff ~ %hop then.next) - =^ zeke gen (come zb fill) - =^ oaks gen (come ob fill) - [[[%next z.i.salt zeke] [%next o.i.salt oaks]] gen] - ?- -.i.tack - %& - ?> ?=(^ salt) - ?> ?=(^ t.salt) - %= $ - tack t.tack - salt - :_ t.t.salt - :- [%both zp.p.i.tack z.i.t.salt z.i.salt] - [%both op.p.i.tack o.i.t.salt o.i.salt] - == - :: - %| - ?- -.p.i.tack - %none $(salt [[[%none ~] %none ~] salt], tack t.tack) - %this - =^ l gen rain - =^ r gen rain - =/ phi (~(gas by *(map bile @uvre)) ~[[zb l] [ob r]]) - %= $ - biff (~(put by biff) sass.p.i.tack phi) - tack t.tack - salt [[[%this l] %this r] salt] - == - :: - %both - =^ hurl gen rain - =^ barf gen rain - =/ phi (~(gas by *(map bile @uvre)) ~[[zb hurl] [ob barf]]) - %= $ - biff (~(put by biff) sass.p.i.tack phi) - tack - :* [%| left.p.i.tack] - [%| rite.p.i.tack] - [%& hurl barf] - t.tack - == - == - == - == - :: - :: direct call information - :: - :: when we emit code for a direct call, we hope to know the - :: registerization already. If we don't, we need to add the call to - :: the redo set. If we do, then we need a linear list of poison - :: registers and a linear list of argument registers, as well as a - :: need which describes which parts of the call subject go in which - :: registers - ++ args - |= =_bell - ^- [[v=(list @uvre) n=need r=?] _gen] - =/ cn (~(get by like) bell) - =? cn ?=(~ cn) - =/ dn (~(get by hill) bell) - ?~ dn ~ - `want.u.dn - ?~ cn - =^ s gen rain - [[~[s] [%this s] &] gen] - =^ s gen (scar u.cn) - [[v n |]:s gen] - :: - :: generate fresh parameter lists - :: - :: generate fresh parameter variables and provide them both in - :: argument list and need form - ++ scar - |= n=need - =| rv=(list @uvre) - =/ tack=(list (each @uvre need)) [%| n]~ - =| salt=(list need) - |- ^- [[v=(list @uvre) n=need] _gen] - ?~ tack - ?> ?=(^ salt) - ?> ?=(~ t.salt) - [[(flop rv) i.salt] gen] - ?- -.i.tack - %& - ?> ?=(^ salt) - ?> ?=(^ t.salt) - $(tack t.tack, salt [[%both p.i.tack i.t.salt i.salt] t.t.salt]) - :: - %| - ?- -.p.i.tack - %both - =^ br gen rain - %= $ - tack - :* [%| left.p.i.tack] - [%| rite.p.i.tack] - [%& br] - t.tack - == - == - :: - %none $(tack t.tack, salt [[%none ~] salt]) - %this - =^ vr gen rain - $(rv [vr rv], salt [[%this vr] salt], tack t.tack) - == - == - :: need at axis - :: - :: push a need down by adding %both cases along the path described by - :: the axis. Used for nock 0 / %not. - ++ from - |= [axe=@ =next] - ?< =(0 axe) - =^ crap gen - =/ crop (sass what.next) - ?~ crop rain - [u.crop gen] - =? what.next ?=(%none -.what.next) [%this crap] - =| bait=(list [r=@uvre c=?(%2 %3)]) - |- ^- [_next _gen] - ?. =(1 axe) - =^ barf gen rain - $(bait [[barf (cap axe)] bait], axe (mas axe)) - =/ bits (turn bait |=([r=@uvre *] r)) - =^ fram gen (emit %fram ~ [%ipb ~[crap]]~ %hop then.next) - =/ feed - %+ roll bait - |= [[r=@uvre c=?(%2 %3)] n=_what.next] - ?- c - %2 [%both r n %none ~] - %3 [%both r [%none ~] n] - == - [[%next feed fram] gen] - :: - :: split need at axis - :: - :: split a need along an axis to describe an edit operation. - :: the first returned need is for the patch noun, and the second is - :: for the noun to be edited - ++ into - |= [axe=@ =next] - =* twig what.next - =| tres=(list [lr=?(%2 %3) p=@uvre =need]) - =| pose=(list pole) - ?< =(0 axe) - |- ^- [[need need bile] _gen] - ?. =(1 axe) - =^ p gen rain - ?- (cap axe) - %2 - ?- -.twig - %both - %= $ - tres [[%2 p rite.twig] tres] - twig left.twig - axe (mas axe) - pose [[%mov p sass.twig] pose] - == - :: - %this - =^ l gen rain - =^ r gen rain - %= $ - tres [[%2 p %this r] tres] - twig [%this l] - axe (mas axe) - pose [[%con l r sass.twig] pose] - == - :: - %none - %= $ - tres [[%2 p %none ~] tres] - axe (mas axe) - == - == - :: - %3 - ?- -.twig - %both - %= $ - tres [[%3 p left.twig] tres] - twig rite.twig - axe (mas axe) - pose [[%mov p sass.twig] pose] - == - :: - %this - =^ l gen rain - =^ r gen rain - %= $ - tres [[%3 p %this l] tres] - twig [%this r] - axe (mas axe) - pose [[%con l r sass.twig] pose] - == - :: - %none - %= $ - tres [[%3 p %none ~] tres] - axe (mas axe) - == - == - == - =^ flag gen rain - =/ tree=need [%this flag] - |- ^- [[need need bile] _gen] - ?~ tres - =^ tint gen (emit %into ~ [[%ipb ~[flag]] pose] %hop then.next) - [[twig tree tint] gen] - ?- lr.i.tres - %2 - $(tres t.tres, tree [%both p.i.tres tree need.i.tres]) - :: - %3 - $(tres t.tres, tree [%both p.i.tres need.i.tres tree]) - == - :: - :: split immediate - :: - :: given a noun and a need, generate instructions to emit that noun - :: into the registers of that need - ++ mede - |= [=bile n=* =need] - =| todo=(list pole) - =/ tack=(list [n=(unit *) =_need]) [`n need]~ - |- ^- [_bile _gen] - ?~ tack - (emit %mede ~ todo %hop bile) - ?- -.need.i.tack - %none $(tack t.tack) - %this - ?~ n.i.tack - $(todo [[%poi sass.need.i.tack] todo], tack t.tack) - $(todo [[%imm u.n.i.tack sass.need.i.tack] todo], tack t.tack) - :: - %both - ?~ n.i.tack - $(tack [[~ rite.need.i.tack] [~ left.need.i.tack] t.tack]) - ?@ u.n.i.tack - $(tack [[~ rite.need.i.tack] [~ left.need.i.tack] t.tack]) - $(tack [[`+.u.n.i.tack rite.need.i.tack] [`-.u.n.i.tack left.need.i.tack] t.tack]) - == + :: XX + :: rain - new register + :: emit - add basic block + :: lyse - split need for cons + :: mine - set up deferred crash + :: from - push need down by axis + :: mede - immediates into need + :: kerf - split single register into goal + :: args - look up subject registerization + :: vial - new basic block label + :: copy - align subject needs for sequential computation + :: sect - align subject needs for branching computation + :: phil - generate phi nodes + :: into - split need for edit -- -:: -:: lists of registers from a need -:: -:: the second list (walt) is the input registers in left-to-right order -++ sill - |= want=need - =| wart=(list @uvre) - =/ tack=(list need) ~[want] - |- ^- (list @uvre) - ?~ tack wart - ?- -.i.tack - %none $(tack t.tack) - %both - %= $ - tack [rite.i.tack left.i.tack t.tack] - == - :: - %this - %= $ - wart [sass.i.tack wart] - tack t.tack - == - == -:: -:: loop over redos -:: -:: run redo:jean on each arm in the redo list, which will generate -:: code to properly registerize callsites whose registerization was -:: deferred, without changing the registerization of the calling arm -++ mill - =| todo=(list [=bell dire=next =gen]) - =| like=(map bell need) - =/ toil work - =/ wurk toil - |- ^- _hill - ?^ toil - =/ [dire=next =gen] ~(cuts jean i.toil *gen like) - %= $ - toil t.toil - todo [[i.toil dire gen] todo] - like (~(put by like) i.toil what.dire) - == - |- ^- _hill - ?^ todo - =/ r redo.gen.i.todo - |- ^- _hill - ?^ r - =. gen.i.todo - ~| =* bel bell.i.todo - =/ mot (~(get ja moan) form.bel) - |- ^- ?(%redo-fail ~) - ?~ mot ~ - ?: =(soot.i.mot text.bel) - ((outa:blot:sack "redo fail: " `@`0 [seat area]:norm.i.mot) %redo-fail) - $(mot t.mot) - (~(redo jean bell.i.todo gen.i.todo like) i.r) - $(r t.r) - =^ [wish=bile sire=@uvre] gen.i.todo (~(kerf jean bell.i.todo gen.i.todo like) %indy dire.i.todo) - ?. (~(has by will.gen.i.todo) wish) ~& %missing-wish !! - %= ^$ - hill - =/ walt (sill what.dire.i.todo) - %+ ~(put by hill) bell.i.todo - [then.dire.i.todo what.dire.i.todo walt wish sire [will sans]:gen.i.todo] - :: - todo t.todo - == - :: XX temporary: turn hip/phi into mov so we can run this as-is - :: note that it's not safe to do mov coalescing on the output of this - :: since we may now have multiple %mov's that target one register - =/ toil wurk - |- ^- _hill - ?~ toil - hill - %= $ - toil t.toil - :: - hill - %+ ~(jab by hill) i.toil - |= =pile - =/ seen (~(gas in *(set bile)) ~[long wish]:pile) - =/ queu=(list bile) ~(tap in seen) - =| back=(list bile) - =| will=(map bile blob) - !. - |- ^+ pile - ?~ queu - ?~ back pile(will will) - $(queu (flop back), back ~) - =/ blob (~(got by will.pile) i.queu) - =^ more=(list bile) blob - ?- -.bend.blob - %hip - :- ~[t.bend.blob] - =/ movs - %- ~(rep by biff:(~(got by will.pile) t.bend.blob)) - |= [[out=@uvre bin=(map bile @uvre)] lit=(list pole)] - [[%mov (~(got by bin) c.bend.blob) out] lit] - [biff.blob (welp body.blob movs) %hop t.bend.blob] :: XX flop? - :: - %clq [~[z o]:bend.blob blob] - %eqq [~[z o]:bend.blob blob] - %brn [~[z o]:bend.blob blob] - %hop [~[t.bend.blob] blob] - %lnk [~[t.bend.blob] blob] - %cal [~[t.bend.blob] blob] - %caf [~[t.bend.blob] blob] - %lnt `blob - %jmp `blob - %jmf `blob - %spy [~[t.bend.blob] blob] - %mer [~[i m]:bend.blob blob] - %don `blob - %bom `blob - == - |- ^+ pile - ?~ more - ^$(queu t.queu, will (~(put by will) i.queu blob)) - ?: (~(has in seen) i.more) - $(more t.more) - $(more t.more, back [i.more back], seen (~(put in seen) i.more)) - - == -- -:: codegen interface -=+ %1 +=+ ver=%1 |% -:: -:: core reference ++ this . -:: -:: look for code -:: -:: check if code exists for a given subject and formula -:: XX should optionally return a path to be checked against hot state, -:: to invoke jets on indirect -++ peek - |= [s=* f=*] - ^- (unit [=bell hall=_hill]) - =/ moat (~(get ja moan) f) - |- - ?~ moat ~ - ?. (~(huge so:sack soot.i.moat) [& s]) - $(moat t.moat) - ?. (~(has by hill) [soot.i.moat f]) - ~& %not-in-hill !! - `[[soot.i.moat f] hill] -:: -:: core state interface -:: [%comp ...]: generate code for given subject/formula pair -++ poke - |= =gist - ~> %bout - ^- [new=(set bell) old=(set bell) =_this] - :: %comp is the only case - :: analyze - =. sack - ~> %bout.[0 %sack] - (rout:sack s.gist f.gist) - ?< =(~ moan) - :: save old codegen table keys - =/ hole ~(key by hill) - :: codegen - =. hill mill - :: get entry label for new codegen - =/ bell - =/ peep (peek [s f]:gist) - ?> ?=(^ peep) - bell.u.peep - =/ heck ~(key by hill) - [(~(dif in heck) hole) (~(dif in hole) heck) this] -:: pretty-printing door -++ xray - |_ will=(map bile blob) - :: - :: print a bell as an @ux-ed mug - ++ ring - |= a=bell - ^- tank - >`@ux`(mug a)< - :: - :: print a bell as an @ux-ed mug + formula - ++ rang - |= a=bell - ^- tank - [%rose ["-" "" ""] (ring a) >form.a< ~] - :: - :: print a bile as thus and axe + a pretty bell - ++ rung - |= b=bile - ^- tank - [%rose ["." "[" "]"] >thus.b< >axe.b< (ring +>+.b) ~] - :: - :: print a register - ++ near - |= r=@uvre - ^- tank - [%leaf 'r' (a-co:co r)] - :: - :: instruction print helper - ++ pink - |= [t=@tas l=(list tank)] - ^- tank - [%palm [" " "" "" ""] [%leaf (trip t)] l] - :: - :: print a dataflow instruction - ++ ping - |= i=pole - ?- -.i - %imm - (pink -.i >n.i< (near d.i) ~) - :: - %mov - (pink -.i (near s.i) (near d.i) ~) - :: - %inc - (pink -.i (near s.i) (near d.i) ~) - :: - %con - (pink -.i (near h.i) (near t.i) (near d.i) ~) - :: - %hed - (pink -.i (near s.i) (near d.i) ~) - :: - %tal - (pink -.i (near s.i) (near d.i) ~) - :: - %men - (pink -.i [%leaf (trip l.i)] (near s.i) ~) - :: - %man - (pink -.i ~) - :: - %hit - (pink -.i (near s.i) ~) - :: - %slg - (pink -.i (near s.i) ~) - :: - %mew - (pink -.i (near k.i) (near u.i) (near f.i) (near r.i) ~) - :: - %tim - (pink -.i ~) - :: - %tom - (pink -.i ~) - :: - %mem - (pink -.i ~) - :: - %poi - (pink -.i (near p.i) ~) - :: - %ipb - (pink -.i (turn p.i near)) - :: - %slo - ~| %todo !! - :: - %sld - ~| %todo !! - == - :: - :: print a control flow instruction - ++ pine - |= i=site - ^- tank - ?- -.i - %clq - (pink -.i (near s.i) (rung z.i) (rung o.i) ~) - :: - %eqq - (pink -.i (near l.i) (near r.i) (rung z.i) (rung o.i) ~) - :: - %brn - (pink -.i (near s.i) (rung z.i) (rung o.i) ~) - :: - %hop - (pink -.i (rung t.i) ~) - :: - %hip - (pink -.i (rung c.i) (rung t.i) ~) - :: - %lnk - (pink -.i (near u.i) (near f.i) (near d.i) (rung t.i) ~) - :: - %cal - (pink -.i (ring a.i) [%rose ["," "[" "]"] (turn v.i near)] (near d.i) (rung t.i) ~) - :: - %caf - (pink -.i (ring a.i) [%rose ["," "[" "]"] (turn v.i near)] (near d.i) (rung t.i) (near u.i) >n.i< ~) - :: - %lnt - (pink -.i (near u.i) (near f.i) ~) - :: - %jmp - (pink -.i (ring a.i) [%rose ["," "[" "]"] (turn v.i near)] ~) - :: - %jmf - (pink -.i (ring a.i) [%rose ["," "[" "]"] (turn v.i near)] (near u.i) >n.i< ~) - :: - %spy - (pink -.i (near e.i) (near p.i) (near d.i) (rung t.i) ~) - :: - %mer - (pink -.i (near k.i) (near u.i) (near f.i) (near d.i) (rung i.i) (rung m.i) ~) - :: - %don - (pink -.i (near s.i) ~) - :: - %bom - (pink -.i ~) - == - :: - :: print a basic block - ++ plop - |= =blob - ^- tank - [%rose [";" "" ""] (snoc (turn body.blob ping) (pine bend.blob))] - :: - :: topo-sort code in execution order, from an entry point - ++ sore - |= tart=bile - =/ queu=(list bile) ~[tart] - =| back=(list bile) - =| code=(list [bile blob]) - =| done=(set bile) - |- ^- (list [bile blob]) - ?~ queu - ?~ back - (flop code) - $(queu (flop back), back ~) - ?: (~(has in done) i.queu) - $(queu t.queu) - =/ blub (~(got by will) i.queu) - =/ ouch=(list bile) - ?- -.bend.blub - %clq ~[z o]:bend.blub - %eqq ~[z o]:bend.blub - %brn ~[z o]:bend.blub - %hop ~[t]:bend.blub - %hip ~[t]:bend.blub - %lnk ~[t]:bend.blub - %cal ~[t]:bend.blub - %caf ~[t]:bend.blub - %lnt ~ - %jmp ~ - %jmf ~ - %spy ~[t]:bend.blub - %mer ~[i m]:bend.blub - %don ~ - %bom ~ - == - %= $ - queu t.queu - back (weld ouch back) - code [[i.queu blub] code] - done (~(put in done) i.queu) - == - :: - :: print the whole code for this arm - ++ parm - |= tart=bile - ^- tank - :* %rose [" " "" ""] - (rang bell.tart) - %+ turn (sore tart) - |= [l=bile b=blob] - [%palm ["" "" "->" ""] (rung l) (plop b) ~] - == - :: - :: print register value assignments - ++ vals - |= v=(map @uvre *) - ^- tank - :* %rose [" " "" ""] - %+ turn ~(tap by v) - |= [r=@uvre n=*] - [%palm ["=" "" "" ""] (near r) >n< ~] - == - :: - :: print value assigned to register - ++ gals - |= [x=@uvre v=(map @uvre *)] - ^- tank - [%palm ["<--" "" "" ""] (near x) (vals v) ~] - -- -:: -:: print code for an arm, if it exists -++ rake - |= [s=* f=*] - ^- tank - =/ a (peek s f) - ?~ a [%leaf "no code generated for arm"] - =/ pile (~(got by hall.u.a) bell.u.a) - (~(parm xray will.pile) wish.pile) -:: -:: debug-print code for an arm, if it exists -++ rack - |= [s=* f=*] - ^- ~ - ((slog (rake s f) ~) ~) +++ peek ~| %todo !! +++ poke ~| %todo !! +++ xray ~| %todo !! -- diff --git a/hoon/codegen/sur/gene.hoon b/hoon/codegen/sur/gene.hoon index 83724d5..177428c 100644 --- a/hoon/codegen/sur/gene.hoon +++ b/hoon/codegen/sur/gene.hoon @@ -27,10 +27,6 @@ :: formula +$ bell [text=sock form=*] :: -:: internal label -:: -:: labels a basic block within generated code for an arm -+$ bile [%bile axe=@ thus=@tas =bell] :: noun shape :: :: labels axes of an abstract noun with SSA registers, possibly @@ -53,9 +49,9 @@ :: %done: nock is in tail position, return result :: %next: jump to given label with result in given $need +$ goal - $% [%pick sass=@uvre zero=bile once=bile] + $% [%pick sass=@uvre zero=@uwoo once=@uwoo] [%done ~] - [%next what=need then=bile] + [%next what=need then=@uwoo] == :: :: instructions in a block @@ -174,19 +170,19 @@ :: %don - return value in s from current arm :: %bom - crash +$ site - $% [%clq s=@uvre z=bile o=bile] - [%eqq l=@uvre r=@uvre z=bile o=bile] - [%brn s=@uvre z=bile o=bile] - [%hop t=bile] - [%hip c=bile t=bile] - [%lnk u=@uvre f=@uvre d=@uvre t=bile] - [%cal a=bell v=(list @uvre) d=@uvre t=bile] - [%caf a=bell v=(list @uvre) d=@uvre t=bile u=@uvre n=[path @]] + $% [%clq s=@uvre z=@uwoo o=@uwoo] + [%eqq l=@uvre r=@uvre z=@uwoo o=@uwoo] + [%brn s=@uvre z=@uwoo o=@uwoo] + [%hop t=@uwoo] + [%hip c=@uwoo t=@uwoo] + [%lnk u=@uvre f=@uvre d=@uvre t=@uwoo] + [%cal a=@uwoo v=(list @uvre) d=@uvre t=@uwoo] + [%caf a=@uwoo v=(list @uvre) d=@uvre t=@uwoo u=@uvre n=[path @]] [%lnt u=@uvre f=@uvre] - [%jmp a=bell v=(list @uvre)] - [%jmf a=bell v=(list @uvre) u=@uvre n=[path @]] - [%spy e=@uvre p=@uvre d=@uvre t=bile] - [%mer k=@uvre u=@uvre f=@uvre d=@uvre i=bile m=bile] + [%jmp a=@uwoo v=(list @uvre)] + [%jmf a=@uwoo v=(list @uvre) u=@uvre n=[path @]] + [%spy e=@uvre p=@uvre d=@uvre t=@uwoo] + [%mer k=@uvre u=@uvre f=@uvre d=@uvre i=@uwoo m=@uwoo] [%don s=@uvre] [%bom ~] == @@ -197,7 +193,7 @@ :: flow instruction) :: zero or more dataflow instructions executed in order, followed by a :: single control-flow instruction -+$ blob [biff=(map @uvre (map bile @uvre)) body=(list pole) bend=site] ++$ blob [biff=(map @uvre (map @uwoo @uvre)) body=(list pole) bend=site] :: :: compilation unit :: @@ -211,17 +207,27 @@ :: will: code table for arm axis 126 :: sans: next SSA register axis 127 +$ pile - $: long=bile - want=need + $: want=need walt=(list @uvre) - wish=bile sire=@uvre - will=(map bile blob) sans=@uvre == +:: code table state :: -:: code table +:: Code table :: -:: code entry information for arms -+$ hill (map bell pile) +:: hill: basic block table +:: peal: direct entry points +:: gong: indirect entry points +:: gist: register information +:: next: next free register +:: free: free label spaces ++$ fuji + $: hill=(map @uwoo blob) + peal=(map bell @uwoo) + gong=(map bell @uwoo) + gist=(map bell pile) + next=@uwoo + free=(list @uwoo) + == --