|
|
1.1 ! root 1: (* Copyright 1989 by AT&T Bell Laboratories *) ! 2: structure Reorder : sig val reorder : Lambda.lexp -> Lambda.lexp end = ! 3: struct ! 4: ! 5: open Lambda ! 6: ! 7: fun inorder({regs=ra:int,side=sa,exp=_} ! 8: :: (rest as {regs=rb,side=sb,exp=_} :: _)) = ! 9: (ra >= rb orelse sa andalso sb) andalso inorder rest ! 10: | inorder _ = true ! 11: ! 12: fun cost(r::rest) = max(r, 1+cost rest) ! 13: | cost nil = 0 ! 14: ! 15: fun insert(a as{side=true,...}, l as {side=true,...}::_) = a::l ! 16: | insert(a as{regs=ra,side,exp,var}, l as (b as {regs=rb,...})::c) = ! 17: if (ra:int) >= rb then a::l else b::insert(a,c) ! 18: | insert(a,l) = a::l ! 19: ! 20: fun sort(do_it, l) = if inorder l ! 21: then {regs=cost(map (#regs) l), side=exists (#side) l, ! 22: exp= do_it(map (#exp) l)} ! 23: else let val l' = map (fn{regs,side,exp}=> ! 24: {regs=regs,side=side,exp=exp, ! 25: var=Access.mkLvar()}) ! 26: l ! 27: val e0 = do_it (map (fn {var,...}=> VAR var) l') ! 28: val l'' = fold insert l' nil ! 29: in {regs= cost(map (#regs) l''), ! 30: side = exists (#side) l'', ! 31: exp = fold (fn({var,exp,...},e)=>APP(FN(var,e),exp)) l'' e0} ! 32: end ! 33: ! 34: val many = 12 (* how many regs to charge a function call *) ! 35: ! 36: val rec reorder : lexp -> {regs: int, side: bool, exp: lexp} = ! 37: fn e as VAR _ => {regs=0, side=false, exp=e} ! 38: | FN(v,e) => {regs=1, side=false, exp= FN(v, #exp(reorder e))} ! 39: | FIX(vl,el,e) => let val {regs,side,exp} = reorder e ! 40: in {regs=regs+1,side=side,exp=FIX(vl,el,exp)} ! 41: end ! 42: | APP(PRIM i, b) => let val {regs=r,side=s,exp=e1} = reorder b ! 43: val e2 = APP(PRIM i, e1) ! 44: in if Prim.pure i then {regs=r,side=s,exp=e2} ! 45: else {regs=many,side=true,exp=e2} ! 46: end ! 47: | e as APP(a,b) => let val {regs=r,side=s,exp=e1} = ! 48: sort( fn[x,y]=>APP(x,y), map reorder [a,b]) ! 49: in {regs=many,side=true,exp=e1} ! 50: end ! 51: | e as INT i => {regs=0, side=false, exp=e} ! 52: | e as REAL i => {regs=0, side=false, exp=e} ! 53: | e as STRING i => {regs=0, side=false, exp=e} ! 54: | SWITCH(e0,l,d) => ! 55: let val {regs,side,exp}= reorder e0 ! 56: val (lr,ls,l') = fold (fn((c,e),(r,s,l)) => ! 57: let val {regs,side,exp}=reorder e ! 58: in (max(r,regs),s orelse side,(c,exp)::l) ! 59: end) l (regs,side,nil) ! 60: in case d ! 61: of SOME d' => let val {regs=dr,side=ds,exp=de} = reorder d' ! 62: in {regs=max(lr,dr),side=ls orelse ds, ! 63: exp=SWITCH(exp,l',SOME de)} ! 64: end ! 65: | NONE => {regs=lr,side=ls,exp=SWITCH(exp,l',NONE)} ! 66: end ! 67: | RECORD l => sort(RECORD, map reorder l) ! 68: | SELECT(i,e) => let val {regs,side,exp} = reorder e ! 69: in {regs=max(1,regs),side=side,exp=SELECT(i,exp)} ! 70: end ! 71: | RAISE e => let val {regs,side,exp} = reorder e ! 72: in {regs=max(1,regs),side=side,exp=RAISE exp} ! 73: end ! 74: | HANDLE(a,b) => let val {regs=ra,side=sa,exp=ea} = reorder a ! 75: val {regs=rb,side=sb,exp=eb} = reorder b ! 76: in {regs=ra,side=sa orelse sb,exp=HANDLE(ea,eb)} ! 77: end ! 78: | e as PRIM i => {regs=0,side=false,exp=e} ! 79: ! 80: val reorder = fn x => #exp (reorder x) ! 81: ! 82: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.