|
|
1.1 ! root 1: (* Copyright 1989 by AT&T Bell Laboratories *) ! 2: structure Hoist : sig val hoist : (string->unit)->CPS.cexp->CPS.cexp end = ! 3: struct ! 4: open Access CPS SortedList ! 5: ! 6: type fv = lvar list ! 7: ! 8: datatype cexp' ! 9: = RECORD' of (lvar * accesspath) list * lvar * cexp' * fv ! 10: | SELECT' of int * lvar * lvar * cexp' * fv ! 11: | OFFSET' of int * lvar * lvar * cexp' * fv ! 12: | APP' of lvar * lvar list ! 13: | FIX' of function' list * fv * cexp' * fv ! 14: | SWITCH' of lvar * (cexp' * fv) list ! 15: | PRIMOP' of Access.primop * lvar list * lvar list * (cexp' * fv) list ! 16: withtype function' = lvar * lvar list * cexp' ! 17: ! 18: fun sum f = let fun h [] = 0 ! 19: | h (a::r) = f a + h r ! 20: in h ! 21: end ! 22: ! 23: fun hoist click cexp = ! 24: let (* val _ = CPSprint.show (output std_out) (Intmap.map ctab) cexp *) ! 25: val clicked = ref false ! 26: val click = fn x => (clicked := true; click x) ! 27: infix 6 \/ val op \/ = merge ! 28: infix 7 /\ val op /\ = intersect ! 29: infix 6 -- val op -- = fn(a,b) => remove(b,a) ! 30: val rec hoist = ! 31: fn RECORD(vl, w, e) => ! 32: (case hoist e ! 33: of (e as FIX'(l,v1,e',v2), v3) => ! 34: if member v1 w ! 35: then (RECORD'(vl, w, e, v3), v3--[w]\/uniq(map #1 vl)) ! 36: else let val defined = uniq(map #1 l) ! 37: val v4 = v2--[w]\/uniq(map #1 vl) ! 38: in (FIX'(l,v1,RECORD'(vl,w,e',v2),v4), v1\/(v4--defined)) ! 39: end ! 40: | (e,v1) => (RECORD'(vl, w, e, v1), v1--[w]\/uniq(map #1 vl))) ! 41: | SELECT(i,v,w,e) => ! 42: (case hoist e of ! 43: (e as FIX'(l,v1,e',v2), v3) => if member v1 w ! 44: then (SELECT'(i, v, w, e, v3), v3--[w]\/[v]) ! 45: else let val defined = uniq(map #1 l) ! 46: val v4 = v2--[w]\/[v] ! 47: in (FIX'(l,v1,SELECT'(i,v,w,e',v2),v4),v1\/(v4--defined)) ! 48: end ! 49: | (e,v1) => (SELECT'(i, v, w, e, v1),v1--[w]\/[v])) ! 50: | PRIMOP(i,vl,wl,[e]) => ! 51: (case hoist e ! 52: of(e as FIX'(l,v1,e',v2),v3) => ! 53: (case uniq wl /\ v1 ! 54: of [] => let val v4 = v2--uniq wl\/uniq vl ! 55: val defined = uniq(map #1 l) ! 56: in (FIX'(l,v1,PRIMOP'(i,vl,wl,[(e',v2)]),v4),v1\/(v4--defined)) ! 57: end ! 58: | _ => (PRIMOP'(i, vl, wl, [(e,v3)]),v3--uniq wl\/uniq vl)) ! 59: | (e,v1) => (PRIMOP'(i, vl, wl, [(e,v1)]),v1--uniq wl\/uniq vl)) ! 60: | PRIMOP(i,vl,wl,el) => ! 61: let val el' = map hoist el ! 62: in (PRIMOP'(i,vl,wl,el'), foldmerge(map #2 el')--uniq wl\/uniq vl) ! 63: end ! 64: | APP(f,vl) => (APP'(f,vl), uniq(f::vl)) ! 65: | SWITCH(v,el) => ! 66: let val el' = map hoist el ! 67: in (SWITCH'(v, el'), foldmerge(map #2 el')\/[v]) ! 68: end ! 69: | FIX(l,e) => ! 70: let fun h((f,vl,(e as FIX'(l',v1,e',v2),v3))::r) = ! 71: let val (ll, v4) = h r ! 72: in case uniq vl /\ v1 ! 73: of [] => (click "p"; ! 74: ((f,vl,e')::l'@ll, ! 75: v2--(uniq vl)\/v1\/v4)) ! 76: | _ => ((f,vl,e) :: ll, v3--(uniq vl)\/v4) ! 77: end ! 78: | h((f,vl,(e,v3)):: r) = ! 79: let val (ll, v4) = h r ! 80: in ((f,vl,e) :: ll, v3--(uniq vl)\/v4) ! 81: end ! 82: | h [] = ([],[]) ! 83: val (l,v1) = h (map (fn(f,vl,a)=>(f,vl,hoist a)) l) ! 84: val defined = uniq(map #1 l) ! 85: val v1 = v1 -- defined ! 86: val (e,v2) = hoist e ! 87: exception Down ! 88: fun check vl = case defined /\ uniq vl of [] => () ! 89: | _ => raise Down ! 90: fun present (_,vx) = case defined/\vx ! 91: of []=>0 | _ => 1 ! 92: val rec down' = fn (cexp,vx) => ! 93: case defined /\ vx ! 94: of [] => (cexp,vx) ! 95: | _ => down cexp ! 96: handle Down => (FIX'(l,v1,cexp,vx), ! 97: vx--defined\/v1) ! 98: and down = ! 99: fn RECORD'(vl,w,e,v3) => (check(map #1 vl); ! 100: let val (e',v4) = down e ! 101: in (RECORD'(vl,w,e',v4),v4--[w]\/uniq(map #1 vl)) ! 102: end) ! 103: | SELECT'(i,v,w,e,v3) => ! 104: let val (e',v4) = down e ! 105: in (SELECT'(i,v,w,e',v4), v4--[w]\/[v]) ! 106: end ! 107: | PRIMOP'(i,vl,wl,[(e,_)]) => (check vl; ! 108: let val (e',v4) = down e ! 109: in (PRIMOP'(i,vl,wl,[(e',v4)]), v4--uniq wl\/uniq vl) ! 110: end) ! 111: | PRIMOP'(i,vl,wl,el) => ! 112: (check vl; ! 113: if sum present el < 2 ! 114: then let val el' = map down' el ! 115: in (PRIMOP'(i,vl,wl,el'), foldmerge(map #2 el')--uniq wl\/uniq vl) ! 116: end ! 117: else raise Down) ! 118: | SWITCH'(v,el) => (* can't switch on a function *) ! 119: if sum present el < 2 ! 120: then let val el' = map down' el ! 121: in (SWITCH'(v,el'), foldmerge(map #2 el')\/[v]) ! 122: end ! 123: else raise Down ! 124: | e as APP'(f,vl) => (check(f::vl); click "s"; (e, uniq(f::vl))) ! 125: | FIX'(m,v3,e',v4) => ! 126: let val v5 = v1\/(v3--defined) ! 127: in click "r"; ! 128: (FIX'(l@m,v5,e',v4),v5\/(v4--(defined\/uniq(map #1 m)))) ! 129: end ! 130: in down e handle Down => (FIX'(l,v1,e,v2), ! 131: v2--defined\/v1) ! 132: end ! 133: val rec clean = ! 134: fn RECORD'(vl,w,e,_) => RECORD(vl,w,clean e) ! 135: | SELECT'(i,v,w,e,_) => SELECT(i,v,w, clean e) ! 136: | PRIMOP'(i,vl,wl,el) => PRIMOP(i,vl,wl,map (clean o #1) el) ! 137: | SWITCH'(v,el) => SWITCH(v, map (clean o #1) el) ! 138: | APP'(f,vl) => APP(f,vl) ! 139: | FIX'(l,_,e,_) => FIX(map (fn (f,vl,e)=>(f,vl,clean e)) l, clean e) ! 140: val cexp' = #1(hoist cexp) ! 141: in if !clicked then clean cexp' else cexp ! 142: end ! 143: ! 144: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.